Implemented x86 inline asm b, h, w, k modifiers.
[oota-llvm.git] / lib / Target / X86 / X86ATTAsmPrinter.cpp
index 5b576b79c91d7ed78b2fe3f5dbbf56817a8679b2..becb9db27ae30860663a7c640fcececa6889127d 100755 (executable)
@@ -35,14 +35,12 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SetupMachineFunction(MF);
   O << "\n\n";
 
-  if (forDarwin) {
-    // Emit pre-function debug information.
-    DW.BeginFunction(&MF);
-  }
-
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
+  // Print out jump tables referenced by the function
+  EmitJumpTableInfo(MF.getJumpTableInfo());
+  
   // Print out labels for the function.
   const Function *F = MF.getFunction();
   switch (F->getLinkage()) {
@@ -73,6 +71,11 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   }
   O << CurrentFnName << ":\n";
 
+  if (forDarwin) {
+    // Emit pre-function debug information.
+    DW.BeginFunction(&MF);
+  }
+
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
@@ -120,18 +123,21 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       O << '$';
     O << (int)MO.getImmedValue();
     return;
-  case MachineOperand::MO_MachineBasicBlock: {
-    MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
-    O << PrivateGlobalPrefix << "BB"
-      << Mang->getValueName(MBBOp->getParent()->getFunction())
-      << "_" << MBBOp->getNumber () << "\t# "
-      << MBBOp->getBasicBlock ()->getName ();
+  case MachineOperand::MO_MachineBasicBlock:
+    printBasicBlockLabel(MO.getMachineBasicBlock());
     return;
-  }
   case MachineOperand::MO_PCRelativeDisp:
     std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
     abort ();
     return;
+  case MachineOperand::MO_JumpTableIndex: {
+    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+    if (!isMemOp) O << '$';
+    O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << "_"
+      << MO.getJumpTableIndex();
+    // FIXME: PIC relocation model
+    return;
+  }
   case MachineOperand::MO_ConstantPoolIndex: {
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     if (!isMemOp) O << '$';
@@ -258,6 +264,157 @@ void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
   O << "\"L" << getFunctionNumber() << "$pb\":";
 }
 
+
+bool X86ATTAsmPrinter::printAsmMRegsiter(const MachineOperand &MO,
+                                         const char Mode) {
+  const MRegisterInfo &RI = *TM.getRegisterInfo();
+  unsigned Reg = MO.getReg();
+  const char *Name = RI.get(Reg).Name;
+  switch (Mode) {
+  default: return true;  // Unknown mode.
+  case 'b': // Print QImode register
+    switch (Reg) {
+    default: return true;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      Name = "al";
+      break;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      Name = "dl";
+      break;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      Name = "cl";
+      break;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      Name = "bl";
+      break;
+    case X86::ESI:
+      Name = "sil";
+      break;
+    case X86::EDI:
+      Name = "dil";
+      break;
+    case X86::EBP:
+      Name = "bpl";
+      break;
+    case X86::ESP:
+      Name = "spl";
+      break;
+    }
+    break;
+  case 'h': // Print QImode high register
+    switch (Reg) {
+    default: return true;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      Name = "al";
+      break;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      Name = "dl";
+      break;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      Name = "cl";
+      break;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      Name = "bl";
+      break;
+    }
+    break;
+  case 'w': // Print HImode register
+    switch (Reg) {
+    default: return true;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      Name = "ax";
+      break;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      Name = "dx";
+      break;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      Name = "cx";
+      break;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      Name = "bx";
+      break;
+    case X86::ESI:
+      Name = "si";
+      break;
+    case X86::EDI:
+      Name = "di";
+      break;
+    case X86::EBP:
+      Name = "bp";
+      break;
+    case X86::ESP:
+      Name = "sp";
+      break;
+    }
+    break;
+  case 'k': // Print SImode register
+    switch (Reg) {
+    default: return true;
+    case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
+      Name = "eax";
+      break;
+    case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
+      Name = "edx";
+      break;
+    case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
+      Name = "ecx";
+      break;
+    case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
+      Name = "ebx";
+      break;
+    case X86::ESI:
+      Name = "esi";
+      break;
+    case X86::EDI:
+      Name = "edi";
+      break;
+    case X86::EBP:
+      Name = "ebp";
+      break;
+    case X86::ESP:
+      Name = "esp";
+      break;
+    }
+    break;
+  }
+
+  O << '%' << Name;
+  return false;
+}
+
+/// PrintAsmOperand - Print out an operand for an inline asm expression.
+///
+bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+                                       unsigned AsmVariant, 
+                                       const char *ExtraCode) {
+  // Does this asm operand have a single letter operand modifier?
+  if (ExtraCode && ExtraCode[0]) {
+    if (ExtraCode[1] != 0) return true; // Unknown modifier.
+    
+    switch (ExtraCode[0]) {
+    default: return true;  // Unknown modifier.
+    case 'b': // Print QImode register
+    case 'h': // Print QImode high register
+    case 'w': // Print HImode register
+    case 'k': // Print SImode register
+      return printAsmMRegsiter(MI->getOperand(OpNo), ExtraCode[0]);
+    }
+  }
+  
+  printOperand(MI, OpNo);
+  return false;
+}
+
+bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
+                                             unsigned OpNo,
+                                             unsigned AsmVariant, 
+                                             const char *ExtraCode) {
+  if (ExtraCode && ExtraCode[0])
+    return true; // Unknown modifier.
+  printMemReference(MI, OpNo);
+  return false;
+}
+
 /// printMachineInstruction -- Print out a single X86 LLVM instruction
 /// MI in Intel syntax to the current output stream.
 ///