Add reg clobber list for direct calls
[oota-llvm.git] / lib / Target / X86 / X86CodeEmitter.cpp
index 7b0f1bfb4434efc992132232480b1c351142b65c..38d1be6a59bb148ca3c47f7c78a7729b7d03867f 100644 (file)
@@ -11,6 +11,7 @@
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Value.h"
 
 namespace {
   class Emitter : public FunctionPass {
@@ -24,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);
@@ -147,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);
       }
     }
@@ -156,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));
@@ -188,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
@@ -197,11 +204,19 @@ 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::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!");
+  }
 }
 
+
 void Emitter::emitInstruction(MachineInstr &MI) {
   unsigned Opcode = MI.getOpcode();
   const MachineInstrDescriptor &Desc = II.get(Opcode);
@@ -223,8 +238,13 @@ void Emitter::emitInstruction(MachineInstr &MI) {
   case X86II::AddRegFrm:
     MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg()));
     if (MI.getNumOperands() == 2) {
-      unsigned Size = 4;
-      emitConstant(MI.getOperand(1).getImmedValue(), Size);
+      unsigned Size = sizeOfPtr(Desc);
+      if (Value *V = MI.getOperand(1).getVRegValueOrNull()) {
+        assert(Size == 4 && "Don't know how to emit non-pointer values!");
+        MCE.emitGlobalAddress(cast<GlobalValue>(V));
+      } else {
+        emitConstant(MI.getOperand(1).getImmedValue(), Size);
+      }
     }
     break;
   case X86II::MRMDestReg:
@@ -255,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))) {
-      unsigned Size = 4;
+    if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
+      unsigned Size = sizeOfPtr(Desc);
       emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size);
     }
     break;
-    
-    
   }
 }