another missed SSE optimization
[oota-llvm.git] / lib / Target / X86 / X86CodeEmitter.cpp
index e7e1ed476ac0ebf0c931d1f73697faa38f10b0e3..8b22634bd429d9159c90ae4b371f908de71e24b5 100644 (file)
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "x86-emitter"
 #include "X86InstrInfo.h"
 #include "X86Subtarget.h"
 #include "X86TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
-namespace {
-  Statistic<>
-  NumEmitted("x86-emitter", "Number of machine instructions emitted");
-}
+STATISTIC(NumEmitted, "Number of machine instructions emitted");
 
 namespace {
   class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass {
@@ -41,11 +39,14 @@ namespace {
     MachineCodeEmitter  &MCE;
     bool Is64BitMode;
   public:
+    static char ID;
     explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
-      : II(0), TD(0), TM(tm), MCE(mce), Is64BitMode(false) {}
+      : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm), 
+      MCE(mce), Is64BitMode(false) {}
     Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
             const X86InstrInfo &ii, const TargetData &td, bool is64)
-      : II(&ii), TD(&td), TM(tm), MCE(mce), Is64BitMode(is64) {}
+      : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm), 
+      MCE(mce), Is64BitMode(is64) {}
 
     bool runOnMachineFunction(MachineFunction &MF);
 
@@ -81,6 +82,7 @@ namespace {
     bool isX86_64ExtendedReg(const MachineOperand &MO);
     unsigned determineREX(const MachineInstr &MI);
   };
+  char Emitter::ID = 0;
 }
 
 /// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
@@ -173,6 +175,8 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
                                    unsigned PCAdj /* = 0 */) {
   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
                                                     Reloc, CPI, PCAdj));
+  if (Reloc == X86::reloc_absolute_dword)
+    MCE.emitWordLE(0);
   MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
 }
 
@@ -183,6 +187,8 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
                                    unsigned PCAdj /* = 0 */) {
   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
                                                     Reloc, JTI, PCAdj));
+  if (Reloc == X86::reloc_absolute_dword)
+    MCE.emitWordLE(0);
   MCE.emitWordLE(0); // The relocated value will be added to the displacement
 }
 
@@ -485,13 +491,13 @@ unsigned Emitter::determineREX(const MachineInstr &MI) {
     for (unsigned e = NumOps; i != e; ++i) {
       const MachineOperand& MO = MI.getOperand(i);
       if (MO.isRegister()) {
-       unsigned Reg = MO.getReg();
-       // Trunc to byte are actually movb. The real source operand is the low
-       // byte of the register.
-       if (isTrunc8 && i == 1)
-         Reg = getX86SubSuperRegister(Reg, MVT::i8);
-       if (isX86_64NonExtLowByteReg(Reg))
-         REX |= 0x40;
+        unsigned Reg = MO.getReg();
+        // Trunc to byte are actually movb. The real source operand is the low
+        // byte of the register.
+        if (isTrunc8 && i == 1)
+          Reg = getX86SubSuperRegister(Reg, MVT::i8);
+        if (isX86_64NonExtLowByteReg(Reg))
+          REX |= 0x40;
       }
     }
 
@@ -582,6 +588,14 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
   case X86II::TB:
     Need0FPrefix = true;   // Two-byte opcode prefix
     break;
+  case X86II::T8:
+    MCE.emitByte(0x0F);
+    MCE.emitByte(0x38);
+    break;
+  case X86II::TA:
+    MCE.emitByte(0x0F);
+    MCE.emitByte(0x3A);
+    break;
   case X86II::REP: break; // already handled.
   case X86II::XS:   // F3 0F
     MCE.emitByte(0xF3);
@@ -617,7 +631,7 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
   unsigned CurOp = 0;
   if (NumOps > 1 && Desc->getOperandConstraint(1, TOI::TIED_TO) != -1)
     CurOp++;
-  
+
   unsigned char BaseOpcode = II->getBaseOpcodeFor(Desc);
   switch (Desc->TSFlags & X86II::FormMask) {
   default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!");
@@ -628,6 +642,8 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
       assert(0 && "psuedo instructions should be removed before code emission");
     case TargetInstrInfo::INLINEASM:
       assert(0 && "JIT does not support inline asm!\n");
+    case TargetInstrInfo::LABEL:
+      assert(0 && "JIT does not support meta labels!\n");
     case X86::IMPLICIT_USE:
     case X86::IMPLICIT_DEF:
     case X86::IMPLICIT_DEF_GR8:
@@ -652,9 +668,10 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
       if (MO.isMachineBasicBlock()) {
         emitPCRelativeBlockAddress(MO.getMachineBasicBlock());
       } else if (MO.isGlobalAddress()) {
-        bool isTailCall = Opcode == X86::TAILJMPd ||
-                          Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
-        emitGlobalAddressForCall(MO.getGlobal(), !isTailCall);
+        bool NeedStub = Is64BitMode ||
+                        Opcode == X86::TAILJMPd ||
+                        Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
+        emitGlobalAddressForCall(MO.getGlobal(), !NeedStub);
       } else if (MO.isExternalSymbol()) {
         emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
       } else if (MO.isImmediate()) {
@@ -675,9 +692,8 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
         emitConstant(MO1.getImm(), Size);
       else {
         unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
-        // FIXME
         if (Opcode == X86::MOV64ri)
-          rt = X86::reloc_absolute_dword;
+          rt = X86::reloc_absolute_dword;  // FIXME: add X86II flag?
         if (MO1.isGlobalAddress())
           emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
         else if (MO1.isExternalSymbol())
@@ -743,10 +759,10 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
       if (MO1.isImmediate())
         emitConstant(MO1.getImm(), Size);
       else {
-        unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
-        // FIXME
+        unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+          : X86::reloc_absolute_word;
         if (Opcode == X86::MOV64ri32)
-          rt = X86::reloc_absolute_word;
+          rt = X86::reloc_absolute_word;  // FIXME: add X86II flag?
         if (MO1.isGlobalAddress())
           emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
         else if (MO1.isExternalSymbol())
@@ -777,7 +793,10 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
       if (MO.isImmediate())
         emitConstant(MO.getImm(), Size);
       else {
-        unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
+        unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+          : X86::reloc_absolute_word;
+        if (Opcode == X86::MOV64mi32)
+          rt = X86::reloc_absolute_word;  // FIXME: add X86II flag?
         if (MO.isGlobalAddress())
           emitGlobalAddressForPtr(MO.getGlobal(), rt, MO.getOffset());
         else if (MO.isExternalSymbol())