Add reg clobber list for direct calls
[oota-llvm.git] / lib / Target / X86 / X86CodeEmitter.cpp
index b18979d11291990b721ccaeb2104bde81eb64553..38d1be6a59bb148ca3c47f7c78a7729b7d03867f 100644 (file)
@@ -25,6 +25,10 @@ namespace {
 
     bool runOnFunction(Function &F);
 
+    virtual const char *getPassName() const {
+      return "X86 Machine Code Emitter";
+    }
+
   private:
     void emitBasicBlock(MachineBasicBlock &MBB);
     void emitInstruction(MachineInstr &MI);
@@ -148,7 +152,7 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
         emitConstant(Disp.getImmedValue(), 1);
       } else {
         // Emit the most general non-SIB encoding: [REG+disp32]
-        MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
+        MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
         emitConstant(Disp.getImmedValue(), 4);
       }
     }
@@ -157,17 +161,19 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
     assert(IndexReg.getReg() != X86::ESP && "Cannot use ESP as index reg!");
 
     bool ForceDisp32 = false;
+    bool ForceDisp8  = false;
     if (BaseReg.getReg() == 0) {
       // If there is no base register, we emit the special case SIB byte with
       // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
       MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
       ForceDisp32 = true;
-    } else if (Disp.getImmedValue() == 0) {
+    } else if (Disp.getImmedValue() == 0 && BaseReg.getReg() != X86::EBP) {
       // Emit no displacement ModR/M byte
       MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
     } else if (isDisp8(Disp.getImmedValue())) {
       // Emit the disp8 encoding...
       MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
+      ForceDisp8 = true;           // Make sure to force 8 bit disp if Base=EBP
     } else {
       // Emit the normal disp32 encoding...
       MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
@@ -189,7 +195,7 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
     }
 
     // Do we need to output a displacement?
-    if (Disp.getImmedValue() != 0 || ForceDisp32) {
+    if (Disp.getImmedValue() != 0 || ForceDisp32 || ForceDisp8) {
       if (!ForceDisp32 && isDisp8(Disp.getImmedValue()))
         emitConstant(Disp.getImmedValue(), 1);
       else
@@ -198,25 +204,15 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
   }
 }
 
-static bool isImmediate(const MachineOperand &MO) {
-  return MO.getType() == MachineOperand::MO_SignExtendedImmed ||
-         MO.getType() == MachineOperand::MO_UnextendedImmed;
-}
-
 unsigned sizeOfPtr (const MachineInstrDescriptor &Desc) {
-  switch (Desc.TSFlags & X86II::MemArgMask) {
-  case X86II::MemArg8:   return 1;
-  case X86II::MemArg16:  return 2;
-  case X86II::MemArg32:  return 4;
-  case X86II::MemArg64:  return 8;
-  case X86II::MemArg80:  return 10;
-  case X86II::MemArg128: return 16;
-  default: {
-    // FIXME: This should be an assert, but it is returning 4 because that was
-    // the former behavior and it's what was expected. Once the assumptions
-    // below are fixed, this can become an assert.
-    return 4;
-  }
+  switch (Desc.TSFlags & X86II::ArgMask) {
+  case X86II::Arg8:   return 1;
+  case X86II::Arg16:  return 2;
+  case X86II::Arg32:  return 4;
+  case X86II::Arg64:  return 8;
+  case X86II::Arg80:  return 10;
+  case X86II::Arg128: return 16;
+  default: assert(0 && "Memory size not set!");
   }
 }
 
@@ -279,12 +275,10 @@ void Emitter::emitInstruction(MachineInstr &MI) {
     emitRegModRMByte(MI.getOperand(0).getReg(),
                      (Desc.TSFlags & X86II::FormMask)-X86II::MRMS0r);
 
-    if (isImmediate(MI.getOperand(MI.getNumOperands()-1))) {
+    if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
       unsigned Size = sizeOfPtr(Desc);
       emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size);
     }
     break;
-    
-    
   }
 }