Start implementing translation of MachineInstr to MCInst. Next
authorChris Lattner <sabre@nondot.org>
Sat, 20 Jun 2009 00:49:26 +0000 (00:49 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 20 Jun 2009 00:49:26 +0000 (00:49 +0000)
step is to make tblgen generate something more appropriate for MCInst,
and generate calls to operand translation routines where needed.
This includes a bunch of #if 0 code which will slowly be refactored into
something sensible.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73810 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp

index 7e48855e08d2974ea4e73259aae44297703dc02f..44d817de0228103baf74cd4d9b7456aa9dff466d 100644 (file)
@@ -771,6 +771,29 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   if (NewAsmPrinter) {
     O << "NEW: ";
     MCInst TmpInst;
+    
+    TmpInst.setOpcode(MI->getOpcode());
+    
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      const MachineOperand &MO = MI->getOperand(i);
+      
+      MCOperand MCOp;
+      if (MO.isReg()) {
+        MCOp.MakeReg(MO.getReg());
+      } else if (MO.isImm()) {
+        MCOp.MakeImm(MO.getImm());
+      } else {
+        assert(0 && "Unimp");
+      }
+      
+      TmpInst.addOperand(MCOp);
+    }
+    
+    if (MI->getOpcode() == X86::LEA64_32r) {
+      // Should handle the 'subreg rewriting' for the lea64_32mem operand.
+      
+    }
+    
     // FIXME: Convert TmpInst.
     printInstruction(&TmpInst);
     O << "OLD: ";
index 934e45aa8157e0dcefb7a10131852e7528a4d470..e46f7a3c74f46e69c8145a2ebcb0259be9247f11 100644 (file)
@@ -28,14 +28,14 @@ void X86ATTAsmPrinter::printSSECC(const MCInst *MI, unsigned Op) {
   unsigned char value = MI->getOperand(Op).getImm();
   assert(value <= 7 && "Invalid ssecc argument!");
   switch (value) {
-    case 0: O << "eq"; break;
-    case 1: O << "lt"; break;
-    case 2: O << "le"; break;
-    case 3: O << "unord"; break;
-    case 4: O << "neq"; break;
-    case 5: O << "nlt"; break;
-    case 6: O << "nle"; break;
-    case 7: O << "ord"; break;
+  case 0: O << "eq"; break;
+  case 1: O << "lt"; break;
+  case 2: O << "le"; break;
+  case 3: O << "unord"; break;
+  case 4: O << "neq"; break;
+  case 5: O << "nlt"; break;
+  case 6: O << "nle"; break;
+  case 7: O << "ord"; break;
   }
 }
 
@@ -48,13 +48,353 @@ void X86ATTAsmPrinter::printPICLabel(const MCInst *MI, unsigned Op) {
 
 void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo,
                                     const char *Modifier, bool NotRIPRel) {
+  //assert(Modifier == 0 && "Modifiers should not be used");
+  
+  const MCOperand &Op = MI->getOperand(OpNo);
+  if (Op.isReg()) {
+    O << '%';
+    unsigned Reg = Op.getReg();
+#if 0
+    if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
+      MVT VT = (strcmp(Modifier+6,"64") == 0) ?
+      MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
+                  ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
+      Reg = getX86SubSuperRegister(Reg, VT);
+    }
+#endif
+    O << TRI->getAsmName(Reg);
+    return;
+  } else if (Op.isImm()) {
+    //if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem") &&
+    // strcmp(Modifier, "call")))
+    O << '$';
+    O << Op.getImm();
+    return;
+  }
+  
+  O << "<<UNKNOWN OPERAND KIND>>";
+  
+  
+#if 0
+  const MachineOperand &MO = MI->getOperand(OpNo);
+  switch (MO.getType()) {
+    case MachineOperand::MO_Register: {
+      assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+             "Virtual registers should not make it this far!");
+      O << '%';
+      unsigned Reg = MO.getReg();
+      if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
+        MVT VT = (strcmp(Modifier+6,"64") == 0) ?
+        MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
+                    ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
+        Reg = getX86SubSuperRegister(Reg, VT);
+      }
+      O << TRI->getAsmName(Reg);
+      return;
+    }
+      
+    case MachineOperand::MO_Immediate:
+      if (!Modifier || (strcmp(Modifier, "debug") &&
+                        strcmp(Modifier, "mem") &&
+                        strcmp(Modifier, "call")))
+        O << '$';
+      O << MO.getImm();
+      return;
+    case MachineOperand::MO_MachineBasicBlock:
+      printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm);
+      return;
+    case MachineOperand::MO_JumpTableIndex: {
+      bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+      if (!isMemOp) O << '$';
+      O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
+      << MO.getIndex();
+      
+      if (TM.getRelocationModel() == Reloc::PIC_) {
+        if (Subtarget->isPICStyleStub())
+          O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
+          << "$pb\"";
+        else if (Subtarget->isPICStyleGOT())
+          O << "@GOTOFF";
+      }
+      
+      if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
+        O << "(%rip)";
+      return;
+    }
+    case MachineOperand::MO_ConstantPoolIndex: {
+      bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+      if (!isMemOp) O << '$';
+      O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
+      << MO.getIndex();
+      
+      if (TM.getRelocationModel() == Reloc::PIC_) {
+        if (Subtarget->isPICStyleStub())
+          O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
+          << "$pb\"";
+        else if (Subtarget->isPICStyleGOT())
+          O << "@GOTOFF";
+      }
+      
+      printOffset(MO.getOffset());
+      
+      if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
+        O << "(%rip)";
+      return;
+    }
+    case MachineOperand::MO_GlobalAddress: {
+      bool isCallOp = Modifier && !strcmp(Modifier, "call");
+      bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+      bool needCloseParen = false;
+      
+      const GlobalValue *GV = MO.getGlobal();
+      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+      if (!GVar) {
+        // If GV is an alias then use the aliasee for determining
+        // thread-localness.
+        if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
+          GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
+      }
+      
+      bool isThreadLocal = GVar && GVar->isThreadLocal();
+      
+      std::string Name = Mang->getValueName(GV);
+      decorateName(Name, GV);
+      
+      if (!isMemOp && !isCallOp)
+        O << '$';
+      else if (Name[0] == '$') {
+        // The name begins with a dollar-sign. In order to avoid having it look
+        // like an integer immediate to the assembler, enclose it in parens.
+        O << '(';
+        needCloseParen = true;
+      }
+      
+      if (shouldPrintStub(TM, Subtarget)) {
+        // Link-once, declaration, or Weakly-linked global variables need
+        // non-lazily-resolved stubs
+        if (GV->isDeclaration() || GV->isWeakForLinker()) {
+          // Dynamically-resolved functions need a stub for the function.
+          if (isCallOp && isa<Function>(GV)) {
+            // Function stubs are no longer needed for Mac OS X 10.5 and up.
+            if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) {
+              O << Name;
+            } else {
+              FnStubs.insert(Name);
+              printSuffixedName(Name, "$stub");
+            }
+          } else if (GV->hasHiddenVisibility()) {
+            if (!GV->isDeclaration() && !GV->hasCommonLinkage())
+              // Definition is not definitely in the current translation unit.
+              O << Name;
+            else {
+              HiddenGVStubs.insert(Name);
+              printSuffixedName(Name, "$non_lazy_ptr");
+            }
+          } else {
+            GVStubs.insert(Name);
+            printSuffixedName(Name, "$non_lazy_ptr");
+          }
+        } else {
+          if (GV->hasDLLImportLinkage())
+            O << "__imp_";
+          O << Name;
+        }
+        
+        if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
+          O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget);
+      } else {
+        if (GV->hasDLLImportLinkage()) {
+          O << "__imp_";
+        }
+        O << Name;
+        
+        if (isCallOp) {
+          if (shouldPrintPLT(TM, Subtarget)) {
+            // Assemble call via PLT for externally visible symbols
+            if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
+                !GV->hasLocalLinkage())
+              O << "@PLT";
+          }
+          if (Subtarget->isTargetCygMing() && GV->isDeclaration())
+            // Save function name for later type emission
+            FnStubs.insert(Name);
+        }
+      }
+      
+      if (GV->hasExternalWeakLinkage())
+        ExtWeakSymbols.insert(GV);
+      
+      printOffset(MO.getOffset());
+      
+      if (isThreadLocal) {
+        TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel());
+        switch (model) {
+          case TLSModel::GeneralDynamic:
+            O << "@TLSGD";
+            break;
+          case TLSModel::LocalDynamic:
+            // O << "@TLSLD"; // local dynamic not implemented
+            O << "@TLSGD";
+            break;
+          case TLSModel::InitialExec:
+            if (Subtarget->is64Bit()) {
+              assert (!NotRIPRel);
+              O << "@GOTTPOFF(%rip)";
+            } else {
+              O << "@INDNTPOFF";
+            }
+            break;
+          case TLSModel::LocalExec:
+            if (Subtarget->is64Bit())
+              O << "@TPOFF";
+            else
+              O << "@NTPOFF";
+            break;
+          default:
+            assert (0 && "Unknown TLS model");
+        }
+      } else if (isMemOp) {
+        if (shouldPrintGOT(TM, Subtarget)) {
+          if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
+            O << "@GOT";
+          else
+            O << "@GOTOFF";
+        } else if (Subtarget->isPICStyleRIPRel() && !NotRIPRel) {
+          if (TM.getRelocationModel() != Reloc::Static) {
+            if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
+              O << "@GOTPCREL";
+            
+            if (needCloseParen) {
+              needCloseParen = false;
+              O << ')';
+            }
+          }
+          
+          // Use rip when possible to reduce code size, except when
+          // index or base register are also part of the address. e.g.
+          // foo(%rip)(%rcx,%rax,4) is not legal
+          O << "(%rip)";
+        }
+      }
+      
+      if (needCloseParen)
+        O << ')';
+      
+      return;
+    }
+    case MachineOperand::MO_ExternalSymbol: {
+      bool isCallOp = Modifier && !strcmp(Modifier, "call");
+      bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+      bool needCloseParen = false;
+      std::string Name(TAI->getGlobalPrefix());
+      Name += MO.getSymbolName();
+      // Print function stub suffix unless it's Mac OS X 10.5 and up.
+      if (isCallOp && shouldPrintStub(TM, Subtarget) && 
+          !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) {
+        FnStubs.insert(Name);
+        printSuffixedName(Name, "$stub");
+        return;
+      }
+      if (!isMemOp && !isCallOp)
+        O << '$';
+      else if (Name[0] == '$') {
+        // The name begins with a dollar-sign. In order to avoid having it look
+        // like an integer immediate to the assembler, enclose it in parens.
+        O << '(';
+        needCloseParen = true;
+      }
+      
+      O << Name;
+      
+      if (shouldPrintPLT(TM, Subtarget)) {
+        std::string GOTName(TAI->getGlobalPrefix());
+        GOTName+="_GLOBAL_OFFSET_TABLE_";
+        if (Name == GOTName)
+          // HACK! Emit extra offset to PC during printing GOT offset to
+          // compensate for the size of popl instruction. The resulting code
+          // should look like:
+          //   call .piclabel
+          // piclabel:
+          //   popl %some_register
+          //   addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
+          O << " + [.-"
+          << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']';
+        
+        if (isCallOp)
+          O << "@PLT";
+      }
+      
+      if (needCloseParen)
+        O << ')';
+      
+      if (!isCallOp && Subtarget->isPICStyleRIPRel())
+        O << "(%rip)";
+      
+      return;
+    }
+    default:
+      O << "<unknown operand type>"; return;
+  }
+#endif
 }
 
 void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op,
                                             const char *Modifier,
                                             bool NotRIPRel) {
+  const MCOperand &BaseReg  = MI->getOperand(Op);
+  const MCOperand &IndexReg = MI->getOperand(Op+2);
+  const MCOperand &DispSpec = MI->getOperand(Op+3);
+  
+  NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
+  if (DispSpec.isImm()) {
+    int64_t DispVal = DispSpec.getImm();
+    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
+      O << DispVal;
+  } else {
+    abort();
+    //assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
+    //       DispSpec.isJTI() || DispSpec.isSymbol());
+    //printOperand(MI, Op+3, "mem", NotRIPRel);
+  }
+  
+  if (IndexReg.getReg() || BaseReg.getReg()) {
+    unsigned ScaleVal = MI->getOperand(Op+1).getImm();
+    unsigned BaseRegOperand = 0, IndexRegOperand = 2;
+    
+    // There are cases where we can end up with ESP/RSP in the indexreg slot.
+    // If this happens, swap the base/index register to support assemblers that
+    // don't work when the index is *SP.
+    // FIXME: REMOVE THIS.
+    if (IndexReg.getReg() == X86::ESP || IndexReg.getReg() == X86::RSP) {
+      assert(ScaleVal == 1 && "Scale not supported for stack pointer!");
+      abort();
+      //std::swap(BaseReg, IndexReg);
+      //std::swap(BaseRegOperand, IndexRegOperand);
+    }
+    
+    O << '(';
+    if (BaseReg.getReg())
+      printOperand(MI, Op+BaseRegOperand, Modifier);
+    
+    if (IndexReg.getReg()) {
+      O << ',';
+      printOperand(MI, Op+IndexRegOperand, Modifier);
+      if (ScaleVal != 1)
+        O << ',' << ScaleVal;
+    }
+    O << ')';
+  }
 }
 
 void X86ATTAsmPrinter::printMemReference(const MCInst *MI, unsigned Op,
                                          const char *Modifier, bool NotRIPRel){
+#if 0
+  assert(isMem(MI, Op) && "Invalid memory reference!");
+  MachineOperand Segment = MI->getOperand(Op+4);
+  if (Segment.getReg()) {
+    printOperand(MI, Op+4, Modifier);
+    O << ':';
+  }
+  printLeaMemReference(MI, Op, Modifier, NotRIPRel);
+#endif
 }