blob: 4cd3836e3e04f0cbec0cd50746099c6458dd6ac8 [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"
Dan Gohman6e3f05f2008-09-04 23:26:51 +000022#include "llvm/InstrTypes.h"
23#include "llvm/DerivedTypes.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000024#include "llvm/CodeGen/FastISel.h"
Owen Anderson667d8f72008-08-29 17:45:56 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000026
27using namespace llvm;
28
29class X86FastISel : public FastISel {
30 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
31 /// make the right decision when generating code for different targets.
32 const X86Subtarget *Subtarget;
33
Evan Cheng8b19e562008-09-03 06:44:39 +000034public:
Dan Gohman3df24e62008-09-03 23:12:08 +000035 explicit X86FastISel(MachineFunction &mf,
36 DenseMap<const Value *, unsigned> &vm,
37 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
38 : FastISel(mf, vm, bm) {
Evan Cheng88e30412008-09-03 01:04:47 +000039 Subtarget = &TM.getSubtarget<X86Subtarget>();
40 }
Evan Chengc3f44b02008-09-03 00:03:49 +000041
Dan Gohman3df24e62008-09-03 23:12:08 +000042 virtual bool TargetSelectInstruction(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000043
Dan Gohman1adf1b02008-08-19 21:45:35 +000044#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000045
46private:
Dan Gohman3df24e62008-09-03 23:12:08 +000047 bool X86SelectConstAddr(Value *V, unsigned &Op0);
Evan Cheng8b19e562008-09-03 06:44:39 +000048
Dan Gohman3df24e62008-09-03 23:12:08 +000049 bool X86SelectLoad(Instruction *I);
Owen Andersona3971df2008-09-04 07:08:58 +000050
51 bool X86SelectStore(Instruction *I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +000052
53 bool X86SelectCmp(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000054};
Dan Gohman99b21822008-08-28 23:21:34 +000055
Evan Cheng8b19e562008-09-03 06:44:39 +000056/// X86SelectConstAddr - Select and emit code to materialize constant address.
57///
58bool X86FastISel::X86SelectConstAddr(Value *V,
Dan Gohman3df24e62008-09-03 23:12:08 +000059 unsigned &Op0) {
Evan Cheng8b19e562008-09-03 06:44:39 +000060 // FIXME: Only GlobalAddress for now.
61 GlobalValue *GV = dyn_cast<GlobalValue>(V);
62 if (!GV)
63 return false;
64
65 if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
66 // Issue load from stub if necessary.
67 unsigned Opc = 0;
68 const TargetRegisterClass *RC = NULL;
69 if (TLI.getPointerTy() == MVT::i32) {
70 Opc = X86::MOV32rm;
71 RC = X86::GR32RegisterClass;
72 } else {
73 Opc = X86::MOV64rm;
74 RC = X86::GR64RegisterClass;
75 }
76 Op0 = createResultReg(RC);
77 X86AddressMode AM;
78 AM.GV = GV;
79 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
Evan Cheng373d50a2008-09-04 06:18:33 +000080 // Prevent loading GV stub multiple times in same MBB.
81 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +000082 }
83 return true;
84}
85
Owen Andersona3971df2008-09-04 07:08:58 +000086/// X86SelectStore - Select and emit code to implement store instructions.
87bool X86FastISel::X86SelectStore(Instruction* I) {
88 MVT VT = MVT::getMVT(I->getOperand(0)->getType());
89 if (VT == MVT::Other || !VT.isSimple())
90 // Unhandled type. Halt "fast" selection and bail.
91 return false;
92 if (VT == MVT::iPTR)
93 // Use pointer type.
94 VT = TLI.getPointerTy();
95 // We only handle legal types. For example, on x86-32 the instruction
96 // selector contains all of the 64-bit instructions from x86-64,
97 // under the assumption that i64 won't be used if the target doesn't
98 // support it.
99 if (!TLI.isTypeLegal(VT))
100 return false;
101 unsigned Op0 = getRegForValue(I->getOperand(0));
102 if (Op0 == 0)
103 // Unhandled operand. Halt "fast" selection and bail.
104 return false;
105
106 Value *V = I->getOperand(1);
107 unsigned Op1 = getRegForValue(V);
108 if (Op1 == 0) {
109 // Handle constant load address.
110 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op1))
111 // Unhandled operand. Halt "fast" selection and bail.
112 return false;
113 }
114
115 // Get opcode and regclass of the output for the given load instruction.
116 unsigned Opc = 0;
117 const TargetRegisterClass *RC = NULL;
118 switch (VT.getSimpleVT()) {
119 default: return false;
120 case MVT::i8:
121 Opc = X86::MOV8mr;
122 RC = X86::GR8RegisterClass;
123 break;
124 case MVT::i16:
125 Opc = X86::MOV16mr;
126 RC = X86::GR16RegisterClass;
127 break;
128 case MVT::i32:
129 Opc = X86::MOV32mr;
130 RC = X86::GR32RegisterClass;
131 break;
132 case MVT::i64:
133 // Must be in x86-64 mode.
134 Opc = X86::MOV64mr;
135 RC = X86::GR64RegisterClass;
136 break;
137 case MVT::f32:
138 if (Subtarget->hasSSE1()) {
139 Opc = X86::MOVSSmr;
140 RC = X86::FR32RegisterClass;
141 } else {
142 Opc = X86::ST_Fp32m;
143 RC = X86::RFP32RegisterClass;
144 }
145 break;
146 case MVT::f64:
147 if (Subtarget->hasSSE2()) {
148 Opc = X86::MOVSDmr;
149 RC = X86::FR64RegisterClass;
150 } else {
151 Opc = X86::ST_Fp64m;
152 RC = X86::RFP64RegisterClass;
153 }
154 break;
155 case MVT::f80:
156 Opc = X86::ST_FP80m;
157 RC = X86::RFP80RegisterClass;
158 break;
159 }
160
161 X86AddressMode AM;
162 if (Op1)
163 // Address is in register.
Owen Anderson79924eb2008-09-04 16:48:33 +0000164 AM.Base.Reg = Op1;
Owen Andersona3971df2008-09-04 07:08:58 +0000165 else
166 AM.GV = cast<GlobalValue>(V);
Owen Anderson79924eb2008-09-04 16:48:33 +0000167 addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Op0);
Owen Andersona3971df2008-09-04 07:08:58 +0000168 return true;
169}
170
Evan Cheng8b19e562008-09-03 06:44:39 +0000171/// X86SelectLoad - Select and emit code to implement load instructions.
172///
Dan Gohman3df24e62008-09-03 23:12:08 +0000173bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000174 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
175 if (VT == MVT::Other || !VT.isSimple())
176 // Unhandled type. Halt "fast" selection and bail.
177 return false;
178 if (VT == MVT::iPTR)
179 // Use pointer type.
180 VT = TLI.getPointerTy();
181 // We only handle legal types. For example, on x86-32 the instruction
182 // selector contains all of the 64-bit instructions from x86-64,
183 // under the assumption that i64 won't be used if the target doesn't
184 // support it.
185 if (!TLI.isTypeLegal(VT))
186 return false;
187
188 Value *V = I->getOperand(0);
Dan Gohman3df24e62008-09-03 23:12:08 +0000189 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +0000190 if (Op0 == 0) {
191 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +0000192 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000193 // Unhandled operand. Halt "fast" selection and bail.
194 return false;
195 }
196
197 // Get opcode and regclass of the output for the given load instruction.
198 unsigned Opc = 0;
199 const TargetRegisterClass *RC = NULL;
200 switch (VT.getSimpleVT()) {
201 default: return false;
202 case MVT::i8:
203 Opc = X86::MOV8rm;
204 RC = X86::GR8RegisterClass;
205 break;
206 case MVT::i16:
207 Opc = X86::MOV16rm;
208 RC = X86::GR16RegisterClass;
209 break;
210 case MVT::i32:
211 Opc = X86::MOV32rm;
212 RC = X86::GR32RegisterClass;
213 break;
214 case MVT::i64:
215 // Must be in x86-64 mode.
216 Opc = X86::MOV64rm;
217 RC = X86::GR64RegisterClass;
218 break;
219 case MVT::f32:
220 if (Subtarget->hasSSE1()) {
221 Opc = X86::MOVSSrm;
222 RC = X86::FR32RegisterClass;
223 } else {
224 Opc = X86::LD_Fp32m;
225 RC = X86::RFP32RegisterClass;
226 }
227 break;
228 case MVT::f64:
229 if (Subtarget->hasSSE2()) {
230 Opc = X86::MOVSDrm;
231 RC = X86::FR64RegisterClass;
232 } else {
233 Opc = X86::LD_Fp64m;
234 RC = X86::RFP64RegisterClass;
235 }
236 break;
237 case MVT::f80:
238 Opc = X86::LD_Fp80m;
239 RC = X86::RFP80RegisterClass;
240 break;
241 }
242
243 unsigned ResultReg = createResultReg(RC);
244 X86AddressMode AM;
245 if (Op0)
246 // Address is in register.
247 AM.Base.Reg = Op0;
248 else
249 AM.GV = cast<GlobalValue>(V);
250 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
Dan Gohman3df24e62008-09-03 23:12:08 +0000251 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000252 return true;
253}
254
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000255bool X86FastISel::X86SelectCmp(Instruction *I) {
256 CmpInst *CI = cast<CmpInst>(I);
257
258 unsigned Op0Reg = getRegForValue(CI->getOperand(0));
259 unsigned Op1Reg = getRegForValue(CI->getOperand(1));
260
261 unsigned Opc;
262 switch (TLI.getValueType(I->getOperand(0)->getType()).getSimpleVT()) {
263 case MVT::i8: Opc = X86::CMP8rr; break;
264 case MVT::i16: Opc = X86::CMP16rr; break;
265 case MVT::i32: Opc = X86::CMP32rr; break;
266 case MVT::i64: Opc = X86::CMP64rr; break;
267 case MVT::f32: Opc = X86::UCOMISSrr; break;
268 case MVT::f64: Opc = X86::UCOMISDrr; break;
269 default: return false;
270 }
271
272 unsigned ResultReg = createResultReg(&X86::GR8RegClass);
273 switch (CI->getPredicate()) {
274 case CmpInst::FCMP_OEQ: {
275 unsigned EReg = createResultReg(&X86::GR8RegClass);
276 unsigned NPReg = createResultReg(&X86::GR8RegClass);
277 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
278 BuildMI(MBB, TII.get(X86::SETEr), EReg);
279 BuildMI(MBB, TII.get(X86::SETNPr), NPReg);
280 BuildMI(MBB, TII.get(X86::AND8rr), ResultReg).addReg(NPReg).addReg(EReg);
281 break;
282 }
283 case CmpInst::FCMP_UNE: {
284 unsigned NEReg = createResultReg(&X86::GR8RegClass);
285 unsigned PReg = createResultReg(&X86::GR8RegClass);
286 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
287 BuildMI(MBB, TII.get(X86::SETNEr), NEReg);
288 BuildMI(MBB, TII.get(X86::SETPr), PReg);
289 BuildMI(MBB, TII.get(X86::OR8rr), ResultReg).addReg(PReg).addReg(NEReg);
290 break;
291 }
292 case CmpInst::FCMP_OGT:
293 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
294 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
295 break;
296 case CmpInst::FCMP_OGE:
297 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
298 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
299 break;
300 case CmpInst::FCMP_OLT:
301 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
302 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
303 break;
304 case CmpInst::FCMP_OLE:
305 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
306 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
307 break;
308 case CmpInst::FCMP_ONE:
309 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
310 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
311 break;
312 case CmpInst::FCMP_ORD:
313 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
314 BuildMI(MBB, TII.get(X86::SETNPr), ResultReg);
315 break;
316 case CmpInst::FCMP_UNO:
317 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
318 BuildMI(MBB, TII.get(X86::SETPr), ResultReg);
319 break;
320 case CmpInst::FCMP_UEQ:
321 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
322 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
323 break;
324 case CmpInst::FCMP_UGT:
325 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
326 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
327 break;
328 case CmpInst::FCMP_UGE:
329 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
330 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
331 break;
332 case CmpInst::FCMP_ULT:
333 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
334 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
335 break;
336 case CmpInst::FCMP_ULE:
337 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
338 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
339 break;
340 case CmpInst::ICMP_EQ:
341 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
342 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
343 break;
344 case CmpInst::ICMP_NE:
345 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
346 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
347 break;
348 case CmpInst::ICMP_UGT:
349 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
350 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
351 break;
352 case CmpInst::ICMP_UGE:
353 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
354 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
355 break;
356 case CmpInst::ICMP_ULT:
357 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
358 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
359 break;
360 case CmpInst::ICMP_ULE:
361 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
362 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
363 break;
364 case CmpInst::ICMP_SGT:
365 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
366 BuildMI(MBB, TII.get(X86::SETGr), ResultReg);
367 break;
368 case CmpInst::ICMP_SGE:
369 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
370 BuildMI(MBB, TII.get(X86::SETGEr), ResultReg);
371 break;
372 case CmpInst::ICMP_SLT:
373 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
374 BuildMI(MBB, TII.get(X86::SETLr), ResultReg);
375 break;
376 case CmpInst::ICMP_SLE:
377 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
378 BuildMI(MBB, TII.get(X86::SETLEr), ResultReg);
379 break;
380 default:
381 return false;
382 }
383
384 UpdateValueMap(I, ResultReg);
385 return true;
386}
Evan Cheng8b19e562008-09-03 06:44:39 +0000387
Dan Gohman99b21822008-08-28 23:21:34 +0000388bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000389X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000390 switch (I->getOpcode()) {
391 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000392 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000393 return X86SelectLoad(I);
Owen Anderson79924eb2008-09-04 16:48:33 +0000394 case Instruction::Store:
395 return X86SelectStore(I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000396 case Instruction::ICmp:
397 case Instruction::FCmp:
398 return X86SelectCmp(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000399 }
400
401 return false;
402}
403
Evan Chengc3f44b02008-09-03 00:03:49 +0000404namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000405 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
406 DenseMap<const Value *, unsigned> &vm,
407 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
408 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000409 }
Dan Gohman99b21822008-08-28 23:21:34 +0000410}