Factor out offset printing code into generic AsmPrinter.
[oota-llvm.git] / lib / Target / X86 / X86CodeEmitter.cpp
index 2fe64273b177eff469a6184d1bdcd834296fe95f..fabb67ee2df6bfc98c7343b0ebec5c5a69e1e1a7 100644 (file)
@@ -73,7 +73,7 @@ namespace {
     void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
     void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
                            intptr_t Disp = 0, intptr_t PCAdj = 0,
-                           bool NeedStub = false, bool IsLazy = false);
+                           bool NeedStub = false, bool IsNonLazy = false);
     void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
     void emitConstPoolAddress(unsigned CPI, unsigned Reloc, intptr_t Disp = 0,
                               intptr_t PCAdj = 0);
@@ -94,7 +94,7 @@ namespace {
 
     unsigned getX86RegNum(unsigned RegNo) const;
 
-    bool gvNeedsLazyPtr(const GlobalValue *GV);
+    bool gvNeedsNonLazyPtr(const GlobalValue *GV);
   };
   char Emitter::ID = 0;
 }
@@ -155,15 +155,15 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
                                 intptr_t Disp /* = 0 */,
                                 intptr_t PCAdj /* = 0 */,
                                 bool NeedStub /* = false */,
-                                bool isLazy /* = false */) {
+                                bool isNonLazy /* = false */) {
   intptr_t RelocCST = 0;
   if (Reloc == X86::reloc_picrel_word)
     RelocCST = PICBaseOffset;
   else if (Reloc == X86::reloc_pcrel_word)
     RelocCST = PCAdj;
-  MachineRelocation MR = isLazy 
-    ? MachineRelocation::getGVLazyPtr(MCE.getCurrentPCOffset(), Reloc,
-                                      GV, RelocCST, NeedStub)
+  MachineRelocation MR = isNonLazy 
+    ? MachineRelocation::getGVNonLazyPtr(MCE.getCurrentPCOffset(), Reloc,
+                                         GV, RelocCST, NeedStub)
     : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
                                GV, RelocCST, NeedStub);
   MCE.addRelocation(MR);
@@ -263,8 +263,8 @@ static bool isDisp8(int Value) {
   return Value == (signed char)Value;
 }
 
-bool Emitter::gvNeedsLazyPtr(const GlobalValue *GV) {
-  // For Darwin, simulate the linktime GOT by using the same lazy-pointer
+bool Emitter::gvNeedsNonLazyPtr(const GlobalValue *GV) {
+  // For Darwin, simulate the linktime GOT by using the same non-lazy-pointer
   // mechanism as 32-bit mode.
   return (!Is64BitMode || TM.getSubtarget<X86Subtarget>().isTargetDarwin()) &&
     TM.getSubtarget<X86Subtarget>().GVRequiresExtraLoad(GV, TM, false);
@@ -289,9 +289,9 @@ void Emitter::emitDisplacementField(const MachineOperand *RelocOp,
     unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
       : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
     bool NeedStub = isa<Function>(RelocOp->getGlobal());
-    bool isLazy = gvNeedsLazyPtr(RelocOp->getGlobal());
+    bool isNonLazy = gvNeedsNonLazyPtr(RelocOp->getGlobal());
     emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
-                      PCAdj, NeedStub, isLazy);
+                      PCAdj, NeedStub, isNonLazy);
   } else if (RelocOp->isCPI()) {
     unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
     emitConstPoolAddress(RelocOp->getIndex(), rt,
@@ -338,7 +338,7 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
   unsigned BaseReg = Base.getReg();
 
   // Is a SIB byte needed?
-  if (IndexReg.getReg() == 0 &&
+  if ((!Is64BitMode || DispForReloc) && IndexReg.getReg() == 0 &&
       (BaseReg == 0 || getX86RegNum(BaseReg) != N86::ESP)) {
     if (BaseReg == 0) {  // Just a displacement?
       // Emit special case [disp32] encoding
@@ -395,9 +395,13 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
     if (BaseReg == 0) {
       // Handle the SIB byte for the case where there is no base.  The
       // displacement has already been output.
-      assert(IndexReg.getReg() && "Index register must be specified!");
-      emitSIBByte(SS, getX86RegNum(IndexReg.getReg()), 5);
-    } else {
+      unsigned IndexRegNo;
+      if (IndexReg.getReg())
+        IndexRegNo = getX86RegNum(IndexReg.getReg());
+      else
+        IndexRegNo = 4;   // For example [ESP+1*<noreg>+4]
+      emitSIBByte(SS, IndexRegNo, 5);
+      } else {
       unsigned BaseRegNo = getX86RegNum(BaseReg);
       unsigned IndexRegNo;
       if (IndexReg.getReg())
@@ -606,9 +610,9 @@ void Emitter::emitInstruction(const MachineInstr &MI,
           rt = X86::reloc_absolute_dword;  // FIXME: add X86II flag?
         if (MO1.isGlobal()) {
           bool NeedStub = isa<Function>(MO1.getGlobal());
-          bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
+          bool isNonLazy = gvNeedsNonLazyPtr(MO1.getGlobal());
           emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, isNonLazy);
         } else if (MO1.isSymbol())
           emitExternalSymbolAddress(MO1.getSymbolName(), rt);
         else if (MO1.isCPI())
@@ -684,9 +688,9 @@ void Emitter::emitInstruction(const MachineInstr &MI,
           rt = X86::reloc_absolute_word;  // FIXME: add X86II flag?
         if (MO1.isGlobal()) {
           bool NeedStub = isa<Function>(MO1.getGlobal());
-          bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
+          bool isNonLazy = gvNeedsNonLazyPtr(MO1.getGlobal());
           emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, isNonLazy);
         } else if (MO1.isSymbol())
           emitExternalSymbolAddress(MO1.getSymbolName(), rt);
         else if (MO1.isCPI())
@@ -722,9 +726,9 @@ void Emitter::emitInstruction(const MachineInstr &MI,
           rt = X86::reloc_absolute_word;  // FIXME: add X86II flag?
         if (MO.isGlobal()) {
           bool NeedStub = isa<Function>(MO.getGlobal());
-          bool isLazy = gvNeedsLazyPtr(MO.getGlobal());
+          bool isNonLazy = gvNeedsNonLazyPtr(MO.getGlobal());
           emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, isNonLazy);
         } else if (MO.isSymbol())
           emitExternalSymbolAddress(MO.getSymbolName(), rt);
         else if (MO.isCPI())