blob: b6240ddc9408a61f6ecd6d01ccf5d7c51a5c89cd [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 Anderson95267a12008-09-05 00:06:23 +000025#include "llvm/CodeGen/MachineConstantPool.h"
Owen Anderson667d8f72008-08-29 17:45:56 +000026#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000027
28using namespace llvm;
29
30class X86FastISel : public FastISel {
31 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
32 /// make the right decision when generating code for different targets.
33 const X86Subtarget *Subtarget;
34
Evan Cheng8b19e562008-09-03 06:44:39 +000035public:
Dan Gohman3df24e62008-09-03 23:12:08 +000036 explicit X86FastISel(MachineFunction &mf,
37 DenseMap<const Value *, unsigned> &vm,
38 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
39 : FastISel(mf, vm, bm) {
Evan Cheng88e30412008-09-03 01:04:47 +000040 Subtarget = &TM.getSubtarget<X86Subtarget>();
41 }
Evan Chengc3f44b02008-09-03 00:03:49 +000042
Dan Gohman3df24e62008-09-03 23:12:08 +000043 virtual bool TargetSelectInstruction(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000044
Dan Gohman1adf1b02008-08-19 21:45:35 +000045#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000046
47private:
Dan Gohman3df24e62008-09-03 23:12:08 +000048 bool X86SelectConstAddr(Value *V, unsigned &Op0);
Evan Cheng8b19e562008-09-03 06:44:39 +000049
Dan Gohman3df24e62008-09-03 23:12:08 +000050 bool X86SelectLoad(Instruction *I);
Owen Andersona3971df2008-09-04 07:08:58 +000051
52 bool X86SelectStore(Instruction *I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +000053
54 bool X86SelectCmp(Instruction *I);
Owen Anderson95267a12008-09-05 00:06:23 +000055
56 unsigned TargetSelectConstantPoolLoad(Constant *C, MachineConstantPool* MCP);
Evan Chengc3f44b02008-09-03 00:03:49 +000057};
Dan Gohman99b21822008-08-28 23:21:34 +000058
Evan Cheng8b19e562008-09-03 06:44:39 +000059/// X86SelectConstAddr - Select and emit code to materialize constant address.
60///
61bool X86FastISel::X86SelectConstAddr(Value *V,
Dan Gohman3df24e62008-09-03 23:12:08 +000062 unsigned &Op0) {
Evan Cheng8b19e562008-09-03 06:44:39 +000063 // FIXME: Only GlobalAddress for now.
64 GlobalValue *GV = dyn_cast<GlobalValue>(V);
65 if (!GV)
66 return false;
67
68 if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
69 // Issue load from stub if necessary.
70 unsigned Opc = 0;
71 const TargetRegisterClass *RC = NULL;
72 if (TLI.getPointerTy() == MVT::i32) {
73 Opc = X86::MOV32rm;
74 RC = X86::GR32RegisterClass;
75 } else {
76 Opc = X86::MOV64rm;
77 RC = X86::GR64RegisterClass;
78 }
79 Op0 = createResultReg(RC);
80 X86AddressMode AM;
81 AM.GV = GV;
82 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
Evan Cheng373d50a2008-09-04 06:18:33 +000083 // Prevent loading GV stub multiple times in same MBB.
84 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +000085 }
86 return true;
87}
88
Owen Andersona3971df2008-09-04 07:08:58 +000089/// X86SelectStore - Select and emit code to implement store instructions.
90bool X86FastISel::X86SelectStore(Instruction* I) {
91 MVT VT = MVT::getMVT(I->getOperand(0)->getType());
92 if (VT == MVT::Other || !VT.isSimple())
93 // Unhandled type. Halt "fast" selection and bail.
94 return false;
95 if (VT == MVT::iPTR)
96 // Use pointer type.
97 VT = TLI.getPointerTy();
98 // We only handle legal types. For example, on x86-32 the instruction
99 // selector contains all of the 64-bit instructions from x86-64,
100 // under the assumption that i64 won't be used if the target doesn't
101 // support it.
102 if (!TLI.isTypeLegal(VT))
103 return false;
104 unsigned Op0 = getRegForValue(I->getOperand(0));
105 if (Op0 == 0)
106 // Unhandled operand. Halt "fast" selection and bail.
107 return false;
108
109 Value *V = I->getOperand(1);
110 unsigned Op1 = getRegForValue(V);
111 if (Op1 == 0) {
112 // Handle constant load address.
113 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op1))
114 // Unhandled operand. Halt "fast" selection and bail.
115 return false;
116 }
117
118 // Get opcode and regclass of the output for the given load instruction.
119 unsigned Opc = 0;
120 const TargetRegisterClass *RC = NULL;
121 switch (VT.getSimpleVT()) {
122 default: return false;
123 case MVT::i8:
124 Opc = X86::MOV8mr;
125 RC = X86::GR8RegisterClass;
126 break;
127 case MVT::i16:
128 Opc = X86::MOV16mr;
129 RC = X86::GR16RegisterClass;
130 break;
131 case MVT::i32:
132 Opc = X86::MOV32mr;
133 RC = X86::GR32RegisterClass;
134 break;
135 case MVT::i64:
136 // Must be in x86-64 mode.
137 Opc = X86::MOV64mr;
138 RC = X86::GR64RegisterClass;
139 break;
140 case MVT::f32:
141 if (Subtarget->hasSSE1()) {
142 Opc = X86::MOVSSmr;
143 RC = X86::FR32RegisterClass;
144 } else {
145 Opc = X86::ST_Fp32m;
146 RC = X86::RFP32RegisterClass;
147 }
148 break;
149 case MVT::f64:
150 if (Subtarget->hasSSE2()) {
151 Opc = X86::MOVSDmr;
152 RC = X86::FR64RegisterClass;
153 } else {
154 Opc = X86::ST_Fp64m;
155 RC = X86::RFP64RegisterClass;
156 }
157 break;
158 case MVT::f80:
159 Opc = X86::ST_FP80m;
160 RC = X86::RFP80RegisterClass;
161 break;
162 }
163
164 X86AddressMode AM;
165 if (Op1)
166 // Address is in register.
Owen Anderson79924eb2008-09-04 16:48:33 +0000167 AM.Base.Reg = Op1;
Owen Andersona3971df2008-09-04 07:08:58 +0000168 else
169 AM.GV = cast<GlobalValue>(V);
Owen Anderson79924eb2008-09-04 16:48:33 +0000170 addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Op0);
Owen Andersona3971df2008-09-04 07:08:58 +0000171 return true;
172}
173
Evan Cheng8b19e562008-09-03 06:44:39 +0000174/// X86SelectLoad - Select and emit code to implement load instructions.
175///
Dan Gohman3df24e62008-09-03 23:12:08 +0000176bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000177 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
178 if (VT == MVT::Other || !VT.isSimple())
179 // Unhandled type. Halt "fast" selection and bail.
180 return false;
181 if (VT == MVT::iPTR)
182 // Use pointer type.
183 VT = TLI.getPointerTy();
184 // We only handle legal types. For example, on x86-32 the instruction
185 // selector contains all of the 64-bit instructions from x86-64,
186 // under the assumption that i64 won't be used if the target doesn't
187 // support it.
188 if (!TLI.isTypeLegal(VT))
189 return false;
190
191 Value *V = I->getOperand(0);
Dan Gohman3df24e62008-09-03 23:12:08 +0000192 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +0000193 if (Op0 == 0) {
194 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +0000195 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000196 // Unhandled operand. Halt "fast" selection and bail.
197 return false;
198 }
199
200 // Get opcode and regclass of the output for the given load instruction.
201 unsigned Opc = 0;
202 const TargetRegisterClass *RC = NULL;
203 switch (VT.getSimpleVT()) {
204 default: return false;
205 case MVT::i8:
206 Opc = X86::MOV8rm;
207 RC = X86::GR8RegisterClass;
208 break;
209 case MVT::i16:
210 Opc = X86::MOV16rm;
211 RC = X86::GR16RegisterClass;
212 break;
213 case MVT::i32:
214 Opc = X86::MOV32rm;
215 RC = X86::GR32RegisterClass;
216 break;
217 case MVT::i64:
218 // Must be in x86-64 mode.
219 Opc = X86::MOV64rm;
220 RC = X86::GR64RegisterClass;
221 break;
222 case MVT::f32:
223 if (Subtarget->hasSSE1()) {
224 Opc = X86::MOVSSrm;
225 RC = X86::FR32RegisterClass;
226 } else {
227 Opc = X86::LD_Fp32m;
228 RC = X86::RFP32RegisterClass;
229 }
230 break;
231 case MVT::f64:
232 if (Subtarget->hasSSE2()) {
233 Opc = X86::MOVSDrm;
234 RC = X86::FR64RegisterClass;
235 } else {
236 Opc = X86::LD_Fp64m;
237 RC = X86::RFP64RegisterClass;
238 }
239 break;
240 case MVT::f80:
241 Opc = X86::LD_Fp80m;
242 RC = X86::RFP80RegisterClass;
243 break;
244 }
245
246 unsigned ResultReg = createResultReg(RC);
247 X86AddressMode AM;
248 if (Op0)
249 // Address is in register.
250 AM.Base.Reg = Op0;
251 else
252 AM.GV = cast<GlobalValue>(V);
253 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
Dan Gohman3df24e62008-09-03 23:12:08 +0000254 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000255 return true;
256}
257
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000258bool X86FastISel::X86SelectCmp(Instruction *I) {
259 CmpInst *CI = cast<CmpInst>(I);
260
261 unsigned Op0Reg = getRegForValue(CI->getOperand(0));
262 unsigned Op1Reg = getRegForValue(CI->getOperand(1));
263
264 unsigned Opc;
265 switch (TLI.getValueType(I->getOperand(0)->getType()).getSimpleVT()) {
266 case MVT::i8: Opc = X86::CMP8rr; break;
267 case MVT::i16: Opc = X86::CMP16rr; break;
268 case MVT::i32: Opc = X86::CMP32rr; break;
269 case MVT::i64: Opc = X86::CMP64rr; break;
270 case MVT::f32: Opc = X86::UCOMISSrr; break;
271 case MVT::f64: Opc = X86::UCOMISDrr; break;
272 default: return false;
273 }
274
275 unsigned ResultReg = createResultReg(&X86::GR8RegClass);
276 switch (CI->getPredicate()) {
277 case CmpInst::FCMP_OEQ: {
278 unsigned EReg = createResultReg(&X86::GR8RegClass);
279 unsigned NPReg = createResultReg(&X86::GR8RegClass);
280 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
281 BuildMI(MBB, TII.get(X86::SETEr), EReg);
282 BuildMI(MBB, TII.get(X86::SETNPr), NPReg);
283 BuildMI(MBB, TII.get(X86::AND8rr), ResultReg).addReg(NPReg).addReg(EReg);
284 break;
285 }
286 case CmpInst::FCMP_UNE: {
287 unsigned NEReg = createResultReg(&X86::GR8RegClass);
288 unsigned PReg = createResultReg(&X86::GR8RegClass);
289 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
290 BuildMI(MBB, TII.get(X86::SETNEr), NEReg);
291 BuildMI(MBB, TII.get(X86::SETPr), PReg);
292 BuildMI(MBB, TII.get(X86::OR8rr), ResultReg).addReg(PReg).addReg(NEReg);
293 break;
294 }
295 case CmpInst::FCMP_OGT:
296 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
297 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
298 break;
299 case CmpInst::FCMP_OGE:
300 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
301 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
302 break;
303 case CmpInst::FCMP_OLT:
304 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
305 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
306 break;
307 case CmpInst::FCMP_OLE:
308 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
309 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
310 break;
311 case CmpInst::FCMP_ONE:
312 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
313 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
314 break;
315 case CmpInst::FCMP_ORD:
316 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
317 BuildMI(MBB, TII.get(X86::SETNPr), ResultReg);
318 break;
319 case CmpInst::FCMP_UNO:
320 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
321 BuildMI(MBB, TII.get(X86::SETPr), ResultReg);
322 break;
323 case CmpInst::FCMP_UEQ:
324 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
325 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
326 break;
327 case CmpInst::FCMP_UGT:
328 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
329 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
330 break;
331 case CmpInst::FCMP_UGE:
332 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
333 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
334 break;
335 case CmpInst::FCMP_ULT:
336 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
337 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
338 break;
339 case CmpInst::FCMP_ULE:
340 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
341 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
342 break;
343 case CmpInst::ICMP_EQ:
344 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
345 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
346 break;
347 case CmpInst::ICMP_NE:
348 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
349 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
350 break;
351 case CmpInst::ICMP_UGT:
352 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
353 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
354 break;
355 case CmpInst::ICMP_UGE:
356 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
357 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
358 break;
359 case CmpInst::ICMP_ULT:
360 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
361 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
362 break;
363 case CmpInst::ICMP_ULE:
364 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
365 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
366 break;
367 case CmpInst::ICMP_SGT:
368 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
369 BuildMI(MBB, TII.get(X86::SETGr), ResultReg);
370 break;
371 case CmpInst::ICMP_SGE:
372 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
373 BuildMI(MBB, TII.get(X86::SETGEr), ResultReg);
374 break;
375 case CmpInst::ICMP_SLT:
376 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
377 BuildMI(MBB, TII.get(X86::SETLr), ResultReg);
378 break;
379 case CmpInst::ICMP_SLE:
380 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
381 BuildMI(MBB, TII.get(X86::SETLEr), ResultReg);
382 break;
383 default:
384 return false;
385 }
386
387 UpdateValueMap(I, ResultReg);
388 return true;
389}
Evan Cheng8b19e562008-09-03 06:44:39 +0000390
Dan Gohman99b21822008-08-28 23:21:34 +0000391bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000392X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000393 switch (I->getOpcode()) {
394 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000395 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000396 return X86SelectLoad(I);
Owen Anderson79924eb2008-09-04 16:48:33 +0000397 case Instruction::Store:
398 return X86SelectStore(I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000399 case Instruction::ICmp:
400 case Instruction::FCmp:
401 return X86SelectCmp(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000402 }
403
404 return false;
405}
406
Owen Anderson95267a12008-09-05 00:06:23 +0000407unsigned X86FastISel::TargetSelectConstantPoolLoad(Constant *C,
408 MachineConstantPool* MCP) {
409 unsigned CPLoad = getRegForValue(C);
410 if (CPLoad != 0)
411 return CPLoad;
412
413 // Can't handle PIC-mode yet.
414 if (TM.getRelocationModel() == Reloc::PIC_)
415 return 0;
416
417 MVT VT = MVT::getMVT(C->getType(), /*HandleUnknown=*/true);
418 if (VT == MVT::Other || !VT.isSimple())
419 // Unhandled type. Halt "fast" selection and bail.
420 return false;
421 if (VT == MVT::iPTR)
422 // Use pointer type.
423 VT = TLI.getPointerTy();
424 // We only handle legal types. For example, on x86-32 the instruction
425 // selector contains all of the 64-bit instructions from x86-64,
426 // under the assumption that i64 won't be used if the target doesn't
427 // support it.
428 if (!TLI.isTypeLegal(VT))
429 return false;
430
431 // Get opcode and regclass of the output for the given load instruction.
432 unsigned Opc = 0;
433 const TargetRegisterClass *RC = NULL;
434 switch (VT.getSimpleVT()) {
435 default: return false;
436 case MVT::i8:
437 Opc = X86::MOV8rm;
438 RC = X86::GR8RegisterClass;
439 break;
440 case MVT::i16:
441 Opc = X86::MOV16rm;
442 RC = X86::GR16RegisterClass;
443 break;
444 case MVT::i32:
445 Opc = X86::MOV32rm;
446 RC = X86::GR32RegisterClass;
447 break;
448 case MVT::i64:
449 // Must be in x86-64 mode.
450 Opc = X86::MOV64rm;
451 RC = X86::GR64RegisterClass;
452 break;
453 case MVT::f32:
454 if (Subtarget->hasSSE1()) {
455 Opc = X86::MOVSSrm;
456 RC = X86::FR32RegisterClass;
457 } else {
458 Opc = X86::LD_Fp32m;
459 RC = X86::RFP32RegisterClass;
460 }
461 break;
462 case MVT::f64:
463 if (Subtarget->hasSSE2()) {
464 Opc = X86::MOVSDrm;
465 RC = X86::FR64RegisterClass;
466 } else {
467 Opc = X86::LD_Fp64m;
468 RC = X86::RFP64RegisterClass;
469 }
470 break;
471 case MVT::f80:
472 Opc = X86::LD_Fp80m;
473 RC = X86::RFP80RegisterClass;
474 break;
475 }
476
477 unsigned ResultReg = createResultReg(RC);
478 if (isa<GlobalValue>(C)) {
479 if (X86SelectConstAddr(C, ResultReg))
480 return ResultReg;
481 else
482 return 0;
483 }
484
485
486 unsigned MCPOffset = MCP->getConstantPoolIndex(C, 0);
487 addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
488 UpdateValueMap(C, ResultReg);
489 return ResultReg;
490}
491
Evan Chengc3f44b02008-09-03 00:03:49 +0000492namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000493 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
494 DenseMap<const Value *, unsigned> &vm,
495 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
496 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000497 }
Dan Gohman99b21822008-08-28 23:21:34 +0000498}