Fix the ordering of operands to the store (inverted relative to LLVM IR), and fix...
[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   bool X86SelectStore(Instruction *I);
50 };
51
52 /// X86SelectConstAddr - Select and emit code to materialize constant address.
53 /// 
54 bool X86FastISel::X86SelectConstAddr(Value *V,
55                                      unsigned &Op0) {
56   // FIXME: Only GlobalAddress for now.
57   GlobalValue *GV = dyn_cast<GlobalValue>(V);
58   if (!GV)
59     return false;
60
61   if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
62     // Issue load from stub if necessary.
63     unsigned Opc = 0;
64     const TargetRegisterClass *RC = NULL;
65     if (TLI.getPointerTy() == MVT::i32) {
66       Opc = X86::MOV32rm;
67       RC  = X86::GR32RegisterClass;
68     } else {
69       Opc = X86::MOV64rm;
70       RC  = X86::GR64RegisterClass;
71     }
72     Op0 = createResultReg(RC);
73     X86AddressMode AM;
74     AM.GV = GV;
75     addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
76     // Prevent loading GV stub multiple times in same MBB.
77     LocalValueMap[V] = Op0;
78   }
79   return true;
80 }
81
82 /// X86SelectStore - Select and emit code to implement store instructions.
83 bool X86FastISel::X86SelectStore(Instruction* I) {
84   MVT VT = MVT::getMVT(I->getOperand(0)->getType());
85   if (VT == MVT::Other || !VT.isSimple())
86     // Unhandled type.  Halt "fast" selection and bail.
87     return false;
88   if (VT == MVT::iPTR)
89     // Use pointer type.
90     VT = TLI.getPointerTy();
91   // We only handle legal types. For example, on x86-32 the instruction
92   // selector contains all of the 64-bit instructions from x86-64,
93   // under the assumption that i64 won't be used if the target doesn't
94   // support it.
95   if (!TLI.isTypeLegal(VT))
96     return false;
97   unsigned Op0 = getRegForValue(I->getOperand(0));
98   if (Op0 == 0)
99     // Unhandled operand. Halt "fast" selection and bail.
100     return false;    
101
102   Value *V = I->getOperand(1);
103   unsigned Op1 = getRegForValue(V);
104   if (Op1 == 0) {
105     // Handle constant load address.
106     if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op1))
107       // Unhandled operand. Halt "fast" selection and bail.
108       return false;    
109   }
110   
111   // Get opcode and regclass of the output for the given load instruction.
112   unsigned Opc = 0;
113   const TargetRegisterClass *RC = NULL;
114   switch (VT.getSimpleVT()) {
115   default: return false;
116   case MVT::i8:
117     Opc = X86::MOV8mr;
118     RC  = X86::GR8RegisterClass;
119     break;
120   case MVT::i16:
121     Opc = X86::MOV16mr;
122     RC  = X86::GR16RegisterClass;
123     break;
124   case MVT::i32:
125     Opc = X86::MOV32mr;
126     RC  = X86::GR32RegisterClass;
127     break;
128   case MVT::i64:
129     // Must be in x86-64 mode.
130     Opc = X86::MOV64mr;
131     RC  = X86::GR64RegisterClass;
132     break;
133   case MVT::f32:
134     if (Subtarget->hasSSE1()) {
135       Opc = X86::MOVSSmr;
136       RC  = X86::FR32RegisterClass;
137     } else {
138       Opc = X86::ST_Fp32m;
139       RC  = X86::RFP32RegisterClass;
140     }
141     break;
142   case MVT::f64:
143     if (Subtarget->hasSSE2()) {
144       Opc = X86::MOVSDmr;
145       RC  = X86::FR64RegisterClass;
146     } else {
147       Opc = X86::ST_Fp64m;
148       RC  = X86::RFP64RegisterClass;
149     }
150     break;
151   case MVT::f80:
152     Opc = X86::ST_FP80m;
153     RC  = X86::RFP80RegisterClass;
154     break;
155   }
156
157   X86AddressMode AM;
158   if (Op1)
159     // Address is in register.
160     AM.Base.Reg = Op1;
161   else
162     AM.GV = cast<GlobalValue>(V);
163   addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Op0);
164   return true;
165 }
166
167 /// X86SelectLoad - Select and emit code to implement load instructions.
168 ///
169 bool X86FastISel::X86SelectLoad(Instruction *I)  {
170   MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
171   if (VT == MVT::Other || !VT.isSimple())
172     // Unhandled type. Halt "fast" selection and bail.
173     return false;
174   if (VT == MVT::iPTR)
175     // Use pointer type.
176     VT = TLI.getPointerTy();
177   // We only handle legal types. For example, on x86-32 the instruction
178   // selector contains all of the 64-bit instructions from x86-64,
179   // under the assumption that i64 won't be used if the target doesn't
180   // support it.
181   if (!TLI.isTypeLegal(VT))
182     return false;
183
184   Value *V = I->getOperand(0);
185   unsigned Op0 = getRegForValue(V);
186   if (Op0 == 0) {
187     // Handle constant load address.
188     if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
189       // Unhandled operand. Halt "fast" selection and bail.
190       return false;    
191   }
192
193   // Get opcode and regclass of the output for the given load instruction.
194   unsigned Opc = 0;
195   const TargetRegisterClass *RC = NULL;
196   switch (VT.getSimpleVT()) {
197   default: return false;
198   case MVT::i8:
199     Opc = X86::MOV8rm;
200     RC  = X86::GR8RegisterClass;
201     break;
202   case MVT::i16:
203     Opc = X86::MOV16rm;
204     RC  = X86::GR16RegisterClass;
205     break;
206   case MVT::i32:
207     Opc = X86::MOV32rm;
208     RC  = X86::GR32RegisterClass;
209     break;
210   case MVT::i64:
211     // Must be in x86-64 mode.
212     Opc = X86::MOV64rm;
213     RC  = X86::GR64RegisterClass;
214     break;
215   case MVT::f32:
216     if (Subtarget->hasSSE1()) {
217       Opc = X86::MOVSSrm;
218       RC  = X86::FR32RegisterClass;
219     } else {
220       Opc = X86::LD_Fp32m;
221       RC  = X86::RFP32RegisterClass;
222     }
223     break;
224   case MVT::f64:
225     if (Subtarget->hasSSE2()) {
226       Opc = X86::MOVSDrm;
227       RC  = X86::FR64RegisterClass;
228     } else {
229       Opc = X86::LD_Fp64m;
230       RC  = X86::RFP64RegisterClass;
231     }
232     break;
233   case MVT::f80:
234     Opc = X86::LD_Fp80m;
235     RC  = X86::RFP80RegisterClass;
236     break;
237   }
238
239   unsigned ResultReg = createResultReg(RC);
240   X86AddressMode AM;
241   if (Op0)
242     // Address is in register.
243     AM.Base.Reg = Op0;
244   else
245     AM.GV = cast<GlobalValue>(V);
246   addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
247   UpdateValueMap(I, ResultReg);
248   return true;
249 }
250
251
252 bool
253 X86FastISel::TargetSelectInstruction(Instruction *I)  {
254   switch (I->getOpcode()) {
255   default: break;
256   case Instruction::Load:
257     return X86SelectLoad(I);
258   case Instruction::Store:
259     return X86SelectStore(I);
260   }
261
262   return false;
263 }
264
265 namespace llvm {
266   llvm::FastISel *X86::createFastISel(MachineFunction &mf,
267                         DenseMap<const Value *, unsigned> &vm,
268                         DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
269     return new X86FastISel(mf, vm, bm);
270   }
271 }