blob: 51ef25a87c6f667996d83943f91a0fb7d5ba3d1d [file] [log] [blame]
Dan Gohman1adf1b02008-08-19 21:45:35 +00001//===-- 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"
Evan Cheng8b19e562008-09-03 06:44:39 +000017#include "X86InstrBuilder.h"
Dan Gohman1adf1b02008-08-19 21:45:35 +000018#include "X86ISelLowering.h"
Evan Cheng88e30412008-09-03 01:04:47 +000019#include "X86RegisterInfo.h"
20#include "X86Subtarget.h"
Dan Gohman22bb3112008-08-22 00:20:26 +000021#include "X86TargetMachine.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000022#include "llvm/CodeGen/FastISel.h"
Owen Anderson667d8f72008-08-29 17:45:56 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000024
25using namespace llvm;
26
27class 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
Evan Cheng8b19e562008-09-03 06:44:39 +000032public:
Dan Gohman3df24e62008-09-03 23:12:08 +000033 explicit X86FastISel(MachineFunction &mf,
34 DenseMap<const Value *, unsigned> &vm,
35 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
36 : FastISel(mf, vm, bm) {
Evan Cheng88e30412008-09-03 01:04:47 +000037 Subtarget = &TM.getSubtarget<X86Subtarget>();
38 }
Evan Chengc3f44b02008-09-03 00:03:49 +000039
Dan Gohman3df24e62008-09-03 23:12:08 +000040 virtual bool TargetSelectInstruction(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000041
Dan Gohman1adf1b02008-08-19 21:45:35 +000042#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000043
44private:
Dan Gohman3df24e62008-09-03 23:12:08 +000045 bool X86SelectConstAddr(Value *V, unsigned &Op0);
Evan Cheng8b19e562008-09-03 06:44:39 +000046
Dan Gohman3df24e62008-09-03 23:12:08 +000047 bool X86SelectLoad(Instruction *I);
Owen Andersona3971df2008-09-04 07:08:58 +000048
49 bool X86SelectStore(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000050};
Dan Gohman99b21822008-08-28 23:21:34 +000051
Evan Cheng8b19e562008-09-03 06:44:39 +000052/// X86SelectConstAddr - Select and emit code to materialize constant address.
53///
54bool X86FastISel::X86SelectConstAddr(Value *V,
Dan Gohman3df24e62008-09-03 23:12:08 +000055 unsigned &Op0) {
Evan Cheng8b19e562008-09-03 06:44:39 +000056 // 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);
Evan Cheng373d50a2008-09-04 06:18:33 +000076 // Prevent loading GV stub multiple times in same MBB.
77 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +000078 }
79 return true;
80}
81
Owen Andersona3971df2008-09-04 07:08:58 +000082/// X86SelectStore - Select and emit code to implement store instructions.
83bool 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 = Op0;
161 else
162 AM.GV = cast<GlobalValue>(V);
163 addFullAddress(BuildMI(MBB, TII.get(Opc)), AM);
164 return true;
165}
166
Evan Cheng8b19e562008-09-03 06:44:39 +0000167/// X86SelectLoad - Select and emit code to implement load instructions.
168///
Dan Gohman3df24e62008-09-03 23:12:08 +0000169bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000170 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);
Dan Gohman3df24e62008-09-03 23:12:08 +0000185 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +0000186 if (Op0 == 0) {
187 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +0000188 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000189 // 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);
Dan Gohman3df24e62008-09-03 23:12:08 +0000247 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000248 return true;
249}
250
251
Dan Gohman99b21822008-08-28 23:21:34 +0000252bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000253X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000254 switch (I->getOpcode()) {
255 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000256 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000257 return X86SelectLoad(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000258 }
259
260 return false;
261}
262
Evan Chengc3f44b02008-09-03 00:03:49 +0000263namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000264 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
265 DenseMap<const Value *, unsigned> &vm,
266 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
267 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000268 }
Dan Gohman99b21822008-08-28 23:21:34 +0000269}