-no-implicit-float means explicit fp operations are legal.
[oota-llvm.git] / lib / Target / X86 / X86CodeEmitter.cpp
index 2fe64273b177eff469a6184d1bdcd834296fe95f..bbe063b4f821efb2b4b6ce8b150907c122e5c7e2 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 Indirect = 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 Indirect /* = 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 = Indirect
+    ? MachineRelocation::getIndirectSymbol(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 Indirect = gvNeedsNonLazyPtr(RelocOp->getGlobal());
     emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
-                      PCAdj, NeedStub, isLazy);
+                      PCAdj, NeedStub, Indirect);
   } 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,8 +395,12 @@ 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);
+      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;
@@ -512,10 +516,12 @@ void Emitter::emitInstruction(const MachineInstr &MI,
       assert(0 && "psuedo instructions should be removed before code emission");
       break;
     case TargetInstrInfo::INLINEASM: {
-      const char* Value = MI.getOperand(0).getSymbolName();
-      /* We allow inline assembler nodes with empty bodies - they can
-         implicitly define registers, which is ok for JIT. */
-      assert((Value[0] == 0) && "JIT does not support inline asm!\n");
+      // We allow inline assembler nodes with empty bodies - they can
+      // implicitly define registers, which is ok for JIT.
+      if (MI.getOperand(0).getSymbolName()[0]) {
+        assert(0 && "JIT does not support inline asm!\n");
+        abort();
+      }
       break;
     }
     case TargetInstrInfo::DBG_LABEL:
@@ -549,7 +555,7 @@ void Emitter::emitInstruction(const MachineInstr &MI,
       MCE.emitByte(BaseOpcode);
       emitConstant(0, X86InstrInfo::sizeOfImm(Desc));
       // Remember PIC base.
-      PICBaseOffset = MCE.getCurrentPCOffset();
+      PICBaseOffset = (intptr_t) MCE.getCurrentPCOffset();
       X86JITInfo *JTI = TM.getJITInfo();
       JTI->setPICBase(MCE.getCurrentPCValue());
       break;
@@ -583,7 +589,13 @@ void Emitter::emitInstruction(const MachineInstr &MI,
       } else if (MO.isSymbol()) {
         emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
       } else if (MO.isImm()) {
-        emitConstant(MO.getImm(), X86InstrInfo::sizeOfImm(Desc));
+        if (Opcode == X86::CALLpcrel32 || Opcode == X86::CALL64pcrel32) {
+          // Fix up immediate operand for pc relative calls.
+          intptr_t Imm = (intptr_t)MO.getImm();
+          Imm = Imm - MCE.getCurrentPCValue() - 4;
+          emitConstant(Imm, X86InstrInfo::sizeOfImm(Desc));
+        } else
+          emitConstant(MO.getImm(), X86InstrInfo::sizeOfImm(Desc));
       } else {
         assert(0 && "Unknown RawFrm operand!");
       }
@@ -606,9 +618,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 Indirect = gvNeedsNonLazyPtr(MO1.getGlobal());
           emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, Indirect);
         } else if (MO1.isSymbol())
           emitExternalSymbolAddress(MO1.getSymbolName(), rt);
         else if (MO1.isCPI())
@@ -684,9 +696,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 Indirect = gvNeedsNonLazyPtr(MO1.getGlobal());
           emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, Indirect);
         } else if (MO1.isSymbol())
           emitExternalSymbolAddress(MO1.getSymbolName(), rt);
         else if (MO1.isCPI())
@@ -722,9 +734,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 Indirect = gvNeedsNonLazyPtr(MO.getGlobal());
           emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0,
-                            NeedStub, isLazy);
+                            NeedStub, Indirect);
         } else if (MO.isSymbol())
           emitExternalSymbolAddress(MO.getSymbolName(), rt);
         else if (MO.isCPI())