blob: e63120d40e4a9974ef2b4ff5a59348b8ae313150 [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 Gohmand89ae992008-09-05 01:06:14 +000022#include "llvm/Instructions.h"
Dan Gohman6e3f05f2008-09-04 23:26:51 +000023#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);
Dan Gohmand89ae992008-09-05 01:06:14 +000055
56 bool X86SelectZExt(Instruction *I);
57
58 bool X86SelectBranch(Instruction *I);
Dan Gohmanc39f4db2008-09-05 18:30:08 +000059
60 bool X86SelectShift(Instruction *I);
61
62 bool X86SelectSelect(Instruction *I);
Owen Anderson95267a12008-09-05 00:06:23 +000063
Owen Anderson9c7216f2008-09-05 20:49:33 +000064 unsigned TargetMaterializeConstant(Constant *C, MachineConstantPool* MCP);
Evan Chengc3f44b02008-09-03 00:03:49 +000065};
Dan Gohman99b21822008-08-28 23:21:34 +000066
Evan Cheng8b19e562008-09-03 06:44:39 +000067/// X86SelectConstAddr - Select and emit code to materialize constant address.
68///
69bool X86FastISel::X86SelectConstAddr(Value *V,
Dan Gohman3df24e62008-09-03 23:12:08 +000070 unsigned &Op0) {
Evan Cheng8b19e562008-09-03 06:44:39 +000071 // FIXME: Only GlobalAddress for now.
72 GlobalValue *GV = dyn_cast<GlobalValue>(V);
73 if (!GV)
74 return false;
75
76 if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) {
77 // Issue load from stub if necessary.
78 unsigned Opc = 0;
79 const TargetRegisterClass *RC = NULL;
80 if (TLI.getPointerTy() == MVT::i32) {
81 Opc = X86::MOV32rm;
82 RC = X86::GR32RegisterClass;
83 } else {
84 Opc = X86::MOV64rm;
85 RC = X86::GR64RegisterClass;
86 }
87 Op0 = createResultReg(RC);
88 X86AddressMode AM;
89 AM.GV = GV;
90 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
Evan Cheng373d50a2008-09-04 06:18:33 +000091 // Prevent loading GV stub multiple times in same MBB.
92 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +000093 }
94 return true;
95}
96
Owen Andersona3971df2008-09-04 07:08:58 +000097/// X86SelectStore - Select and emit code to implement store instructions.
98bool X86FastISel::X86SelectStore(Instruction* I) {
99 MVT VT = MVT::getMVT(I->getOperand(0)->getType());
100 if (VT == MVT::Other || !VT.isSimple())
101 // Unhandled type. Halt "fast" selection and bail.
102 return false;
103 if (VT == MVT::iPTR)
104 // Use pointer type.
105 VT = TLI.getPointerTy();
106 // We only handle legal types. For example, on x86-32 the instruction
107 // selector contains all of the 64-bit instructions from x86-64,
108 // under the assumption that i64 won't be used if the target doesn't
109 // support it.
110 if (!TLI.isTypeLegal(VT))
111 return false;
112 unsigned Op0 = getRegForValue(I->getOperand(0));
113 if (Op0 == 0)
114 // Unhandled operand. Halt "fast" selection and bail.
115 return false;
116
117 Value *V = I->getOperand(1);
118 unsigned Op1 = getRegForValue(V);
119 if (Op1 == 0) {
120 // Handle constant load address.
121 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op1))
122 // Unhandled operand. Halt "fast" selection and bail.
123 return false;
124 }
125
126 // Get opcode and regclass of the output for the given load instruction.
127 unsigned Opc = 0;
128 const TargetRegisterClass *RC = NULL;
129 switch (VT.getSimpleVT()) {
130 default: return false;
131 case MVT::i8:
132 Opc = X86::MOV8mr;
133 RC = X86::GR8RegisterClass;
134 break;
135 case MVT::i16:
136 Opc = X86::MOV16mr;
137 RC = X86::GR16RegisterClass;
138 break;
139 case MVT::i32:
140 Opc = X86::MOV32mr;
141 RC = X86::GR32RegisterClass;
142 break;
143 case MVT::i64:
144 // Must be in x86-64 mode.
145 Opc = X86::MOV64mr;
146 RC = X86::GR64RegisterClass;
147 break;
148 case MVT::f32:
149 if (Subtarget->hasSSE1()) {
150 Opc = X86::MOVSSmr;
151 RC = X86::FR32RegisterClass;
152 } else {
153 Opc = X86::ST_Fp32m;
154 RC = X86::RFP32RegisterClass;
155 }
156 break;
157 case MVT::f64:
158 if (Subtarget->hasSSE2()) {
159 Opc = X86::MOVSDmr;
160 RC = X86::FR64RegisterClass;
161 } else {
162 Opc = X86::ST_Fp64m;
163 RC = X86::RFP64RegisterClass;
164 }
165 break;
166 case MVT::f80:
167 Opc = X86::ST_FP80m;
168 RC = X86::RFP80RegisterClass;
169 break;
170 }
171
172 X86AddressMode AM;
173 if (Op1)
174 // Address is in register.
Owen Anderson79924eb2008-09-04 16:48:33 +0000175 AM.Base.Reg = Op1;
Owen Andersona3971df2008-09-04 07:08:58 +0000176 else
177 AM.GV = cast<GlobalValue>(V);
Owen Anderson79924eb2008-09-04 16:48:33 +0000178 addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Op0);
Owen Andersona3971df2008-09-04 07:08:58 +0000179 return true;
180}
181
Evan Cheng8b19e562008-09-03 06:44:39 +0000182/// X86SelectLoad - Select and emit code to implement load instructions.
183///
Dan Gohman3df24e62008-09-03 23:12:08 +0000184bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000185 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
186 if (VT == MVT::Other || !VT.isSimple())
187 // Unhandled type. Halt "fast" selection and bail.
188 return false;
189 if (VT == MVT::iPTR)
190 // Use pointer type.
191 VT = TLI.getPointerTy();
192 // We only handle legal types. For example, on x86-32 the instruction
193 // selector contains all of the 64-bit instructions from x86-64,
194 // under the assumption that i64 won't be used if the target doesn't
195 // support it.
196 if (!TLI.isTypeLegal(VT))
197 return false;
198
199 Value *V = I->getOperand(0);
Dan Gohman3df24e62008-09-03 23:12:08 +0000200 unsigned Op0 = getRegForValue(V);
Evan Cheng8b19e562008-09-03 06:44:39 +0000201 if (Op0 == 0) {
202 // Handle constant load address.
Dan Gohman3df24e62008-09-03 23:12:08 +0000203 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Op0))
Evan Cheng8b19e562008-09-03 06:44:39 +0000204 // Unhandled operand. Halt "fast" selection and bail.
205 return false;
206 }
207
208 // Get opcode and regclass of the output for the given load instruction.
209 unsigned Opc = 0;
210 const TargetRegisterClass *RC = NULL;
211 switch (VT.getSimpleVT()) {
212 default: return false;
213 case MVT::i8:
214 Opc = X86::MOV8rm;
215 RC = X86::GR8RegisterClass;
216 break;
217 case MVT::i16:
218 Opc = X86::MOV16rm;
219 RC = X86::GR16RegisterClass;
220 break;
221 case MVT::i32:
222 Opc = X86::MOV32rm;
223 RC = X86::GR32RegisterClass;
224 break;
225 case MVT::i64:
226 // Must be in x86-64 mode.
227 Opc = X86::MOV64rm;
228 RC = X86::GR64RegisterClass;
229 break;
230 case MVT::f32:
231 if (Subtarget->hasSSE1()) {
232 Opc = X86::MOVSSrm;
233 RC = X86::FR32RegisterClass;
234 } else {
235 Opc = X86::LD_Fp32m;
236 RC = X86::RFP32RegisterClass;
237 }
238 break;
239 case MVT::f64:
240 if (Subtarget->hasSSE2()) {
241 Opc = X86::MOVSDrm;
242 RC = X86::FR64RegisterClass;
243 } else {
244 Opc = X86::LD_Fp64m;
245 RC = X86::RFP64RegisterClass;
246 }
247 break;
248 case MVT::f80:
249 Opc = X86::LD_Fp80m;
250 RC = X86::RFP80RegisterClass;
251 break;
252 }
253
254 unsigned ResultReg = createResultReg(RC);
255 X86AddressMode AM;
256 if (Op0)
257 // Address is in register.
258 AM.Base.Reg = Op0;
259 else
260 AM.GV = cast<GlobalValue>(V);
261 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
Dan Gohman3df24e62008-09-03 23:12:08 +0000262 UpdateValueMap(I, ResultReg);
Evan Cheng8b19e562008-09-03 06:44:39 +0000263 return true;
264}
265
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000266bool X86FastISel::X86SelectCmp(Instruction *I) {
267 CmpInst *CI = cast<CmpInst>(I);
268
Dan Gohman4f22bb02008-09-05 01:33:56 +0000269 MVT VT = TLI.getValueType(I->getOperand(0)->getType());
270 if (!TLI.isTypeLegal(VT))
271 return false;
272
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000273 unsigned Op0Reg = getRegForValue(CI->getOperand(0));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000274 if (Op0Reg == 0) return false;
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000275 unsigned Op1Reg = getRegForValue(CI->getOperand(1));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000276 if (Op1Reg == 0) return false;
277
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000278 unsigned Opc;
Dan Gohmanf52550b2008-09-05 01:15:35 +0000279 switch (VT.getSimpleVT()) {
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000280 case MVT::i8: Opc = X86::CMP8rr; break;
281 case MVT::i16: Opc = X86::CMP16rr; break;
282 case MVT::i32: Opc = X86::CMP32rr; break;
283 case MVT::i64: Opc = X86::CMP64rr; break;
284 case MVT::f32: Opc = X86::UCOMISSrr; break;
285 case MVT::f64: Opc = X86::UCOMISDrr; break;
286 default: return false;
287 }
288
289 unsigned ResultReg = createResultReg(&X86::GR8RegClass);
290 switch (CI->getPredicate()) {
291 case CmpInst::FCMP_OEQ: {
292 unsigned EReg = createResultReg(&X86::GR8RegClass);
293 unsigned NPReg = createResultReg(&X86::GR8RegClass);
294 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
295 BuildMI(MBB, TII.get(X86::SETEr), EReg);
296 BuildMI(MBB, TII.get(X86::SETNPr), NPReg);
297 BuildMI(MBB, TII.get(X86::AND8rr), ResultReg).addReg(NPReg).addReg(EReg);
298 break;
299 }
300 case CmpInst::FCMP_UNE: {
301 unsigned NEReg = createResultReg(&X86::GR8RegClass);
302 unsigned PReg = createResultReg(&X86::GR8RegClass);
303 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
304 BuildMI(MBB, TII.get(X86::SETNEr), NEReg);
305 BuildMI(MBB, TII.get(X86::SETPr), PReg);
306 BuildMI(MBB, TII.get(X86::OR8rr), ResultReg).addReg(PReg).addReg(NEReg);
307 break;
308 }
309 case CmpInst::FCMP_OGT:
310 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
311 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
312 break;
313 case CmpInst::FCMP_OGE:
314 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
315 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
316 break;
317 case CmpInst::FCMP_OLT:
318 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
319 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
320 break;
321 case CmpInst::FCMP_OLE:
322 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
323 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
324 break;
325 case CmpInst::FCMP_ONE:
326 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
327 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
328 break;
329 case CmpInst::FCMP_ORD:
330 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
331 BuildMI(MBB, TII.get(X86::SETNPr), ResultReg);
332 break;
333 case CmpInst::FCMP_UNO:
334 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
335 BuildMI(MBB, TII.get(X86::SETPr), ResultReg);
336 break;
337 case CmpInst::FCMP_UEQ:
338 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
339 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
340 break;
341 case CmpInst::FCMP_UGT:
342 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
343 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
344 break;
345 case CmpInst::FCMP_UGE:
346 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
347 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
348 break;
349 case CmpInst::FCMP_ULT:
350 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
351 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
352 break;
353 case CmpInst::FCMP_ULE:
354 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
355 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
356 break;
357 case CmpInst::ICMP_EQ:
358 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
359 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
360 break;
361 case CmpInst::ICMP_NE:
362 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
363 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
364 break;
365 case CmpInst::ICMP_UGT:
366 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
367 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
368 break;
369 case CmpInst::ICMP_UGE:
370 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
371 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
372 break;
373 case CmpInst::ICMP_ULT:
374 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
375 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
376 break;
377 case CmpInst::ICMP_ULE:
378 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
379 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
380 break;
381 case CmpInst::ICMP_SGT:
382 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
383 BuildMI(MBB, TII.get(X86::SETGr), ResultReg);
384 break;
385 case CmpInst::ICMP_SGE:
386 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
387 BuildMI(MBB, TII.get(X86::SETGEr), ResultReg);
388 break;
389 case CmpInst::ICMP_SLT:
390 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
391 BuildMI(MBB, TII.get(X86::SETLr), ResultReg);
392 break;
393 case CmpInst::ICMP_SLE:
394 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
395 BuildMI(MBB, TII.get(X86::SETLEr), ResultReg);
396 break;
397 default:
398 return false;
399 }
400
401 UpdateValueMap(I, ResultReg);
402 return true;
403}
Evan Cheng8b19e562008-09-03 06:44:39 +0000404
Dan Gohmand89ae992008-09-05 01:06:14 +0000405bool X86FastISel::X86SelectZExt(Instruction *I) {
406 // Special-case hack: The only i1 values we know how to produce currently
407 // set the upper bits of an i8 value to zero.
408 if (I->getType() == Type::Int8Ty &&
409 I->getOperand(0)->getType() == Type::Int1Ty) {
410 unsigned ResultReg = getRegForValue(I->getOperand(0));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000411 if (ResultReg == 0) return false;
Dan Gohmand89ae992008-09-05 01:06:14 +0000412 UpdateValueMap(I, ResultReg);
413 return true;
414 }
415
416 return false;
417}
418
419bool X86FastISel::X86SelectBranch(Instruction *I) {
420 BranchInst *BI = cast<BranchInst>(I);
421 // Unconditional branches are selected by tablegen-generated code.
422 unsigned OpReg = getRegForValue(BI->getCondition());
Dan Gohmanf52550b2008-09-05 01:15:35 +0000423 if (OpReg == 0) return false;
Dan Gohmand89ae992008-09-05 01:06:14 +0000424 MachineBasicBlock *TrueMBB = MBBMap[BI->getSuccessor(0)];
425 MachineBasicBlock *FalseMBB = MBBMap[BI->getSuccessor(1)];
426
427 BuildMI(MBB, TII.get(X86::TEST8rr)).addReg(OpReg).addReg(OpReg);
428 BuildMI(MBB, TII.get(X86::JNE)).addMBB(TrueMBB);
429 BuildMI(MBB, TII.get(X86::JMP)).addMBB(FalseMBB);
430
431 MBB->addSuccessor(TrueMBB);
432 MBB->addSuccessor(FalseMBB);
433
434 return true;
435}
436
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000437bool X86FastISel::X86SelectShift(Instruction *I) {
438 unsigned CReg = 0;
439 unsigned Opc = 0;
440 const TargetRegisterClass *RC = NULL;
441 if (I->getType() == Type::Int8Ty) {
442 CReg = X86::CL;
443 RC = &X86::GR8RegClass;
444 switch (I->getOpcode()) {
445 case Instruction::LShr: Opc = X86::SHL8rCL; break;
446 case Instruction::AShr: Opc = X86::SAR8rCL; break;
447 case Instruction::Shl: Opc = X86::SHR8rCL; break;
448 default: return false;
449 }
450 } else if (I->getType() == Type::Int16Ty) {
451 CReg = X86::CX;
452 RC = &X86::GR16RegClass;
453 switch (I->getOpcode()) {
454 case Instruction::LShr: Opc = X86::SHL16rCL; break;
455 case Instruction::AShr: Opc = X86::SAR16rCL; break;
456 case Instruction::Shl: Opc = X86::SHR16rCL; break;
457 default: return false;
458 }
459 } else if (I->getType() == Type::Int32Ty) {
460 CReg = X86::ECX;
461 RC = &X86::GR32RegClass;
462 switch (I->getOpcode()) {
463 case Instruction::LShr: Opc = X86::SHL32rCL; break;
464 case Instruction::AShr: Opc = X86::SAR32rCL; break;
465 case Instruction::Shl: Opc = X86::SHR32rCL; break;
466 default: return false;
467 }
468 } else if (I->getType() == Type::Int64Ty) {
469 CReg = X86::RCX;
470 RC = &X86::GR64RegClass;
471 switch (I->getOpcode()) {
472 case Instruction::LShr: Opc = X86::SHL64rCL; break;
473 case Instruction::AShr: Opc = X86::SAR64rCL; break;
474 case Instruction::Shl: Opc = X86::SHR64rCL; break;
475 default: return false;
476 }
477 } else {
478 return false;
479 }
480
481 unsigned Op0Reg = getRegForValue(I->getOperand(0));
482 if (Op0Reg == 0) return false;
483 unsigned Op1Reg = getRegForValue(I->getOperand(1));
484 if (Op1Reg == 0) return false;
485 TII.copyRegToReg(*MBB, MBB->end(), CReg, Op1Reg, RC, RC);
486 unsigned ResultReg = createResultReg(RC);
487 BuildMI(MBB, TII.get(Opc), ResultReg).addReg(Op0Reg);
488 UpdateValueMap(I, ResultReg);
489 return true;
490}
491
492bool X86FastISel::X86SelectSelect(Instruction *I) {
493 const Type *Ty = I->getOperand(1)->getType();
494 if (isa<PointerType>(Ty))
495 Ty = TLI.getTargetData()->getIntPtrType();
496
497 unsigned Opc = 0;
498 const TargetRegisterClass *RC = NULL;
499 if (Ty == Type::Int16Ty) {
500 Opc = X86::CMOVNE16rr;
501 RC = &X86::GR16RegClass;
502 } else if (Ty == Type::Int32Ty) {
503 Opc = X86::CMOVNE32rr;
504 RC = &X86::GR32RegClass;
505 } else if (Ty == Type::Int64Ty) {
506 Opc = X86::CMOVNE64rr;
507 RC = &X86::GR64RegClass;
508 } else {
509 return false;
510 }
511
512 unsigned Op0Reg = getRegForValue(I->getOperand(0));
513 if (Op0Reg == 0) return false;
514 unsigned Op1Reg = getRegForValue(I->getOperand(1));
515 if (Op1Reg == 0) return false;
516 unsigned Op2Reg = getRegForValue(I->getOperand(2));
517 if (Op2Reg == 0) return false;
518
519 BuildMI(MBB, TII.get(X86::TEST8rr)).addReg(Op0Reg).addReg(Op0Reg);
520 unsigned ResultReg = createResultReg(RC);
521 BuildMI(MBB, TII.get(Opc), ResultReg).addReg(Op1Reg).addReg(Op2Reg);
522 UpdateValueMap(I, ResultReg);
523 return true;
524}
525
Dan Gohman99b21822008-08-28 23:21:34 +0000526bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000527X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000528 switch (I->getOpcode()) {
529 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000530 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000531 return X86SelectLoad(I);
Owen Anderson79924eb2008-09-04 16:48:33 +0000532 case Instruction::Store:
533 return X86SelectStore(I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000534 case Instruction::ICmp:
535 case Instruction::FCmp:
536 return X86SelectCmp(I);
Dan Gohmand89ae992008-09-05 01:06:14 +0000537 case Instruction::ZExt:
538 return X86SelectZExt(I);
539 case Instruction::Br:
540 return X86SelectBranch(I);
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000541 case Instruction::LShr:
542 case Instruction::AShr:
543 case Instruction::Shl:
544 return X86SelectShift(I);
545 case Instruction::Select:
546 return X86SelectSelect(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000547 }
548
549 return false;
550}
551
Owen Anderson9c7216f2008-09-05 20:49:33 +0000552unsigned X86FastISel::TargetMaterializeConstant(Constant *C,
553 MachineConstantPool* MCP) {
Owen Anderson95267a12008-09-05 00:06:23 +0000554 unsigned CPLoad = getRegForValue(C);
555 if (CPLoad != 0)
556 return CPLoad;
557
558 // Can't handle PIC-mode yet.
559 if (TM.getRelocationModel() == Reloc::PIC_)
560 return 0;
561
562 MVT VT = MVT::getMVT(C->getType(), /*HandleUnknown=*/true);
563 if (VT == MVT::Other || !VT.isSimple())
564 // Unhandled type. Halt "fast" selection and bail.
565 return false;
566 if (VT == MVT::iPTR)
567 // Use pointer type.
568 VT = TLI.getPointerTy();
569 // We only handle legal types. For example, on x86-32 the instruction
570 // selector contains all of the 64-bit instructions from x86-64,
571 // under the assumption that i64 won't be used if the target doesn't
572 // support it.
573 if (!TLI.isTypeLegal(VT))
574 return false;
575
576 // Get opcode and regclass of the output for the given load instruction.
577 unsigned Opc = 0;
578 const TargetRegisterClass *RC = NULL;
579 switch (VT.getSimpleVT()) {
580 default: return false;
581 case MVT::i8:
582 Opc = X86::MOV8rm;
583 RC = X86::GR8RegisterClass;
584 break;
585 case MVT::i16:
586 Opc = X86::MOV16rm;
587 RC = X86::GR16RegisterClass;
588 break;
589 case MVT::i32:
590 Opc = X86::MOV32rm;
591 RC = X86::GR32RegisterClass;
592 break;
593 case MVT::i64:
594 // Must be in x86-64 mode.
595 Opc = X86::MOV64rm;
596 RC = X86::GR64RegisterClass;
597 break;
598 case MVT::f32:
599 if (Subtarget->hasSSE1()) {
600 Opc = X86::MOVSSrm;
601 RC = X86::FR32RegisterClass;
602 } else {
603 Opc = X86::LD_Fp32m;
604 RC = X86::RFP32RegisterClass;
605 }
606 break;
607 case MVT::f64:
608 if (Subtarget->hasSSE2()) {
609 Opc = X86::MOVSDrm;
610 RC = X86::FR64RegisterClass;
611 } else {
612 Opc = X86::LD_Fp64m;
613 RC = X86::RFP64RegisterClass;
614 }
615 break;
616 case MVT::f80:
617 Opc = X86::LD_Fp80m;
618 RC = X86::RFP80RegisterClass;
619 break;
620 }
621
622 unsigned ResultReg = createResultReg(RC);
623 if (isa<GlobalValue>(C)) {
624 if (X86SelectConstAddr(C, ResultReg))
625 return ResultReg;
626 else
627 return 0;
628 }
629
630
631 unsigned MCPOffset = MCP->getConstantPoolIndex(C, 0);
632 addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
633 UpdateValueMap(C, ResultReg);
634 return ResultReg;
635}
636
Evan Chengc3f44b02008-09-03 00:03:49 +0000637namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +0000638 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
639 DenseMap<const Value *, unsigned> &vm,
640 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
641 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +0000642 }
Dan Gohman99b21822008-08-28 23:21:34 +0000643}