Create HandlePHINodesInSuccessorBlocksFast, a version of
[oota-llvm.git] / lib / Target / X86 / X86FastISel.cpp
1 //===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the X86-specific support for the FastISel class. Much
11 // of the target-specific code is generated by tablegen in the file
12 // X86GenFastISel.inc, which is #included here.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "X86.h"
17 #include "X86InstrBuilder.h"
18 #include "X86ISelLowering.h"
19 #include "X86RegisterInfo.h"
20 #include "X86Subtarget.h"
21 #include "X86TargetMachine.h"
22 #include "llvm/CodeGen/FastISel.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24
25 using namespace llvm;
26
27 class X86FastISel : public FastISel {
28   /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
29   /// make the right decision when generating code for different targets.
30   const X86Subtarget *Subtarget;
31     
32 public:
33   explicit X86FastISel(MachineFunction &mf,
34                        DenseMap<const Value *, unsigned> &vm,
35                        DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
36     : FastISel(mf, vm, bm) {
37     Subtarget = &TM.getSubtarget<X86Subtarget>();
38   }
39
40   virtual bool TargetSelectInstruction(Instruction *I);
41
42 #include "X86GenFastISel.inc"
43
44 private:
45   bool X86SelectConstAddr(Value *V, unsigned &Op0);
46
47   bool X86SelectLoad(Instruction *I);
48 };
49
50 /// X86SelectConstAddr - Select and emit code to materialize constant address.
51 /// 
52 bool X86FastISel::X86SelectConstAddr(Value *V,
53                                      unsigned &Op0) {
54   // FIXME: Only GlobalAddress for now.
55   GlobalValue *GV = dyn_cast<GlobalValue>(V);
56   if (!GV)
57     return false;
58
59   if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
60     // Issue load from stub if necessary.
61     unsigned Opc = 0;
62     const TargetRegisterClass *RC = NULL;
63     if (TLI.getPointerTy() == MVT::i32) {
64       Opc = X86::MOV32rm;
65       RC  = X86::GR32RegisterClass;
66     } else {
67       Opc = X86::MOV64rm;
68       RC  = X86::GR64RegisterClass;
69     }
70     Op0 = createResultReg(RC);
71     X86AddressMode AM;
72     AM.GV = GV;
73     addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
74   }
75   return true;
76 }
77
78 /// X86SelectLoad - Select and emit code to implement load instructions.
79 ///
80 bool X86FastISel::X86SelectLoad(Instruction *I)  {
81   MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
82   if (VT == MVT::Other || !VT.isSimple())
83     // Unhandled type. Halt "fast" selection and bail.
84     return false;
85   if (VT == MVT::iPTR)
86     // Use pointer type.
87     VT = TLI.getPointerTy();
88   // We only handle legal types. For example, on x86-32 the instruction
89   // selector contains all of the 64-bit instructions from x86-64,
90   // under the assumption that i64 won't be used if the target doesn't
91   // support it.
92   if (!TLI.isTypeLegal(VT))
93     return false;
94
95   Value *V = I->getOperand(0);
96   unsigned Op0 = getRegForValue(V);
97   if (Op0 == 0) {
98     // Handle constant load address.
99     if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
100       // Unhandled operand. Halt "fast" selection and bail.
101       return false;    
102   }
103
104   // Get opcode and regclass of the output for the given load instruction.
105   unsigned Opc = 0;
106   const TargetRegisterClass *RC = NULL;
107   switch (VT.getSimpleVT()) {
108   default: return false;
109   case MVT::i8:
110     Opc = X86::MOV8rm;
111     RC  = X86::GR8RegisterClass;
112     break;
113   case MVT::i16:
114     Opc = X86::MOV16rm;
115     RC  = X86::GR16RegisterClass;
116     break;
117   case MVT::i32:
118     Opc = X86::MOV32rm;
119     RC  = X86::GR32RegisterClass;
120     break;
121   case MVT::i64:
122     // Must be in x86-64 mode.
123     Opc = X86::MOV64rm;
124     RC  = X86::GR64RegisterClass;
125     break;
126   case MVT::f32:
127     if (Subtarget->hasSSE1()) {
128       Opc = X86::MOVSSrm;
129       RC  = X86::FR32RegisterClass;
130     } else {
131       Opc = X86::LD_Fp32m;
132       RC  = X86::RFP32RegisterClass;
133     }
134     break;
135   case MVT::f64:
136     if (Subtarget->hasSSE2()) {
137       Opc = X86::MOVSDrm;
138       RC  = X86::FR64RegisterClass;
139     } else {
140       Opc = X86::LD_Fp64m;
141       RC  = X86::RFP64RegisterClass;
142     }
143     break;
144   case MVT::f80:
145     Opc = X86::LD_Fp80m;
146     RC  = X86::RFP80RegisterClass;
147     break;
148   }
149
150   unsigned ResultReg = createResultReg(RC);
151   X86AddressMode AM;
152   if (Op0)
153     // Address is in register.
154     AM.Base.Reg = Op0;
155   else
156     AM.GV = cast<GlobalValue>(V);
157   addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
158   UpdateValueMap(I, ResultReg);
159   return true;
160 }
161
162
163 bool
164 X86FastISel::TargetSelectInstruction(Instruction *I)  {
165   switch (I->getOpcode()) {
166   default: break;
167   case Instruction::Load:
168     return X86SelectLoad(I);
169   }
170
171   return false;
172 }
173
174 namespace llvm {
175   llvm::FastISel *X86::createFastISel(MachineFunction &mf,
176                         DenseMap<const Value *, unsigned> &vm,
177                         DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
178     return new X86FastISel(mf, vm, bm);
179   }
180 }