blob: 3f5d6f99f612db8bcb99bbb5a734bfd32f989b82 [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 Chengf3d4efe2008-09-07 09:09:33 +000022#include "llvm/CallingConv.h"
Dan Gohman6e3f05f2008-09-04 23:26:51 +000023#include "llvm/DerivedTypes.h"
Evan Chengf3d4efe2008-09-07 09:09:33 +000024#include "llvm/Instructions.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000025#include "llvm/CodeGen/FastISel.h"
Owen Anderson95267a12008-09-05 00:06:23 +000026#include "llvm/CodeGen/MachineConstantPool.h"
Evan Chengf3d4efe2008-09-07 09:09:33 +000027#include "llvm/CodeGen/MachineFrameInfo.h"
Owen Anderson667d8f72008-08-29 17:45:56 +000028#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chengf3d4efe2008-09-07 09:09:33 +000029#include "llvm/Support/CallSite.h"
Evan Chengc3f44b02008-09-03 00:03:49 +000030
31using namespace llvm;
32
33class X86FastISel : public FastISel {
Evan Chengf3d4efe2008-09-07 09:09:33 +000034 /// MFI - Keep track of objects allocated on the stack.
35 ///
36 MachineFrameInfo *MFI;
37
Evan Chengc3f44b02008-09-03 00:03:49 +000038 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
39 /// make the right decision when generating code for different targets.
40 const X86Subtarget *Subtarget;
Evan Chengf3d4efe2008-09-07 09:09:33 +000041
42 /// StackPtr - Register used as the stack pointer.
43 ///
44 unsigned StackPtr;
45
46 /// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87
47 /// floating point ops.
48 /// When SSE is available, use it for f32 operations.
49 /// When SSE2 is available, use it for f64 operations.
50 bool X86ScalarSSEf64;
51 bool X86ScalarSSEf32;
52
Evan Cheng8b19e562008-09-03 06:44:39 +000053public:
Dan Gohman3df24e62008-09-03 23:12:08 +000054 explicit X86FastISel(MachineFunction &mf,
55 DenseMap<const Value *, unsigned> &vm,
56 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm)
Evan Chengf3d4efe2008-09-07 09:09:33 +000057 : FastISel(mf, vm, bm), MFI(MF.getFrameInfo()) {
Evan Cheng88e30412008-09-03 01:04:47 +000058 Subtarget = &TM.getSubtarget<X86Subtarget>();
Evan Chengf3d4efe2008-09-07 09:09:33 +000059 StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
60 X86ScalarSSEf64 = Subtarget->hasSSE2();
61 X86ScalarSSEf32 = Subtarget->hasSSE1();
Evan Cheng88e30412008-09-03 01:04:47 +000062 }
Evan Chengc3f44b02008-09-03 00:03:49 +000063
Dan Gohman3df24e62008-09-03 23:12:08 +000064 virtual bool TargetSelectInstruction(Instruction *I);
Evan Chengc3f44b02008-09-03 00:03:49 +000065
Dan Gohman1adf1b02008-08-19 21:45:35 +000066#include "X86GenFastISel.inc"
Evan Cheng8b19e562008-09-03 06:44:39 +000067
68private:
Evan Cheng0de588f2008-09-05 21:00:03 +000069 bool X86FastEmitLoad(MVT VT, unsigned Op0, Value *V, unsigned &RR);
70
Evan Chengf3d4efe2008-09-07 09:09:33 +000071 bool X86FastEmitStore(MVT VT, unsigned Val,
72 unsigned Ptr, unsigned Offset, Value *V);
Evan Cheng24e3a902008-09-08 06:35:17 +000073
74 bool X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, unsigned Src, MVT SrcVT,
75 unsigned &ResultReg);
Evan Cheng0de588f2008-09-05 21:00:03 +000076
Evan Cheng59fbc802008-09-09 01:26:59 +000077 bool X86SelectConstAddr(Value *V, unsigned &Op0,
78 bool isCall = false, bool inReg = false);
Evan Cheng8b19e562008-09-03 06:44:39 +000079
Dan Gohman3df24e62008-09-03 23:12:08 +000080 bool X86SelectLoad(Instruction *I);
Owen Andersona3971df2008-09-04 07:08:58 +000081
82 bool X86SelectStore(Instruction *I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +000083
84 bool X86SelectCmp(Instruction *I);
Dan Gohmand89ae992008-09-05 01:06:14 +000085
86 bool X86SelectZExt(Instruction *I);
87
88 bool X86SelectBranch(Instruction *I);
Dan Gohmanc39f4db2008-09-05 18:30:08 +000089
90 bool X86SelectShift(Instruction *I);
91
92 bool X86SelectSelect(Instruction *I);
Evan Cheng0de588f2008-09-05 21:00:03 +000093
Evan Cheng10a8d9c2008-09-07 08:47:42 +000094 bool X86SelectTrunc(Instruction *I);
95
Evan Chengf3d4efe2008-09-07 09:09:33 +000096 bool X86SelectCall(Instruction *I);
97
98 CCAssignFn *CCAssignFnForCall(unsigned CC, bool isTailCall = false);
99
Owen Anderson9c7216f2008-09-05 20:49:33 +0000100 unsigned TargetMaterializeConstant(Constant *C, MachineConstantPool* MCP);
Evan Chengf3d4efe2008-09-07 09:09:33 +0000101
102 /// isScalarFPTypeInSSEReg - Return true if the specified scalar FP type is
103 /// computed in an SSE register, not on the X87 floating point stack.
104 bool isScalarFPTypeInSSEReg(MVT VT) const {
105 return (VT == MVT::f64 && X86ScalarSSEf64) || // f64 is when SSE2
106 (VT == MVT::f32 && X86ScalarSSEf32); // f32 is when SSE1
107 }
108
Evan Chengc3f44b02008-09-03 00:03:49 +0000109};
Dan Gohman99b21822008-08-28 23:21:34 +0000110
Evan Chengdebdea02008-09-08 17:15:42 +0000111static bool isTypeLegal(const Type *Ty, const TargetLowering &TLI, MVT &VT,
112 bool AllowI1 = false) {
Evan Chengf3d4efe2008-09-07 09:09:33 +0000113 VT = MVT::getMVT(Ty, /*HandleUnknown=*/true);
114 if (VT == MVT::Other || !VT.isSimple())
115 // Unhandled type. Halt "fast" selection and bail.
116 return false;
117 if (VT == MVT::iPTR)
118 // Use pointer type.
119 VT = TLI.getPointerTy();
120 // We only handle legal types. For example, on x86-32 the instruction
121 // selector contains all of the 64-bit instructions from x86-64,
122 // under the assumption that i64 won't be used if the target doesn't
123 // support it.
Evan Chengdebdea02008-09-08 17:15:42 +0000124 return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
Evan Chengf3d4efe2008-09-07 09:09:33 +0000125}
126
127#include "X86GenCallingConv.inc"
128
129/// CCAssignFnForCall - Selects the correct CCAssignFn for a given calling
130/// convention.
131CCAssignFn *X86FastISel::CCAssignFnForCall(unsigned CC, bool isTaillCall) {
132 if (Subtarget->is64Bit()) {
133 if (Subtarget->isTargetWin64())
134 return CC_X86_Win64_C;
135 else if (CC == CallingConv::Fast && isTaillCall)
136 return CC_X86_64_TailCall;
137 else
138 return CC_X86_64_C;
139 }
140
141 if (CC == CallingConv::X86_FastCall)
142 return CC_X86_32_FastCall;
143 else if (CC == CallingConv::Fast && isTaillCall)
144 return CC_X86_32_TailCall;
145 else if (CC == CallingConv::Fast)
146 return CC_X86_32_FastCC;
147 else
148 return CC_X86_32_C;
149}
150
Evan Cheng0de588f2008-09-05 21:00:03 +0000151/// X86FastEmitLoad - Emit a machine instruction to load a value of type VT.
Evan Chengf3d4efe2008-09-07 09:09:33 +0000152/// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV.
Evan Cheng0de588f2008-09-05 21:00:03 +0000153/// Return true and the result register by reference if it is possible.
Evan Chengf3d4efe2008-09-07 09:09:33 +0000154bool X86FastISel::X86FastEmitLoad(MVT VT, unsigned Ptr, Value *GV,
Evan Cheng0de588f2008-09-05 21:00:03 +0000155 unsigned &ResultReg) {
156 // Get opcode and regclass of the output for the given load instruction.
157 unsigned Opc = 0;
158 const TargetRegisterClass *RC = NULL;
159 switch (VT.getSimpleVT()) {
160 default: return false;
161 case MVT::i8:
162 Opc = X86::MOV8rm;
163 RC = X86::GR8RegisterClass;
164 break;
165 case MVT::i16:
166 Opc = X86::MOV16rm;
167 RC = X86::GR16RegisterClass;
168 break;
169 case MVT::i32:
170 Opc = X86::MOV32rm;
171 RC = X86::GR32RegisterClass;
172 break;
173 case MVT::i64:
174 // Must be in x86-64 mode.
175 Opc = X86::MOV64rm;
176 RC = X86::GR64RegisterClass;
177 break;
178 case MVT::f32:
179 if (Subtarget->hasSSE1()) {
180 Opc = X86::MOVSSrm;
181 RC = X86::FR32RegisterClass;
182 } else {
183 Opc = X86::LD_Fp32m;
184 RC = X86::RFP32RegisterClass;
185 }
186 break;
187 case MVT::f64:
188 if (Subtarget->hasSSE2()) {
189 Opc = X86::MOVSDrm;
190 RC = X86::FR64RegisterClass;
191 } else {
192 Opc = X86::LD_Fp64m;
193 RC = X86::RFP64RegisterClass;
194 }
195 break;
196 case MVT::f80:
197 Opc = X86::LD_Fp80m;
198 RC = X86::RFP80RegisterClass;
199 break;
200 }
201
202 ResultReg = createResultReg(RC);
203 X86AddressMode AM;
Evan Chengf3d4efe2008-09-07 09:09:33 +0000204 if (Ptr)
Evan Cheng0de588f2008-09-05 21:00:03 +0000205 // Address is in register.
Evan Chengf3d4efe2008-09-07 09:09:33 +0000206 AM.Base.Reg = Ptr;
Evan Cheng0de588f2008-09-05 21:00:03 +0000207 else
Evan Chengf3d4efe2008-09-07 09:09:33 +0000208 AM.GV = cast<GlobalValue>(GV);
Evan Cheng0de588f2008-09-05 21:00:03 +0000209 addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
210 return true;
211}
212
Evan Chengf3d4efe2008-09-07 09:09:33 +0000213/// X86FastEmitStore - Emit a machine instruction to store a value Val of
214/// type VT. The address is either pre-computed, consisted of a base ptr, Ptr
215/// and a displacement offset, or a GlobalAddress,
Evan Cheng0de588f2008-09-05 21:00:03 +0000216/// i.e. V. Return true if it is possible.
217bool
Evan Chengf3d4efe2008-09-07 09:09:33 +0000218X86FastISel::X86FastEmitStore(MVT VT, unsigned Val,
219 unsigned Ptr, unsigned Offset, Value *V) {
Dan Gohman863890e2008-09-08 16:31:35 +0000220 // Get opcode and regclass of the output for the given store instruction.
Evan Cheng0de588f2008-09-05 21:00:03 +0000221 unsigned Opc = 0;
222 const TargetRegisterClass *RC = NULL;
223 switch (VT.getSimpleVT()) {
224 default: return false;
225 case MVT::i8:
226 Opc = X86::MOV8mr;
227 RC = X86::GR8RegisterClass;
228 break;
229 case MVT::i16:
230 Opc = X86::MOV16mr;
231 RC = X86::GR16RegisterClass;
232 break;
233 case MVT::i32:
234 Opc = X86::MOV32mr;
235 RC = X86::GR32RegisterClass;
236 break;
237 case MVT::i64:
238 // Must be in x86-64 mode.
239 Opc = X86::MOV64mr;
240 RC = X86::GR64RegisterClass;
241 break;
242 case MVT::f32:
243 if (Subtarget->hasSSE1()) {
244 Opc = X86::MOVSSmr;
245 RC = X86::FR32RegisterClass;
246 } else {
247 Opc = X86::ST_Fp32m;
248 RC = X86::RFP32RegisterClass;
249 }
250 break;
251 case MVT::f64:
252 if (Subtarget->hasSSE2()) {
253 Opc = X86::MOVSDmr;
254 RC = X86::FR64RegisterClass;
255 } else {
256 Opc = X86::ST_Fp64m;
257 RC = X86::RFP64RegisterClass;
258 }
259 break;
260 case MVT::f80:
261 Opc = X86::ST_FP80m;
262 RC = X86::RFP80RegisterClass;
263 break;
264 }
265
266 X86AddressMode AM;
Evan Chengf3d4efe2008-09-07 09:09:33 +0000267 if (Ptr) {
Evan Cheng0de588f2008-09-05 21:00:03 +0000268 // Address is in register.
Evan Chengf3d4efe2008-09-07 09:09:33 +0000269 AM.Base.Reg = Ptr;
270 AM.Disp = Offset;
271 } else
Evan Cheng0de588f2008-09-05 21:00:03 +0000272 AM.GV = cast<GlobalValue>(V);
Evan Chengf3d4efe2008-09-07 09:09:33 +0000273 addFullAddress(BuildMI(MBB, TII.get(Opc)), AM).addReg(Val);
Evan Cheng0de588f2008-09-05 21:00:03 +0000274 return true;
275}
276
Evan Cheng24e3a902008-09-08 06:35:17 +0000277/// X86FastEmitExtend - Emit a machine instruction to extend a value Src of
278/// type SrcVT to type DstVT using the specified extension opcode Opc (e.g.
279/// ISD::SIGN_EXTEND).
280bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT,
281 unsigned Src, MVT SrcVT,
282 unsigned &ResultReg) {
283 ResultReg = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Opc, Src);
284 return ResultReg != 0;
285}
286
Evan Cheng8b19e562008-09-03 06:44:39 +0000287/// X86SelectConstAddr - Select and emit code to materialize constant address.
288///
Evan Cheng59fbc802008-09-09 01:26:59 +0000289bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0,
290 bool isCall, bool inReg) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000291 // FIXME: Only GlobalAddress for now.
292 GlobalValue *GV = dyn_cast<GlobalValue>(V);
293 if (!GV)
294 return false;
295
Evan Chengf3d4efe2008-09-07 09:09:33 +0000296 if (Subtarget->GVRequiresExtraLoad(GV, TM, isCall)) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000297 // Issue load from stub if necessary.
298 unsigned Opc = 0;
299 const TargetRegisterClass *RC = NULL;
300 if (TLI.getPointerTy() == MVT::i32) {
301 Opc = X86::MOV32rm;
302 RC = X86::GR32RegisterClass;
303 } else {
304 Opc = X86::MOV64rm;
305 RC = X86::GR64RegisterClass;
306 }
307 Op0 = createResultReg(RC);
308 X86AddressMode AM;
309 AM.GV = GV;
310 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
Evan Cheng373d50a2008-09-04 06:18:33 +0000311 // Prevent loading GV stub multiple times in same MBB.
312 LocalValueMap[V] = Op0;
Evan Cheng59fbc802008-09-09 01:26:59 +0000313 } else if (inReg) {
314 unsigned Opc = 0;
315 const TargetRegisterClass *RC = NULL;
316 if (TLI.getPointerTy() == MVT::i32) {
317 Opc = X86::LEA32r;
318 RC = X86::GR32RegisterClass;
319 } else {
320 Opc = X86::LEA64r;
321 RC = X86::GR64RegisterClass;
322 }
323 Op0 = createResultReg(RC);
324 X86AddressMode AM;
325 AM.GV = GV;
326 addFullAddress(BuildMI(MBB, TII.get(Opc), Op0), AM);
327 // Prevent materializing GV address multiple times in same MBB.
328 LocalValueMap[V] = Op0;
Evan Cheng8b19e562008-09-03 06:44:39 +0000329 }
Evan Cheng59fbc802008-09-09 01:26:59 +0000330
Evan Cheng8b19e562008-09-03 06:44:39 +0000331 return true;
332}
333
Owen Andersona3971df2008-09-04 07:08:58 +0000334/// X86SelectStore - Select and emit code to implement store instructions.
335bool X86FastISel::X86SelectStore(Instruction* I) {
Evan Cheng24e3a902008-09-08 06:35:17 +0000336 MVT VT;
337 if (!isTypeLegal(I->getOperand(0)->getType(), TLI, VT))
Owen Andersona3971df2008-09-04 07:08:58 +0000338 return false;
Evan Chengf3d4efe2008-09-07 09:09:33 +0000339 unsigned Val = getRegForValue(I->getOperand(0));
340 if (Val == 0)
Owen Andersona3971df2008-09-04 07:08:58 +0000341 // Unhandled operand. Halt "fast" selection and bail.
342 return false;
343
344 Value *V = I->getOperand(1);
Evan Cheng59fbc802008-09-09 01:26:59 +0000345 unsigned Ptr = lookUpRegForValue(V);
346 if (!Ptr) {
347 // Handle constant load address.
348 // FIXME: If load type is something we can't handle, this can result in
349 // a dead stub load instruction.
350 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) {
351 Ptr = getRegForValue(V);
352 if (Ptr == 0)
353 // Unhandled operand. Halt "fast" selection and bail.
354 return false;
355 }
Owen Andersona3971df2008-09-04 07:08:58 +0000356 }
Owen Andersona3971df2008-09-04 07:08:58 +0000357
Evan Chengf3d4efe2008-09-07 09:09:33 +0000358 return X86FastEmitStore(VT, Val, Ptr, 0, V);
Owen Andersona3971df2008-09-04 07:08:58 +0000359}
360
Evan Cheng8b19e562008-09-03 06:44:39 +0000361/// X86SelectLoad - Select and emit code to implement load instructions.
362///
Dan Gohman3df24e62008-09-03 23:12:08 +0000363bool X86FastISel::X86SelectLoad(Instruction *I) {
Evan Chengf3d4efe2008-09-07 09:09:33 +0000364 MVT VT;
365 if (!isTypeLegal(I->getType(), TLI, VT))
Evan Cheng8b19e562008-09-03 06:44:39 +0000366 return false;
367
368 Value *V = I->getOperand(0);
Evan Cheng59fbc802008-09-09 01:26:59 +0000369 unsigned Ptr = lookUpRegForValue(V);
370 if (!Ptr) {
Evan Cheng8b19e562008-09-03 06:44:39 +0000371 // Handle constant load address.
Evan Cheng0de588f2008-09-05 21:00:03 +0000372 // FIXME: If load type is something we can't handle, this can result in
373 // a dead stub load instruction.
Evan Cheng59fbc802008-09-09 01:26:59 +0000374 if (!isa<Constant>(V) || !X86SelectConstAddr(V, Ptr)) {
375 Ptr = getRegForValue(V);
376 if (Ptr == 0)
377 // Unhandled operand. Halt "fast" selection and bail.
378 return false;
379 }
Evan Cheng8b19e562008-09-03 06:44:39 +0000380 }
381
Evan Cheng0de588f2008-09-05 21:00:03 +0000382 unsigned ResultReg = 0;
Evan Chengf3d4efe2008-09-07 09:09:33 +0000383 if (X86FastEmitLoad(VT, Ptr, V, ResultReg)) {
Evan Cheng0de588f2008-09-05 21:00:03 +0000384 UpdateValueMap(I, ResultReg);
385 return true;
Evan Cheng8b19e562008-09-03 06:44:39 +0000386 }
Evan Cheng0de588f2008-09-05 21:00:03 +0000387 return false;
Evan Cheng8b19e562008-09-03 06:44:39 +0000388}
389
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000390bool X86FastISel::X86SelectCmp(Instruction *I) {
391 CmpInst *CI = cast<CmpInst>(I);
392
Dan Gohman4f22bb02008-09-05 01:33:56 +0000393 MVT VT = TLI.getValueType(I->getOperand(0)->getType());
394 if (!TLI.isTypeLegal(VT))
395 return false;
396
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000397 unsigned Op0Reg = getRegForValue(CI->getOperand(0));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000398 if (Op0Reg == 0) return false;
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000399 unsigned Op1Reg = getRegForValue(CI->getOperand(1));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000400 if (Op1Reg == 0) return false;
401
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000402 unsigned Opc;
Dan Gohmanf52550b2008-09-05 01:15:35 +0000403 switch (VT.getSimpleVT()) {
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000404 case MVT::i8: Opc = X86::CMP8rr; break;
405 case MVT::i16: Opc = X86::CMP16rr; break;
406 case MVT::i32: Opc = X86::CMP32rr; break;
407 case MVT::i64: Opc = X86::CMP64rr; break;
408 case MVT::f32: Opc = X86::UCOMISSrr; break;
409 case MVT::f64: Opc = X86::UCOMISDrr; break;
410 default: return false;
411 }
412
413 unsigned ResultReg = createResultReg(&X86::GR8RegClass);
414 switch (CI->getPredicate()) {
415 case CmpInst::FCMP_OEQ: {
416 unsigned EReg = createResultReg(&X86::GR8RegClass);
417 unsigned NPReg = createResultReg(&X86::GR8RegClass);
418 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
419 BuildMI(MBB, TII.get(X86::SETEr), EReg);
420 BuildMI(MBB, TII.get(X86::SETNPr), NPReg);
421 BuildMI(MBB, TII.get(X86::AND8rr), ResultReg).addReg(NPReg).addReg(EReg);
422 break;
423 }
424 case CmpInst::FCMP_UNE: {
425 unsigned NEReg = createResultReg(&X86::GR8RegClass);
426 unsigned PReg = createResultReg(&X86::GR8RegClass);
427 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
428 BuildMI(MBB, TII.get(X86::SETNEr), NEReg);
429 BuildMI(MBB, TII.get(X86::SETPr), PReg);
430 BuildMI(MBB, TII.get(X86::OR8rr), ResultReg).addReg(PReg).addReg(NEReg);
431 break;
432 }
433 case CmpInst::FCMP_OGT:
434 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
435 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
436 break;
437 case CmpInst::FCMP_OGE:
438 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
439 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
440 break;
441 case CmpInst::FCMP_OLT:
442 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
443 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
444 break;
445 case CmpInst::FCMP_OLE:
446 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
447 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
448 break;
449 case CmpInst::FCMP_ONE:
450 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
451 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
452 break;
453 case CmpInst::FCMP_ORD:
454 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
455 BuildMI(MBB, TII.get(X86::SETNPr), ResultReg);
456 break;
457 case CmpInst::FCMP_UNO:
458 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
459 BuildMI(MBB, TII.get(X86::SETPr), ResultReg);
460 break;
461 case CmpInst::FCMP_UEQ:
462 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
463 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
464 break;
465 case CmpInst::FCMP_UGT:
466 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
467 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
468 break;
469 case CmpInst::FCMP_UGE:
470 BuildMI(MBB, TII.get(Opc)).addReg(Op1Reg).addReg(Op0Reg);
471 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
472 break;
473 case CmpInst::FCMP_ULT:
474 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
475 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
476 break;
477 case CmpInst::FCMP_ULE:
478 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
479 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
480 break;
481 case CmpInst::ICMP_EQ:
482 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
483 BuildMI(MBB, TII.get(X86::SETEr), ResultReg);
484 break;
485 case CmpInst::ICMP_NE:
486 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
487 BuildMI(MBB, TII.get(X86::SETNEr), ResultReg);
488 break;
489 case CmpInst::ICMP_UGT:
490 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
491 BuildMI(MBB, TII.get(X86::SETAr), ResultReg);
492 break;
493 case CmpInst::ICMP_UGE:
494 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
495 BuildMI(MBB, TII.get(X86::SETAEr), ResultReg);
496 break;
497 case CmpInst::ICMP_ULT:
498 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
499 BuildMI(MBB, TII.get(X86::SETBr), ResultReg);
500 break;
501 case CmpInst::ICMP_ULE:
502 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
503 BuildMI(MBB, TII.get(X86::SETBEr), ResultReg);
504 break;
505 case CmpInst::ICMP_SGT:
506 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
507 BuildMI(MBB, TII.get(X86::SETGr), ResultReg);
508 break;
509 case CmpInst::ICMP_SGE:
510 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
511 BuildMI(MBB, TII.get(X86::SETGEr), ResultReg);
512 break;
513 case CmpInst::ICMP_SLT:
514 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
515 BuildMI(MBB, TII.get(X86::SETLr), ResultReg);
516 break;
517 case CmpInst::ICMP_SLE:
518 BuildMI(MBB, TII.get(Opc)).addReg(Op0Reg).addReg(Op1Reg);
519 BuildMI(MBB, TII.get(X86::SETLEr), ResultReg);
520 break;
521 default:
522 return false;
523 }
524
525 UpdateValueMap(I, ResultReg);
526 return true;
527}
Evan Cheng8b19e562008-09-03 06:44:39 +0000528
Dan Gohmand89ae992008-09-05 01:06:14 +0000529bool X86FastISel::X86SelectZExt(Instruction *I) {
530 // Special-case hack: The only i1 values we know how to produce currently
531 // set the upper bits of an i8 value to zero.
532 if (I->getType() == Type::Int8Ty &&
533 I->getOperand(0)->getType() == Type::Int1Ty) {
534 unsigned ResultReg = getRegForValue(I->getOperand(0));
Dan Gohmanf52550b2008-09-05 01:15:35 +0000535 if (ResultReg == 0) return false;
Dan Gohmand89ae992008-09-05 01:06:14 +0000536 UpdateValueMap(I, ResultReg);
537 return true;
538 }
539
540 return false;
541}
542
543bool X86FastISel::X86SelectBranch(Instruction *I) {
544 BranchInst *BI = cast<BranchInst>(I);
545 // Unconditional branches are selected by tablegen-generated code.
546 unsigned OpReg = getRegForValue(BI->getCondition());
Dan Gohmanf52550b2008-09-05 01:15:35 +0000547 if (OpReg == 0) return false;
Dan Gohmand89ae992008-09-05 01:06:14 +0000548 MachineBasicBlock *TrueMBB = MBBMap[BI->getSuccessor(0)];
549 MachineBasicBlock *FalseMBB = MBBMap[BI->getSuccessor(1)];
550
551 BuildMI(MBB, TII.get(X86::TEST8rr)).addReg(OpReg).addReg(OpReg);
552 BuildMI(MBB, TII.get(X86::JNE)).addMBB(TrueMBB);
553 BuildMI(MBB, TII.get(X86::JMP)).addMBB(FalseMBB);
554
555 MBB->addSuccessor(TrueMBB);
556 MBB->addSuccessor(FalseMBB);
557
558 return true;
559}
560
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000561bool X86FastISel::X86SelectShift(Instruction *I) {
562 unsigned CReg = 0;
563 unsigned Opc = 0;
564 const TargetRegisterClass *RC = NULL;
565 if (I->getType() == Type::Int8Ty) {
566 CReg = X86::CL;
567 RC = &X86::GR8RegClass;
568 switch (I->getOpcode()) {
Dan Gohman31d26912008-09-05 21:13:04 +0000569 case Instruction::LShr: Opc = X86::SHR8rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000570 case Instruction::AShr: Opc = X86::SAR8rCL; break;
Dan Gohman31d26912008-09-05 21:13:04 +0000571 case Instruction::Shl: Opc = X86::SHL8rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000572 default: return false;
573 }
574 } else if (I->getType() == Type::Int16Ty) {
575 CReg = X86::CX;
576 RC = &X86::GR16RegClass;
577 switch (I->getOpcode()) {
Dan Gohman31d26912008-09-05 21:13:04 +0000578 case Instruction::LShr: Opc = X86::SHR16rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000579 case Instruction::AShr: Opc = X86::SAR16rCL; break;
Dan Gohman31d26912008-09-05 21:13:04 +0000580 case Instruction::Shl: Opc = X86::SHL16rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000581 default: return false;
582 }
583 } else if (I->getType() == Type::Int32Ty) {
584 CReg = X86::ECX;
585 RC = &X86::GR32RegClass;
586 switch (I->getOpcode()) {
Dan Gohman31d26912008-09-05 21:13:04 +0000587 case Instruction::LShr: Opc = X86::SHR32rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000588 case Instruction::AShr: Opc = X86::SAR32rCL; break;
Dan Gohman31d26912008-09-05 21:13:04 +0000589 case Instruction::Shl: Opc = X86::SHL32rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000590 default: return false;
591 }
592 } else if (I->getType() == Type::Int64Ty) {
593 CReg = X86::RCX;
594 RC = &X86::GR64RegClass;
595 switch (I->getOpcode()) {
Dan Gohman31d26912008-09-05 21:13:04 +0000596 case Instruction::LShr: Opc = X86::SHR64rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000597 case Instruction::AShr: Opc = X86::SAR64rCL; break;
Dan Gohman31d26912008-09-05 21:13:04 +0000598 case Instruction::Shl: Opc = X86::SHL64rCL; break;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000599 default: return false;
600 }
601 } else {
602 return false;
603 }
604
Dan Gohmanf58cb6d2008-09-05 21:27:34 +0000605 MVT VT = MVT::getMVT(I->getType(), /*HandleUnknown=*/true);
606 if (VT == MVT::Other || !TLI.isTypeLegal(VT))
607 return false;
608
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000609 unsigned Op0Reg = getRegForValue(I->getOperand(0));
610 if (Op0Reg == 0) return false;
611 unsigned Op1Reg = getRegForValue(I->getOperand(1));
612 if (Op1Reg == 0) return false;
613 TII.copyRegToReg(*MBB, MBB->end(), CReg, Op1Reg, RC, RC);
614 unsigned ResultReg = createResultReg(RC);
615 BuildMI(MBB, TII.get(Opc), ResultReg).addReg(Op0Reg);
616 UpdateValueMap(I, ResultReg);
617 return true;
618}
619
620bool X86FastISel::X86SelectSelect(Instruction *I) {
Dan Gohmanf58cb6d2008-09-05 21:27:34 +0000621 const Type *Ty = I->getType();
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000622 if (isa<PointerType>(Ty))
623 Ty = TLI.getTargetData()->getIntPtrType();
624
625 unsigned Opc = 0;
626 const TargetRegisterClass *RC = NULL;
627 if (Ty == Type::Int16Ty) {
Dan Gohman31d26912008-09-05 21:13:04 +0000628 Opc = X86::CMOVE16rr;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000629 RC = &X86::GR16RegClass;
630 } else if (Ty == Type::Int32Ty) {
Dan Gohman31d26912008-09-05 21:13:04 +0000631 Opc = X86::CMOVE32rr;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000632 RC = &X86::GR32RegClass;
633 } else if (Ty == Type::Int64Ty) {
Dan Gohman31d26912008-09-05 21:13:04 +0000634 Opc = X86::CMOVE64rr;
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000635 RC = &X86::GR64RegClass;
636 } else {
637 return false;
638 }
639
Dan Gohmanf58cb6d2008-09-05 21:27:34 +0000640 MVT VT = MVT::getMVT(Ty, /*HandleUnknown=*/true);
641 if (VT == MVT::Other || !TLI.isTypeLegal(VT))
642 return false;
643
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000644 unsigned Op0Reg = getRegForValue(I->getOperand(0));
645 if (Op0Reg == 0) return false;
646 unsigned Op1Reg = getRegForValue(I->getOperand(1));
647 if (Op1Reg == 0) return false;
648 unsigned Op2Reg = getRegForValue(I->getOperand(2));
649 if (Op2Reg == 0) return false;
650
651 BuildMI(MBB, TII.get(X86::TEST8rr)).addReg(Op0Reg).addReg(Op0Reg);
652 unsigned ResultReg = createResultReg(RC);
653 BuildMI(MBB, TII.get(Opc), ResultReg).addReg(Op1Reg).addReg(Op2Reg);
654 UpdateValueMap(I, ResultReg);
655 return true;
656}
657
Evan Cheng10a8d9c2008-09-07 08:47:42 +0000658bool X86FastISel::X86SelectTrunc(Instruction *I) {
659 if (Subtarget->is64Bit())
660 // All other cases should be handled by the tblgen generated code.
661 return false;
662 MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType());
663 MVT DstVT = TLI.getValueType(I->getType());
664 if (DstVT != MVT::i8)
665 // All other cases should be handled by the tblgen generated code.
666 return false;
667 if (SrcVT != MVT::i16 && SrcVT != MVT::i32)
668 // All other cases should be handled by the tblgen generated code.
669 return false;
670
671 unsigned InputReg = getRegForValue(I->getOperand(0));
672 if (!InputReg)
673 // Unhandled operand. Halt "fast" selection and bail.
674 return false;
675
676 // First issue a copy to GR16_ or GR32_.
677 unsigned CopyOpc = (SrcVT == MVT::i16) ? X86::MOV16to16_ : X86::MOV32to32_;
678 const TargetRegisterClass *CopyRC = (SrcVT == MVT::i16)
679 ? X86::GR16_RegisterClass : X86::GR32_RegisterClass;
680 unsigned CopyReg = createResultReg(CopyRC);
681 BuildMI(MBB, TII.get(CopyOpc), CopyReg).addReg(InputReg);
682
683 // Then issue an extract_subreg.
684 unsigned ResultReg = FastEmitInst_extractsubreg(CopyReg,1); // x86_subreg_8bit
685 if (!ResultReg)
686 return false;
687
688 UpdateValueMap(I, ResultReg);
689 return true;
690}
691
Evan Chengf3d4efe2008-09-07 09:09:33 +0000692bool X86FastISel::X86SelectCall(Instruction *I) {
693 CallInst *CI = cast<CallInst>(I);
694 Value *Callee = I->getOperand(0);
695
696 // Can't handle inline asm yet.
697 if (isa<InlineAsm>(Callee))
698 return false;
699
700 // FIXME: Handle some intrinsics.
701 if (Function *F = CI->getCalledFunction()) {
702 if (F->isDeclaration() &&F->getIntrinsicID())
703 return false;
704 }
705
706 // Materialize callee address in a register. FIXME: GV address can be
707 // handled with a CALLpcrel32 instead.
708 unsigned CalleeOp = getRegForValue(Callee);
709 if (CalleeOp == 0) {
710 if (!isa<Constant>(Callee) || !X86SelectConstAddr(Callee, CalleeOp, true))
711 // Unhandled operand. Halt "fast" selection and bail.
712 return false;
713 }
714
715 // Handle only C and fastcc calling conventions for now.
716 CallSite CS(CI);
717 unsigned CC = CS.getCallingConv();
718 if (CC != CallingConv::C &&
719 CC != CallingConv::Fast &&
720 CC != CallingConv::X86_FastCall)
721 return false;
722
723 // Let SDISel handle vararg functions.
724 const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
725 const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
726 if (FTy->isVarArg())
727 return false;
728
729 // Handle *simple* calls for now.
730 const Type *RetTy = CS.getType();
731 MVT RetVT;
Evan Chengdebdea02008-09-08 17:15:42 +0000732 if (!isTypeLegal(RetTy, TLI, RetVT, true))
Evan Chengf3d4efe2008-09-07 09:09:33 +0000733 return false;
734
Evan Chengdebdea02008-09-08 17:15:42 +0000735 // Allow calls which produce i1 results.
736 bool AndToI1 = false;
737 if (RetVT == MVT::i1) {
738 RetVT = MVT::i8;
739 AndToI1 = true;
740 }
741
Evan Chengf3d4efe2008-09-07 09:09:33 +0000742 // Deal with call operands first.
743 SmallVector<unsigned, 4> Args;
744 SmallVector<MVT, 4> ArgVTs;
745 SmallVector<ISD::ArgFlagsTy, 4> ArgFlags;
746 Args.reserve(CS.arg_size());
747 ArgVTs.reserve(CS.arg_size());
748 ArgFlags.reserve(CS.arg_size());
749 for (CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
750 i != e; ++i) {
751 unsigned Arg = getRegForValue(*i);
752 if (Arg == 0)
753 return false;
754 ISD::ArgFlagsTy Flags;
755 unsigned AttrInd = i - CS.arg_begin() + 1;
756 if (CS.paramHasAttr(AttrInd, ParamAttr::SExt))
757 Flags.setSExt();
758 if (CS.paramHasAttr(AttrInd, ParamAttr::ZExt))
759 Flags.setZExt();
760
761 // FIXME: Only handle *easy* calls for now.
762 if (CS.paramHasAttr(AttrInd, ParamAttr::InReg) ||
763 CS.paramHasAttr(AttrInd, ParamAttr::StructRet) ||
764 CS.paramHasAttr(AttrInd, ParamAttr::Nest) ||
765 CS.paramHasAttr(AttrInd, ParamAttr::ByVal))
766 return false;
767
768 const Type *ArgTy = (*i)->getType();
769 MVT ArgVT;
770 if (!isTypeLegal(ArgTy, TLI, ArgVT))
771 return false;
772 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
773 Flags.setOrigAlign(OriginalAlignment);
774
775 Args.push_back(Arg);
776 ArgVTs.push_back(ArgVT);
777 ArgFlags.push_back(Flags);
778 }
779
780 // Analyze operands of the call, assigning locations to each operand.
781 SmallVector<CCValAssign, 16> ArgLocs;
782 CCState CCInfo(CC, false, TM, ArgLocs);
783 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC));
784
785 // Get a count of how many bytes are to be pushed on the stack.
786 unsigned NumBytes = CCInfo.getNextStackOffset();
787
788 // Issue CALLSEQ_START
789 BuildMI(MBB, TII.get(X86::ADJCALLSTACKDOWN)).addImm(NumBytes);
790
791 // Process argumenet: walk the register/memloc assignments, inserting
792 // copies / loads.
793 SmallVector<unsigned, 4> RegArgs;
794 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
795 CCValAssign &VA = ArgLocs[i];
796 unsigned Arg = Args[VA.getValNo()];
797 MVT ArgVT = ArgVTs[VA.getValNo()];
798
799 // Promote the value if needed.
800 switch (VA.getLocInfo()) {
801 default: assert(0 && "Unknown loc info!");
802 case CCValAssign::Full: break;
Evan Cheng24e3a902008-09-08 06:35:17 +0000803 case CCValAssign::SExt: {
804 bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(),
805 Arg, ArgVT, Arg);
806 assert(Emitted && "Failed to emit a sext!");
807 ArgVT = VA.getLocVT();
Evan Chengf3d4efe2008-09-07 09:09:33 +0000808 break;
Evan Cheng24e3a902008-09-08 06:35:17 +0000809 }
810 case CCValAssign::ZExt: {
811 bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(),
812 Arg, ArgVT, Arg);
813 assert(Emitted && "Failed to emit a zext!");
814 ArgVT = VA.getLocVT();
Evan Chengf3d4efe2008-09-07 09:09:33 +0000815 break;
Evan Cheng24e3a902008-09-08 06:35:17 +0000816 }
817 case CCValAssign::AExt: {
818 bool Emitted = X86FastEmitExtend(ISD::ANY_EXTEND, VA.getLocVT(),
819 Arg, ArgVT, Arg);
820 assert(Emitted && "Failed to emit a aext!");
821 ArgVT = VA.getLocVT();
Evan Chengf3d4efe2008-09-07 09:09:33 +0000822 break;
823 }
Evan Cheng24e3a902008-09-08 06:35:17 +0000824 }
Evan Chengf3d4efe2008-09-07 09:09:33 +0000825
826 if (VA.isRegLoc()) {
827 TargetRegisterClass* RC = TLI.getRegClassFor(ArgVT);
828 bool Emitted = TII.copyRegToReg(*MBB, MBB->end(), VA.getLocReg(),
829 Arg, RC, RC);
830 assert(Emitted && "Failed to emit a copy instruction!");
831 RegArgs.push_back(VA.getLocReg());
832 } else {
833 unsigned LocMemOffset = VA.getLocMemOffset();
834 X86FastEmitStore(ArgVT, Arg, StackPtr, LocMemOffset, NULL);
835 }
836 }
837
838 // Issue the call.
839 unsigned CallOpc = CalleeOp
840 ? (Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r)
841 : (Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32);
842 MachineInstrBuilder MIB = CalleeOp
843 ? BuildMI(MBB, TII.get(CallOpc)).addReg(CalleeOp)
844 :BuildMI(MBB, TII.get(CallOpc)).addGlobalAddress(cast<GlobalValue>(Callee));
845 // Add implicit physical register uses to the call.
846 while (!RegArgs.empty()) {
847 MIB.addReg(RegArgs.back());
848 RegArgs.pop_back();
849 }
850
851 // Issue CALLSEQ_END
852 BuildMI(MBB, TII.get(X86::ADJCALLSTACKUP)).addImm(NumBytes).addImm(0);
853
854 // Now handle call return value (if any).
Evan Chengf3d4efe2008-09-07 09:09:33 +0000855 if (RetVT.getSimpleVT() != MVT::isVoid) {
856 SmallVector<CCValAssign, 16> RVLocs;
857 CCState CCInfo(CC, false, TM, RVLocs);
858 CCInfo.AnalyzeCallResult(RetVT, RetCC_X86);
859
860 // Copy all of the result registers out of their specified physreg.
861 assert(RVLocs.size() == 1 && "Can't handle multi-value calls!");
862 MVT CopyVT = RVLocs[0].getValVT();
863 TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
864 TargetRegisterClass *SrcRC = DstRC;
865
866 // If this is a call to a function that returns an fp value on the x87 fp
867 // stack, but where we prefer to use the value in xmm registers, copy it
868 // out as F80 and use a truncate to move it from fp stack reg to xmm reg.
869 if ((RVLocs[0].getLocReg() == X86::ST0 ||
870 RVLocs[0].getLocReg() == X86::ST1) &&
871 isScalarFPTypeInSSEReg(RVLocs[0].getValVT())) {
872 CopyVT = MVT::f80;
873 SrcRC = X86::RSTRegisterClass;
874 DstRC = X86::RFP80RegisterClass;
875 }
876
877 unsigned ResultReg = createResultReg(DstRC);
878 bool Emitted = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
879 RVLocs[0].getLocReg(), DstRC, SrcRC);
880 assert(Emitted && "Failed to emit a copy instruction!");
881 if (CopyVT != RVLocs[0].getValVT()) {
882 // Round the F80 the right size, which also moves to the appropriate xmm
883 // register. This is accomplished by storing the F80 value in memory and
884 // then loading it back. Ewww...
885 MVT ResVT = RVLocs[0].getValVT();
886 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
887 unsigned MemSize = ResVT.getSizeInBits()/8;
888 int FI = MFI->CreateStackObject(MemSize, MemSize);
889 addFrameReference(BuildMI(MBB, TII.get(Opc)), FI).addReg(ResultReg);
890 DstRC = ResVT == MVT::f32
891 ? X86::FR32RegisterClass : X86::FR64RegisterClass;
892 Opc = ResVT == MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm;
893 ResultReg = createResultReg(DstRC);
894 addFrameReference(BuildMI(MBB, TII.get(Opc), ResultReg), FI);
895 }
896
Evan Chengdebdea02008-09-08 17:15:42 +0000897 if (AndToI1) {
898 // Mask out all but lowest bit for some call which produces an i1.
899 unsigned AndResult = createResultReg(X86::GR8RegisterClass);
900 BuildMI(MBB, TII.get(X86::AND8ri), AndResult).addReg(ResultReg).addImm(1);
901 ResultReg = AndResult;
902 }
903
Evan Chengf3d4efe2008-09-07 09:09:33 +0000904 UpdateValueMap(I, ResultReg);
905 }
906
907 return true;
908}
909
910
Dan Gohman99b21822008-08-28 23:21:34 +0000911bool
Dan Gohman3df24e62008-09-03 23:12:08 +0000912X86FastISel::TargetSelectInstruction(Instruction *I) {
Dan Gohman99b21822008-08-28 23:21:34 +0000913 switch (I->getOpcode()) {
914 default: break;
Evan Cheng8b19e562008-09-03 06:44:39 +0000915 case Instruction::Load:
Dan Gohman3df24e62008-09-03 23:12:08 +0000916 return X86SelectLoad(I);
Owen Anderson79924eb2008-09-04 16:48:33 +0000917 case Instruction::Store:
918 return X86SelectStore(I);
Dan Gohman6e3f05f2008-09-04 23:26:51 +0000919 case Instruction::ICmp:
920 case Instruction::FCmp:
921 return X86SelectCmp(I);
Dan Gohmand89ae992008-09-05 01:06:14 +0000922 case Instruction::ZExt:
923 return X86SelectZExt(I);
924 case Instruction::Br:
925 return X86SelectBranch(I);
Evan Chengf3d4efe2008-09-07 09:09:33 +0000926 case Instruction::Call:
927 return X86SelectCall(I);
Dan Gohmanc39f4db2008-09-05 18:30:08 +0000928 case Instruction::LShr:
929 case Instruction::AShr:
930 case Instruction::Shl:
931 return X86SelectShift(I);
932 case Instruction::Select:
933 return X86SelectSelect(I);
Evan Cheng10a8d9c2008-09-07 08:47:42 +0000934 case Instruction::Trunc:
935 return X86SelectTrunc(I);
Dan Gohman99b21822008-08-28 23:21:34 +0000936 }
937
938 return false;
939}
940
Owen Anderson9c7216f2008-09-05 20:49:33 +0000941unsigned X86FastISel::TargetMaterializeConstant(Constant *C,
942 MachineConstantPool* MCP) {
Owen Anderson95267a12008-09-05 00:06:23 +0000943 // Can't handle PIC-mode yet.
944 if (TM.getRelocationModel() == Reloc::PIC_)
945 return 0;
946
Evan Cheng59fbc802008-09-09 01:26:59 +0000947 MVT VT;
948 if (!isTypeLegal(C->getType(), TLI, VT))
Owen Anderson95267a12008-09-05 00:06:23 +0000949 return false;
950
951 // Get opcode and regclass of the output for the given load instruction.
952 unsigned Opc = 0;
953 const TargetRegisterClass *RC = NULL;
954 switch (VT.getSimpleVT()) {
955 default: return false;
956 case MVT::i8:
957 Opc = X86::MOV8rm;
958 RC = X86::GR8RegisterClass;
959 break;
960 case MVT::i16:
961 Opc = X86::MOV16rm;
962 RC = X86::GR16RegisterClass;
963 break;
964 case MVT::i32:
965 Opc = X86::MOV32rm;
966 RC = X86::GR32RegisterClass;
967 break;
968 case MVT::i64:
969 // Must be in x86-64 mode.
970 Opc = X86::MOV64rm;
971 RC = X86::GR64RegisterClass;
972 break;
973 case MVT::f32:
974 if (Subtarget->hasSSE1()) {
975 Opc = X86::MOVSSrm;
976 RC = X86::FR32RegisterClass;
977 } else {
978 Opc = X86::LD_Fp32m;
979 RC = X86::RFP32RegisterClass;
980 }
981 break;
982 case MVT::f64:
983 if (Subtarget->hasSSE2()) {
984 Opc = X86::MOVSDrm;
985 RC = X86::FR64RegisterClass;
986 } else {
987 Opc = X86::LD_Fp64m;
988 RC = X86::RFP64RegisterClass;
989 }
990 break;
991 case MVT::f80:
992 Opc = X86::LD_Fp80m;
993 RC = X86::RFP80RegisterClass;
994 break;
995 }
996
997 unsigned ResultReg = createResultReg(RC);
998 if (isa<GlobalValue>(C)) {
Evan Cheng59fbc802008-09-09 01:26:59 +0000999 if (X86SelectConstAddr(C, ResultReg, false, true))
Owen Anderson95267a12008-09-05 00:06:23 +00001000 return ResultReg;
Evan Cheng0de588f2008-09-05 21:00:03 +00001001 return 0;
Owen Anderson95267a12008-09-05 00:06:23 +00001002 }
1003
Owen Anderson3b217c62008-09-06 01:11:01 +00001004 // MachineConstantPool wants an explicit alignment.
1005 unsigned Align =
1006 TM.getTargetData()->getPreferredTypeAlignmentShift(C->getType());
1007 if (Align == 0) {
1008 // Alignment of vector types. FIXME!
1009 Align = TM.getTargetData()->getABITypeSize(C->getType());
1010 Align = Log2_64(Align);
1011 }
Owen Anderson95267a12008-09-05 00:06:23 +00001012
Owen Anderson3b217c62008-09-06 01:11:01 +00001013 unsigned MCPOffset = MCP->getConstantPoolIndex(C, Align);
Owen Anderson95267a12008-09-05 00:06:23 +00001014 addConstantPoolReference(BuildMI(MBB, TII.get(Opc), ResultReg), MCPOffset);
Owen Anderson95267a12008-09-05 00:06:23 +00001015 return ResultReg;
1016}
1017
Evan Chengc3f44b02008-09-03 00:03:49 +00001018namespace llvm {
Dan Gohman3df24e62008-09-03 23:12:08 +00001019 llvm::FastISel *X86::createFastISel(MachineFunction &mf,
1020 DenseMap<const Value *, unsigned> &vm,
1021 DenseMap<const BasicBlock *, MachineBasicBlock *> &bm) {
1022 return new X86FastISel(mf, vm, bm);
Evan Chengc3f44b02008-09-03 00:03:49 +00001023 }
Dan Gohman99b21822008-08-28 23:21:34 +00001024}