blob: 6a2fb684a850136fd3aa00c09722b02feba3992f [file] [log] [blame]
Chris Lattner76ac0682005-11-15 00:40:23 +00001//===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the interfaces that X86 uses to lower LLVM code into a
11// selection DAG.
12//
13//===----------------------------------------------------------------------===//
14
15#include "X86.h"
16#include "X86ISelLowering.h"
17#include "X86TargetMachine.h"
18#include "llvm/CallingConv.h"
19#include "llvm/Function.h"
Chris Lattner76ac0682005-11-15 00:40:23 +000020#include "llvm/CodeGen/MachineFrameInfo.h"
Evan Cheng339edad2006-01-11 00:33:36 +000021#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner76ac0682005-11-15 00:40:23 +000023#include "llvm/CodeGen/SelectionDAG.h"
24#include "llvm/CodeGen/SSARegMap.h"
25#include "llvm/Target/TargetOptions.h"
26using namespace llvm;
27
28// FIXME: temporary.
29#include "llvm/Support/CommandLine.h"
30static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
31 cl::desc("Enable fastcc on X86"));
32
33X86TargetLowering::X86TargetLowering(TargetMachine &TM)
34 : TargetLowering(TM) {
Chris Lattner76ac0682005-11-15 00:40:23 +000035 // Set up the TargetLowering object.
36
37 // X86 is weird, it always uses i8 for shift amounts and setcc results.
38 setShiftAmountType(MVT::i8);
39 setSetCCResultType(MVT::i8);
40 setSetCCResultContents(ZeroOrOneSetCCResult);
41 setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0
42
43 // Set up the register classes.
Chris Lattner76ac0682005-11-15 00:40:23 +000044 addRegisterClass(MVT::i8, X86::R8RegisterClass);
45 addRegisterClass(MVT::i16, X86::R16RegisterClass);
46 addRegisterClass(MVT::i32, X86::R32RegisterClass);
47
48 // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
49 // operation.
50 setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote);
51 setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote);
52 setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote);
53 setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
54
55 // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
56 // this operation.
57 setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
58 setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
59
60 if (!X86ScalarSSE) {
61 // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
62 // isn't legal.
63 setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
64 setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom);
65 setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
66 setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom);
67 }
68
69 // Handle FP_TO_UINT by promoting the destination to a larger signed
70 // conversion.
71 setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote);
72 setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote);
73 setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote);
74
75 if (!X86ScalarSSE)
76 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
77
78 // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
79 // this operation.
80 setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote);
81 setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote);
82 setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote);
83
Chris Lattner30107e62005-12-23 05:15:23 +000084 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand);
85 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand);
86
Evan Cheng6fc31042005-12-19 23:12:38 +000087 if (X86DAGIsel) {
88 setOperationAction(ISD::BRCOND , MVT::Other, Custom);
89 }
Chris Lattner76ac0682005-11-15 00:40:23 +000090 setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
91 setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand);
92 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
93 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
Chris Lattner32257332005-12-07 17:59:14 +000094 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
Chris Lattner76ac0682005-11-15 00:40:23 +000095 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
96 setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
97 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
98 setOperationAction(ISD::FREM , MVT::f64 , Expand);
99 setOperationAction(ISD::CTPOP , MVT::i8 , Expand);
100 setOperationAction(ISD::CTTZ , MVT::i8 , Expand);
101 setOperationAction(ISD::CTLZ , MVT::i8 , Expand);
102 setOperationAction(ISD::CTPOP , MVT::i16 , Expand);
103 setOperationAction(ISD::CTTZ , MVT::i16 , Expand);
104 setOperationAction(ISD::CTLZ , MVT::i16 , Expand);
105 setOperationAction(ISD::CTPOP , MVT::i32 , Expand);
106 setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
107 setOperationAction(ISD::CTLZ , MVT::i32 , Expand);
Andrew Lenharth0bf68ae2005-11-20 21:41:10 +0000108 setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
Chris Lattner76ac0682005-11-15 00:40:23 +0000109
Evan Cheng6d2ab042006-01-11 23:20:05 +0000110 if (!X86DAGIsel) {
111 setOperationAction(ISD::ROTL , MVT::i8 , Expand);
112 setOperationAction(ISD::ROTR , MVT::i8 , Expand);
113 setOperationAction(ISD::ROTL , MVT::i16 , Expand);
114 setOperationAction(ISD::ROTR , MVT::i16 , Expand);
115 setOperationAction(ISD::ROTL , MVT::i32 , Expand);
116 setOperationAction(ISD::ROTR , MVT::i32 , Expand);
117 }
Nate Begeman1b8121b2006-01-11 21:21:00 +0000118
Chris Lattner76ac0682005-11-15 00:40:23 +0000119 setOperationAction(ISD::READIO , MVT::i1 , Expand);
120 setOperationAction(ISD::READIO , MVT::i8 , Expand);
121 setOperationAction(ISD::READIO , MVT::i16 , Expand);
122 setOperationAction(ISD::READIO , MVT::i32 , Expand);
123 setOperationAction(ISD::WRITEIO , MVT::i1 , Expand);
124 setOperationAction(ISD::WRITEIO , MVT::i8 , Expand);
125 setOperationAction(ISD::WRITEIO , MVT::i16 , Expand);
126 setOperationAction(ISD::WRITEIO , MVT::i32 , Expand);
127
128 // These should be promoted to a larger select which is supported.
129 setOperationAction(ISD::SELECT , MVT::i1 , Promote);
130 setOperationAction(ISD::SELECT , MVT::i8 , Promote);
Evan Cheng225a4d02005-12-17 01:21:05 +0000131 if (X86DAGIsel) {
Evan Cheng172fce72006-01-06 00:43:03 +0000132 // X86 wants to expand cmov itself.
Evan Cheng225a4d02005-12-17 01:21:05 +0000133 setOperationAction(ISD::SELECT , MVT::i16 , Custom);
134 setOperationAction(ISD::SELECT , MVT::i32 , Custom);
Evan Cheng172fce72006-01-06 00:43:03 +0000135 setOperationAction(ISD::SELECT , MVT::f32 , Custom);
136 setOperationAction(ISD::SELECT , MVT::f64 , Custom);
Evan Chengc1583db2005-12-21 20:21:51 +0000137 setOperationAction(ISD::SETCC , MVT::i8 , Custom);
138 setOperationAction(ISD::SETCC , MVT::i16 , Custom);
139 setOperationAction(ISD::SETCC , MVT::i32 , Custom);
Evan Cheng172fce72006-01-06 00:43:03 +0000140 setOperationAction(ISD::SETCC , MVT::f32 , Custom);
141 setOperationAction(ISD::SETCC , MVT::f64 , Custom);
142 // X86 ret instruction may pop stack.
143 setOperationAction(ISD::RET , MVT::Other, Custom);
144 // Darwin ABI issue.
Evan Cheng9cdc16c2005-12-21 23:05:39 +0000145 setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
Evan Cheng9c249c32006-01-09 18:33:28 +0000146 // 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
147 setOperationAction(ISD::ADD_PARTS , MVT::i32 , Custom);
148 setOperationAction(ISD::SUB_PARTS , MVT::i32 , Custom);
149 setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom);
150 setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom);
151 setOperationAction(ISD::SRL_PARTS , MVT::i32 , Custom);
Evan Chengae986f12006-01-11 22:15:48 +0000152 // X86 wants to expand memset / memcpy itself.
153 setOperationAction(ISD::MEMSET , MVT::Other, Custom);
154 setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
Evan Cheng225a4d02005-12-17 01:21:05 +0000155 }
Chris Lattner76ac0682005-11-15 00:40:23 +0000156
Chris Lattner9c415362005-11-29 06:16:21 +0000157 // We don't have line number support yet.
158 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
Jim Laskeydeeafa02006-01-05 01:47:43 +0000159 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
160 setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
Chris Lattner9c415362005-11-29 06:16:21 +0000161
Chris Lattner8e2f52e2006-01-13 02:42:53 +0000162 // Not implemented yet.
163 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
164 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
165
Chris Lattner76ac0682005-11-15 00:40:23 +0000166 if (X86ScalarSSE) {
167 // Set up the FP register classes.
Evan Cheng84dc9b52006-01-12 08:27:59 +0000168 addRegisterClass(MVT::f32, X86::FR32RegisterClass);
169 addRegisterClass(MVT::f64, X86::FR64RegisterClass);
Chris Lattner76ac0682005-11-15 00:40:23 +0000170
171 // SSE has no load+extend ops
172 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
173 setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
174
175 // SSE has no i16 to fp conversion, only i32
176 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
177 setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote);
178
179 // Expand FP_TO_UINT into a select.
180 // FIXME: We would like to use a Custom expander here eventually to do
181 // the optimal thing for SSE vs. the default expansion in the legalizer.
182 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand);
183
184 // We don't support sin/cos/sqrt/fmod
185 setOperationAction(ISD::FSIN , MVT::f64, Expand);
186 setOperationAction(ISD::FCOS , MVT::f64, Expand);
187 setOperationAction(ISD::FABS , MVT::f64, Expand);
188 setOperationAction(ISD::FNEG , MVT::f64, Expand);
189 setOperationAction(ISD::FREM , MVT::f64, Expand);
190 setOperationAction(ISD::FSIN , MVT::f32, Expand);
191 setOperationAction(ISD::FCOS , MVT::f32, Expand);
192 setOperationAction(ISD::FABS , MVT::f32, Expand);
193 setOperationAction(ISD::FNEG , MVT::f32, Expand);
194 setOperationAction(ISD::FREM , MVT::f32, Expand);
195
196 addLegalFPImmediate(+0.0); // xorps / xorpd
197 } else {
198 // Set up the FP register classes.
199 addRegisterClass(MVT::f64, X86::RFPRegisterClass);
200
Evan Cheng6305e502006-01-12 22:54:21 +0000201 if (X86DAGIsel) {
202 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Custom);
203 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
204 }
205
Chris Lattner76ac0682005-11-15 00:40:23 +0000206 if (!UnsafeFPMath) {
207 setOperationAction(ISD::FSIN , MVT::f64 , Expand);
208 setOperationAction(ISD::FCOS , MVT::f64 , Expand);
209 }
210
211 addLegalFPImmediate(+0.0); // FLD0
212 addLegalFPImmediate(+1.0); // FLD1
213 addLegalFPImmediate(-0.0); // FLD0/FCHS
214 addLegalFPImmediate(-1.0); // FLD1/FCHS
215 }
216 computeRegisterProperties();
217
218 maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores
219 maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores
220 maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores
221 allowUnalignedMemoryAccesses = true; // x86 supports it!
222}
223
224std::vector<SDOperand>
225X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
226 if (F.getCallingConv() == CallingConv::Fast && EnableFastCC)
227 return LowerFastCCArguments(F, DAG);
228 return LowerCCCArguments(F, DAG);
229}
230
231std::pair<SDOperand, SDOperand>
232X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
233 bool isVarArg, unsigned CallingConv,
234 bool isTailCall,
235 SDOperand Callee, ArgListTy &Args,
236 SelectionDAG &DAG) {
237 assert((!isVarArg || CallingConv == CallingConv::C) &&
238 "Only C takes varargs!");
Evan Cheng172fce72006-01-06 00:43:03 +0000239
240 // If the callee is a GlobalAddress node (quite common, every direct call is)
241 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
242 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
243 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
Evan Chengbc7a0f442006-01-11 06:09:51 +0000244 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
245 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
Evan Cheng172fce72006-01-06 00:43:03 +0000246
Chris Lattner76ac0682005-11-15 00:40:23 +0000247 if (CallingConv == CallingConv::Fast && EnableFastCC)
248 return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG);
249 return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG);
250}
251
Evan Chenga74ce622005-12-21 02:39:21 +0000252SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
253 SelectionDAG &DAG) {
254 if (!X86DAGIsel)
255 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
256
257 SDOperand Copy;
258 MVT::ValueType OpVT = Op.getValueType();
259 switch (OpVT) {
260 default: assert(0 && "Unknown type to return!");
261 case MVT::i32:
262 Copy = DAG.getCopyToReg(Chain, X86::EAX, Op, SDOperand());
263 break;
264 case MVT::i64: {
265 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
266 DAG.getConstant(1, MVT::i32));
267 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
268 DAG.getConstant(0, MVT::i32));
Evan Cheng172fce72006-01-06 00:43:03 +0000269 Copy = DAG.getCopyToReg(Chain, X86::EDX, Hi, SDOperand());
270 Copy = DAG.getCopyToReg(Copy, X86::EAX, Lo, Copy.getValue(1));
Evan Chenga74ce622005-12-21 02:39:21 +0000271 break;
272 }
273 case MVT::f32:
Evan Chenga74ce622005-12-21 02:39:21 +0000274 case MVT::f64:
275 if (!X86ScalarSSE) {
Evan Cheng9c249c32006-01-09 18:33:28 +0000276 if (OpVT == MVT::f32)
277 Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op);
Evan Chenga74ce622005-12-21 02:39:21 +0000278 std::vector<MVT::ValueType> Tys;
279 Tys.push_back(MVT::Other);
280 Tys.push_back(MVT::Flag);
281 std::vector<SDOperand> Ops;
282 Ops.push_back(Chain);
283 Ops.push_back(Op);
284 Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
285 } else {
286 // Spill the value to memory and reload it into top of stack.
287 unsigned Size = MVT::getSizeInBits(OpVT)/8;
288 MachineFunction &MF = DAG.getMachineFunction();
289 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
290 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
291 Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Op,
292 StackSlot, DAG.getSrcValue(NULL));
293 std::vector<MVT::ValueType> Tys;
294 Tys.push_back(MVT::f64);
295 Tys.push_back(MVT::Other);
296 std::vector<SDOperand> Ops;
297 Ops.push_back(Chain);
298 Ops.push_back(StackSlot);
299 Ops.push_back(DAG.getValueType(OpVT));
300 Copy = DAG.getNode(X86ISD::FLD, Tys, Ops);
301 Tys.clear();
302 Tys.push_back(MVT::Other);
303 Tys.push_back(MVT::Flag);
304 Ops.clear();
305 Ops.push_back(Copy.getValue(1));
306 Ops.push_back(Copy);
307 Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
308 }
309 break;
310 }
Evan Chengc1583db2005-12-21 20:21:51 +0000311
312 return DAG.getNode(X86ISD::RET_FLAG, MVT::Other,
313 Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16),
314 Copy.getValue(1));
Evan Chenga74ce622005-12-21 02:39:21 +0000315}
316
Chris Lattner76ac0682005-11-15 00:40:23 +0000317//===----------------------------------------------------------------------===//
318// C Calling Convention implementation
319//===----------------------------------------------------------------------===//
320
321std::vector<SDOperand>
322X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
323 std::vector<SDOperand> ArgValues;
324
325 MachineFunction &MF = DAG.getMachineFunction();
326 MachineFrameInfo *MFI = MF.getFrameInfo();
327
328 // Add DAG nodes to load the arguments... On entry to a function on the X86,
329 // the stack frame looks like this:
330 //
331 // [ESP] -- return address
332 // [ESP + 4] -- first argument (leftmost lexically)
333 // [ESP + 8] -- second argument, if first argument is four bytes in size
334 // ...
335 //
336 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
337 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
338 MVT::ValueType ObjectVT = getValueType(I->getType());
339 unsigned ArgIncrement = 4;
340 unsigned ObjSize;
341 switch (ObjectVT) {
342 default: assert(0 && "Unhandled argument type!");
343 case MVT::i1:
344 case MVT::i8: ObjSize = 1; break;
345 case MVT::i16: ObjSize = 2; break;
346 case MVT::i32: ObjSize = 4; break;
347 case MVT::i64: ObjSize = ArgIncrement = 8; break;
348 case MVT::f32: ObjSize = 4; break;
349 case MVT::f64: ObjSize = ArgIncrement = 8; break;
350 }
351 // Create the frame index object for this incoming parameter...
352 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
353
354 // Create the SelectionDAG nodes corresponding to a load from this parameter
355 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
356
357 // Don't codegen dead arguments. FIXME: remove this check when we can nuke
358 // dead loads.
359 SDOperand ArgValue;
360 if (!I->use_empty())
361 ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
362 DAG.getSrcValue(NULL));
363 else {
364 if (MVT::isInteger(ObjectVT))
365 ArgValue = DAG.getConstant(0, ObjectVT);
366 else
367 ArgValue = DAG.getConstantFP(0, ObjectVT);
368 }
369 ArgValues.push_back(ArgValue);
370
371 ArgOffset += ArgIncrement; // Move on to the next argument...
372 }
373
374 // If the function takes variable number of arguments, make a frame index for
375 // the start of the first vararg value... for expansion of llvm.va_start.
376 if (F.isVarArg())
377 VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
378 ReturnAddrIndex = 0; // No return address slot generated yet.
379 BytesToPopOnReturn = 0; // Callee pops nothing.
380 BytesCallerReserves = ArgOffset;
381
382 // Finally, inform the code generator which regs we return values in.
383 switch (getValueType(F.getReturnType())) {
384 default: assert(0 && "Unknown type!");
385 case MVT::isVoid: break;
386 case MVT::i1:
387 case MVT::i8:
388 case MVT::i16:
389 case MVT::i32:
390 MF.addLiveOut(X86::EAX);
391 break;
392 case MVT::i64:
393 MF.addLiveOut(X86::EAX);
394 MF.addLiveOut(X86::EDX);
395 break;
396 case MVT::f32:
397 case MVT::f64:
398 MF.addLiveOut(X86::ST0);
399 break;
400 }
401 return ArgValues;
402}
403
404std::pair<SDOperand, SDOperand>
405X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
406 bool isVarArg, bool isTailCall,
407 SDOperand Callee, ArgListTy &Args,
408 SelectionDAG &DAG) {
409 // Count how many bytes are to be pushed on the stack.
410 unsigned NumBytes = 0;
411
412 if (Args.empty()) {
413 // Save zero bytes.
414 Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
415 DAG.getConstant(0, getPointerTy()));
416 } else {
417 for (unsigned i = 0, e = Args.size(); i != e; ++i)
418 switch (getValueType(Args[i].second)) {
419 default: assert(0 && "Unknown value type!");
420 case MVT::i1:
421 case MVT::i8:
422 case MVT::i16:
423 case MVT::i32:
424 case MVT::f32:
425 NumBytes += 4;
426 break;
427 case MVT::i64:
428 case MVT::f64:
429 NumBytes += 8;
430 break;
431 }
432
433 Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
434 DAG.getConstant(NumBytes, getPointerTy()));
435
436 // Arguments go on the stack in reverse order, as specified by the ABI.
437 unsigned ArgOffset = 0;
Evan Chengbc7a0f442006-01-11 06:09:51 +0000438 SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32);
Chris Lattner76ac0682005-11-15 00:40:23 +0000439 std::vector<SDOperand> Stores;
440
441 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
442 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
443 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
444
445 switch (getValueType(Args[i].second)) {
446 default: assert(0 && "Unexpected ValueType for argument!");
447 case MVT::i1:
448 case MVT::i8:
449 case MVT::i16:
450 // Promote the integer to 32 bits. If the input type is signed use a
451 // sign extend, otherwise use a zero extend.
452 if (Args[i].second->isSigned())
453 Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
454 else
455 Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
456
457 // FALL THROUGH
458 case MVT::i32:
459 case MVT::f32:
460 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
461 Args[i].first, PtrOff,
462 DAG.getSrcValue(NULL)));
463 ArgOffset += 4;
464 break;
465 case MVT::i64:
466 case MVT::f64:
467 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
468 Args[i].first, PtrOff,
469 DAG.getSrcValue(NULL)));
470 ArgOffset += 8;
471 break;
472 }
473 }
474 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
475 }
476
477 std::vector<MVT::ValueType> RetVals;
478 MVT::ValueType RetTyVT = getValueType(RetTy);
479 RetVals.push_back(MVT::Other);
480
481 // The result values produced have to be legal. Promote the result.
482 switch (RetTyVT) {
483 case MVT::isVoid: break;
484 default:
485 RetVals.push_back(RetTyVT);
486 break;
487 case MVT::i1:
488 case MVT::i8:
489 case MVT::i16:
490 RetVals.push_back(MVT::i32);
491 break;
492 case MVT::f32:
493 if (X86ScalarSSE)
494 RetVals.push_back(MVT::f32);
495 else
496 RetVals.push_back(MVT::f64);
497 break;
498 case MVT::i64:
499 RetVals.push_back(MVT::i32);
500 RetVals.push_back(MVT::i32);
501 break;
502 }
Chris Lattner76ac0682005-11-15 00:40:23 +0000503
Evan Cheng45e190982006-01-05 00:27:02 +0000504 if (X86DAGIsel) {
505 std::vector<MVT::ValueType> NodeTys;
506 NodeTys.push_back(MVT::Other); // Returns a chain
507 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
Evan Cheng45e190982006-01-05 00:27:02 +0000508 std::vector<SDOperand> Ops;
509 Ops.push_back(Chain);
510 Ops.push_back(Callee);
511
Evan Cheng172fce72006-01-06 00:43:03 +0000512 // FIXME: Do not generate X86ISD::TAILCALL for now.
513 Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops);
Evan Cheng45e190982006-01-05 00:27:02 +0000514 SDOperand InFlag = Chain.getValue(1);
515
516 SDOperand RetVal;
517 if (RetTyVT != MVT::isVoid) {
518 switch (RetTyVT) {
519 default: assert(0 && "Unknown value type to return!");
520 case MVT::i1:
521 case MVT::i8:
522 RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag);
523 Chain = RetVal.getValue(1);
524 break;
525 case MVT::i16:
526 RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag);
527 Chain = RetVal.getValue(1);
528 break;
529 case MVT::i32:
530 RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
531 Chain = RetVal.getValue(1);
532 break;
533 case MVT::i64: {
534 SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
535 SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32,
536 Lo.getValue(2));
537 RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
538 Chain = Hi.getValue(1);
539 break;
540 }
541 case MVT::f32:
542 case MVT::f64: {
543 std::vector<MVT::ValueType> Tys;
544 Tys.push_back(MVT::f64);
545 Tys.push_back(MVT::Other);
546 std::vector<SDOperand> Ops;
547 Ops.push_back(Chain);
548 Ops.push_back(InFlag);
549 RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops);
550 Chain = RetVal.getValue(1);
551 if (X86ScalarSSE) {
552 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
553 MachineFunction &MF = DAG.getMachineFunction();
554 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
555 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
556 Tys.clear();
557 Tys.push_back(MVT::Other);
558 Ops.clear();
559 Ops.push_back(Chain);
560 Ops.push_back(RetVal);
561 Ops.push_back(StackSlot);
562 Ops.push_back(DAG.getValueType(RetTyVT));
563 Chain = DAG.getNode(X86ISD::FST, Tys, Ops);
564 RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot,
565 DAG.getSrcValue(NULL));
566 Chain = RetVal.getValue(1);
567 } else if (RetTyVT == MVT::f32)
568 RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
569 break;
570 }
571 }
572 }
573
574 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
575 DAG.getConstant(NumBytes, getPointerTy()),
576 DAG.getConstant(0, getPointerTy()));
577 return std::make_pair(RetVal, Chain);
578 } else {
579 std::vector<SDOperand> Ops;
580 Ops.push_back(Chain);
581 Ops.push_back(Callee);
582 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
583 Ops.push_back(DAG.getConstant(0, getPointerTy()));
584
585 SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
586 RetVals, Ops);
587
588 SDOperand ResultVal;
589 switch (RetTyVT) {
590 case MVT::isVoid: break;
591 default:
592 ResultVal = TheCall.getValue(1);
593 break;
594 case MVT::i1:
595 case MVT::i8:
596 case MVT::i16:
597 ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
598 break;
599 case MVT::f32:
600 // FIXME: we would really like to remember that this FP_ROUND operation is
601 // okay to eliminate if we allow excess FP precision.
602 ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
603 break;
604 case MVT::i64:
605 ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
606 TheCall.getValue(2));
607 break;
608 }
609
610 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
611 return std::make_pair(ResultVal, Chain);
Chris Lattner76ac0682005-11-15 00:40:23 +0000612 }
Chris Lattner76ac0682005-11-15 00:40:23 +0000613}
614
615SDOperand
616X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
617 Value *VAListV, SelectionDAG &DAG) {
618 // vastart just stores the address of the VarArgsFrameIndex slot.
619 SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
620 return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
621 DAG.getSrcValue(VAListV));
622}
623
624
625std::pair<SDOperand,SDOperand>
626X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP,
627 Value *VAListV, const Type *ArgTy,
628 SelectionDAG &DAG) {
629 MVT::ValueType ArgVT = getValueType(ArgTy);
630 SDOperand Val = DAG.getLoad(MVT::i32, Chain,
631 VAListP, DAG.getSrcValue(VAListV));
632 SDOperand Result = DAG.getLoad(ArgVT, Chain, Val,
633 DAG.getSrcValue(NULL));
634 unsigned Amt;
635 if (ArgVT == MVT::i32)
636 Amt = 4;
637 else {
638 assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
639 "Other types should have been promoted for varargs!");
640 Amt = 8;
641 }
642 Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
643 DAG.getConstant(Amt, Val.getValueType()));
644 Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
645 Val, VAListP, DAG.getSrcValue(VAListV));
646 return std::make_pair(Result, Chain);
647}
648
649//===----------------------------------------------------------------------===//
650// Fast Calling Convention implementation
651//===----------------------------------------------------------------------===//
652//
653// The X86 'fast' calling convention passes up to two integer arguments in
654// registers (an appropriate portion of EAX/EDX), passes arguments in C order,
655// and requires that the callee pop its arguments off the stack (allowing proper
656// tail calls), and has the same return value conventions as C calling convs.
657//
658// This calling convention always arranges for the callee pop value to be 8n+4
659// bytes, which is needed for tail recursion elimination and stack alignment
660// reasons.
661//
662// Note that this can be enhanced in the future to pass fp vals in registers
663// (when we have a global fp allocator) and do other tricks.
664//
665
666/// AddLiveIn - This helper function adds the specified physical register to the
667/// MachineFunction as a live in value. It also creates a corresponding virtual
668/// register for it.
669static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
670 TargetRegisterClass *RC) {
671 assert(RC->contains(PReg) && "Not the correct regclass!");
672 unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
673 MF.addLiveIn(PReg, VReg);
674 return VReg;
675}
676
677
678std::vector<SDOperand>
679X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
680 std::vector<SDOperand> ArgValues;
681
682 MachineFunction &MF = DAG.getMachineFunction();
683 MachineFrameInfo *MFI = MF.getFrameInfo();
684
685 // Add DAG nodes to load the arguments... On entry to a function the stack
686 // frame looks like this:
687 //
688 // [ESP] -- return address
689 // [ESP + 4] -- first nonreg argument (leftmost lexically)
690 // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size
691 // ...
692 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
693
694 // Keep track of the number of integer regs passed so far. This can be either
695 // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
696 // used).
697 unsigned NumIntRegs = 0;
698
699 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
700 MVT::ValueType ObjectVT = getValueType(I->getType());
701 unsigned ArgIncrement = 4;
702 unsigned ObjSize = 0;
703 SDOperand ArgValue;
704
705 switch (ObjectVT) {
706 default: assert(0 && "Unhandled argument type!");
707 case MVT::i1:
708 case MVT::i8:
709 if (NumIntRegs < 2) {
710 if (!I->use_empty()) {
711 unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
712 X86::R8RegisterClass);
713 ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8);
714 DAG.setRoot(ArgValue.getValue(1));
Chris Lattner82584892005-12-27 03:02:18 +0000715 if (ObjectVT == MVT::i1)
716 // FIXME: Should insert a assertzext here.
717 ArgValue = DAG.getNode(ISD::TRUNCATE, MVT::i1, ArgValue);
Chris Lattner76ac0682005-11-15 00:40:23 +0000718 }
719 ++NumIntRegs;
720 break;
721 }
722
723 ObjSize = 1;
724 break;
725 case MVT::i16:
726 if (NumIntRegs < 2) {
727 if (!I->use_empty()) {
728 unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
729 X86::R16RegisterClass);
730 ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16);
731 DAG.setRoot(ArgValue.getValue(1));
732 }
733 ++NumIntRegs;
734 break;
735 }
736 ObjSize = 2;
737 break;
738 case MVT::i32:
739 if (NumIntRegs < 2) {
740 if (!I->use_empty()) {
741 unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX,
742 X86::R32RegisterClass);
743 ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
744 DAG.setRoot(ArgValue.getValue(1));
745 }
746 ++NumIntRegs;
747 break;
748 }
749 ObjSize = 4;
750 break;
751 case MVT::i64:
752 if (NumIntRegs == 0) {
753 if (!I->use_empty()) {
754 unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
755 unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
756
757 SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
758 SDOperand Hi = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32);
759 DAG.setRoot(Hi.getValue(1));
760
761 ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
762 }
763 NumIntRegs = 2;
764 break;
765 } else if (NumIntRegs == 1) {
766 if (!I->use_empty()) {
767 unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
768 SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
769 DAG.setRoot(Low.getValue(1));
770
771 // Load the high part from memory.
772 // Create the frame index object for this incoming parameter...
773 int FI = MFI->CreateFixedObject(4, ArgOffset);
774 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
775 SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
776 DAG.getSrcValue(NULL));
777 ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
778 }
779 ArgOffset += 4;
780 NumIntRegs = 2;
781 break;
782 }
783 ObjSize = ArgIncrement = 8;
784 break;
785 case MVT::f32: ObjSize = 4; break;
786 case MVT::f64: ObjSize = ArgIncrement = 8; break;
787 }
788
789 // Don't codegen dead arguments. FIXME: remove this check when we can nuke
790 // dead loads.
791 if (ObjSize && !I->use_empty()) {
792 // Create the frame index object for this incoming parameter...
793 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
794
795 // Create the SelectionDAG nodes corresponding to a load from this
796 // parameter.
797 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
798
799 ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
800 DAG.getSrcValue(NULL));
801 } else if (ArgValue.Val == 0) {
802 if (MVT::isInteger(ObjectVT))
803 ArgValue = DAG.getConstant(0, ObjectVT);
804 else
805 ArgValue = DAG.getConstantFP(0, ObjectVT);
806 }
807 ArgValues.push_back(ArgValue);
808
809 if (ObjSize)
810 ArgOffset += ArgIncrement; // Move on to the next argument.
811 }
812
813 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
814 // arguments and the arguments after the retaddr has been pushed are aligned.
815 if ((ArgOffset & 7) == 0)
816 ArgOffset += 4;
817
818 VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs.
819 ReturnAddrIndex = 0; // No return address slot generated yet.
820 BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments.
821 BytesCallerReserves = 0;
822
823 // Finally, inform the code generator which regs we return values in.
824 switch (getValueType(F.getReturnType())) {
825 default: assert(0 && "Unknown type!");
826 case MVT::isVoid: break;
827 case MVT::i1:
828 case MVT::i8:
829 case MVT::i16:
830 case MVT::i32:
831 MF.addLiveOut(X86::EAX);
832 break;
833 case MVT::i64:
834 MF.addLiveOut(X86::EAX);
835 MF.addLiveOut(X86::EDX);
836 break;
837 case MVT::f32:
838 case MVT::f64:
839 MF.addLiveOut(X86::ST0);
840 break;
841 }
842 return ArgValues;
843}
844
845std::pair<SDOperand, SDOperand>
846X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
847 bool isTailCall, SDOperand Callee,
848 ArgListTy &Args, SelectionDAG &DAG) {
849 // Count how many bytes are to be pushed on the stack.
850 unsigned NumBytes = 0;
851
852 // Keep track of the number of integer regs passed so far. This can be either
853 // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
854 // used).
855 unsigned NumIntRegs = 0;
856
857 for (unsigned i = 0, e = Args.size(); i != e; ++i)
858 switch (getValueType(Args[i].second)) {
859 default: assert(0 && "Unknown value type!");
860 case MVT::i1:
861 case MVT::i8:
862 case MVT::i16:
863 case MVT::i32:
864 if (NumIntRegs < 2) {
865 ++NumIntRegs;
866 break;
867 }
868 // fall through
869 case MVT::f32:
870 NumBytes += 4;
871 break;
872 case MVT::i64:
873 if (NumIntRegs == 0) {
874 NumIntRegs = 2;
875 break;
876 } else if (NumIntRegs == 1) {
877 NumIntRegs = 2;
878 NumBytes += 4;
879 break;
880 }
881
882 // fall through
883 case MVT::f64:
884 NumBytes += 8;
885 break;
886 }
887
888 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
889 // arguments and the arguments after the retaddr has been pushed are aligned.
890 if ((NumBytes & 7) == 0)
891 NumBytes += 4;
892
893 Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
894 DAG.getConstant(NumBytes, getPointerTy()));
895
896 // Arguments go on the stack in reverse order, as specified by the ABI.
897 unsigned ArgOffset = 0;
898 SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
899 X86::ESP, MVT::i32);
900 NumIntRegs = 0;
901 std::vector<SDOperand> Stores;
902 std::vector<SDOperand> RegValuesToPass;
903 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
904 switch (getValueType(Args[i].second)) {
905 default: assert(0 && "Unexpected ValueType for argument!");
906 case MVT::i1:
Chris Lattner82584892005-12-27 03:02:18 +0000907 Args[i].first = DAG.getNode(ISD::ANY_EXTEND, MVT::i8, Args[i].first);
908 // Fall through.
Chris Lattner76ac0682005-11-15 00:40:23 +0000909 case MVT::i8:
910 case MVT::i16:
911 case MVT::i32:
912 if (NumIntRegs < 2) {
913 RegValuesToPass.push_back(Args[i].first);
914 ++NumIntRegs;
915 break;
916 }
917 // Fall through
918 case MVT::f32: {
919 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
920 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
921 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
922 Args[i].first, PtrOff,
923 DAG.getSrcValue(NULL)));
924 ArgOffset += 4;
925 break;
926 }
927 case MVT::i64:
928 if (NumIntRegs < 2) { // Can pass part of it in regs?
929 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
930 Args[i].first, DAG.getConstant(1, MVT::i32));
931 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
932 Args[i].first, DAG.getConstant(0, MVT::i32));
933 RegValuesToPass.push_back(Lo);
934 ++NumIntRegs;
935 if (NumIntRegs < 2) { // Pass both parts in regs?
936 RegValuesToPass.push_back(Hi);
937 ++NumIntRegs;
938 } else {
939 // Pass the high part in memory.
940 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
941 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
942 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
943 Hi, PtrOff, DAG.getSrcValue(NULL)));
944 ArgOffset += 4;
945 }
946 break;
947 }
948 // Fall through
949 case MVT::f64:
950 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
951 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
952 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
953 Args[i].first, PtrOff,
954 DAG.getSrcValue(NULL)));
955 ArgOffset += 8;
956 break;
957 }
958 }
959 if (!Stores.empty())
960 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
961
962 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
963 // arguments and the arguments after the retaddr has been pushed are aligned.
964 if ((ArgOffset & 7) == 0)
965 ArgOffset += 4;
966
967 std::vector<MVT::ValueType> RetVals;
968 MVT::ValueType RetTyVT = getValueType(RetTy);
969
970 RetVals.push_back(MVT::Other);
971
972 // The result values produced have to be legal. Promote the result.
973 switch (RetTyVT) {
974 case MVT::isVoid: break;
975 default:
976 RetVals.push_back(RetTyVT);
977 break;
978 case MVT::i1:
979 case MVT::i8:
980 case MVT::i16:
981 RetVals.push_back(MVT::i32);
982 break;
983 case MVT::f32:
984 if (X86ScalarSSE)
985 RetVals.push_back(MVT::f32);
986 else
987 RetVals.push_back(MVT::f64);
988 break;
989 case MVT::i64:
990 RetVals.push_back(MVT::i32);
991 RetVals.push_back(MVT::i32);
992 break;
993 }
994
Evan Cheng172fce72006-01-06 00:43:03 +0000995 if (X86DAGIsel) {
996 // Build a sequence of copy-to-reg nodes chained together with token chain
997 // and flag operands which copy the outgoing args into registers.
998 SDOperand InFlag;
999 for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
1000 unsigned CCReg;
1001 SDOperand RegToPass = RegValuesToPass[i];
1002 switch (RegToPass.getValueType()) {
1003 default: assert(0 && "Bad thing to pass in regs");
1004 case MVT::i8:
1005 CCReg = (i == 0) ? X86::AL : X86::DL;
1006 break;
1007 case MVT::i16:
1008 CCReg = (i == 0) ? X86::AX : X86::DX;
1009 break;
1010 case MVT::i32:
1011 CCReg = (i == 0) ? X86::EAX : X86::EDX;
1012 break;
1013 }
Chris Lattner76ac0682005-11-15 00:40:23 +00001014
Evan Cheng172fce72006-01-06 00:43:03 +00001015 Chain = DAG.getCopyToReg(Chain, CCReg, RegToPass, InFlag);
1016 InFlag = Chain.getValue(1);
1017 }
Chris Lattner76ac0682005-11-15 00:40:23 +00001018
Evan Cheng172fce72006-01-06 00:43:03 +00001019 std::vector<MVT::ValueType> NodeTys;
1020 NodeTys.push_back(MVT::Other); // Returns a chain
1021 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
Evan Cheng172fce72006-01-06 00:43:03 +00001022 std::vector<SDOperand> Ops;
1023 Ops.push_back(Chain);
1024 Ops.push_back(Callee);
1025 if (InFlag.Val)
1026 Ops.push_back(InFlag);
1027
1028 // FIXME: Do not generate X86ISD::TAILCALL for now.
1029 Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops);
1030 InFlag = Chain.getValue(1);
1031
1032 SDOperand RetVal;
1033 if (RetTyVT != MVT::isVoid) {
1034 switch (RetTyVT) {
1035 default: assert(0 && "Unknown value type to return!");
1036 case MVT::i1:
1037 case MVT::i8:
1038 RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag);
1039 Chain = RetVal.getValue(1);
1040 break;
1041 case MVT::i16:
1042 RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag);
1043 Chain = RetVal.getValue(1);
1044 break;
1045 case MVT::i32:
1046 RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
1047 Chain = RetVal.getValue(1);
1048 break;
1049 case MVT::i64: {
1050 SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
1051 SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32,
1052 Lo.getValue(2));
1053 RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
1054 Chain = Hi.getValue(1);
1055 break;
1056 }
1057 case MVT::f32:
1058 case MVT::f64: {
1059 std::vector<MVT::ValueType> Tys;
1060 Tys.push_back(MVT::f64);
1061 Tys.push_back(MVT::Other);
1062 std::vector<SDOperand> Ops;
1063 Ops.push_back(Chain);
1064 Ops.push_back(InFlag);
1065 RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops);
1066 Chain = RetVal.getValue(1);
1067 if (X86ScalarSSE) {
1068 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1069 MachineFunction &MF = DAG.getMachineFunction();
1070 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
1071 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
1072 Tys.clear();
1073 Tys.push_back(MVT::Other);
1074 Ops.clear();
1075 Ops.push_back(Chain);
1076 Ops.push_back(RetVal);
1077 Ops.push_back(StackSlot);
1078 Ops.push_back(DAG.getValueType(RetTyVT));
1079 Chain = DAG.getNode(X86ISD::FST, Tys, Ops);
1080 RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot,
1081 DAG.getSrcValue(NULL));
1082 Chain = RetVal.getValue(1);
1083 } else if (RetTyVT == MVT::f32)
1084 RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
1085 break;
1086 }
1087 }
1088 }
1089
1090 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
1091 DAG.getConstant(ArgOffset, getPointerTy()),
1092 DAG.getConstant(ArgOffset, getPointerTy()));
1093 return std::make_pair(RetVal, Chain);
1094 } else {
1095 std::vector<SDOperand> Ops;
1096 Ops.push_back(Chain);
1097 Ops.push_back(Callee);
1098 Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
1099 // Callee pops all arg values on the stack.
1100 Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
1101
1102 // Pass register arguments as needed.
1103 Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end());
1104
1105 SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
1106 RetVals, Ops);
1107 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
1108
1109 SDOperand ResultVal;
1110 switch (RetTyVT) {
1111 case MVT::isVoid: break;
1112 default:
1113 ResultVal = TheCall.getValue(1);
1114 break;
1115 case MVT::i1:
1116 case MVT::i8:
1117 case MVT::i16:
1118 ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
1119 break;
1120 case MVT::f32:
1121 // FIXME: we would really like to remember that this FP_ROUND operation is
1122 // okay to eliminate if we allow excess FP precision.
1123 ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
1124 break;
1125 case MVT::i64:
1126 ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
1127 TheCall.getValue(2));
1128 break;
1129 }
1130
1131 return std::make_pair(ResultVal, Chain);
Chris Lattner76ac0682005-11-15 00:40:23 +00001132 }
Chris Lattner76ac0682005-11-15 00:40:23 +00001133}
1134
1135SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
1136 if (ReturnAddrIndex == 0) {
1137 // Set up a frame object for the return address.
1138 MachineFunction &MF = DAG.getMachineFunction();
1139 ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4);
1140 }
1141
1142 return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32);
1143}
1144
1145
1146
1147std::pair<SDOperand, SDOperand> X86TargetLowering::
1148LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
1149 SelectionDAG &DAG) {
1150 SDOperand Result;
1151 if (Depth) // Depths > 0 not supported yet!
1152 Result = DAG.getConstant(0, getPointerTy());
1153 else {
1154 SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
1155 if (!isFrameAddress)
1156 // Just load the return address
1157 Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI,
1158 DAG.getSrcValue(NULL));
1159 else
1160 Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI,
1161 DAG.getConstant(4, MVT::i32));
1162 }
1163 return std::make_pair(Result, Chain);
1164}
1165
Evan Cheng339edad2006-01-11 00:33:36 +00001166/// getCondBrOpcodeForX86CC - Returns the X86 conditional branch opcode
1167/// which corresponds to the condition code.
1168static unsigned getCondBrOpcodeForX86CC(unsigned X86CC) {
1169 switch (X86CC) {
1170 default: assert(0 && "Unknown X86 conditional code!");
1171 case X86ISD::COND_A: return X86::JA;
1172 case X86ISD::COND_AE: return X86::JAE;
1173 case X86ISD::COND_B: return X86::JB;
1174 case X86ISD::COND_BE: return X86::JBE;
1175 case X86ISD::COND_E: return X86::JE;
1176 case X86ISD::COND_G: return X86::JG;
1177 case X86ISD::COND_GE: return X86::JGE;
1178 case X86ISD::COND_L: return X86::JL;
1179 case X86ISD::COND_LE: return X86::JLE;
1180 case X86ISD::COND_NE: return X86::JNE;
1181 case X86ISD::COND_NO: return X86::JNO;
1182 case X86ISD::COND_NP: return X86::JNP;
1183 case X86ISD::COND_NS: return X86::JNS;
1184 case X86ISD::COND_O: return X86::JO;
1185 case X86ISD::COND_P: return X86::JP;
1186 case X86ISD::COND_S: return X86::JS;
1187 }
1188}
Chris Lattner76ac0682005-11-15 00:40:23 +00001189
Evan Cheng339edad2006-01-11 00:33:36 +00001190/// getX86CC - do a one to one translation of a ISD::CondCode to the X86
1191/// specific condition code. It returns a X86ISD::COND_INVALID if it cannot
Evan Cheng172fce72006-01-06 00:43:03 +00001192/// do a direct translation.
Evan Cheng339edad2006-01-11 00:33:36 +00001193static unsigned getX86CC(SDOperand CC, bool isFP) {
Evan Cheng172fce72006-01-06 00:43:03 +00001194 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
1195 unsigned X86CC = X86ISD::COND_INVALID;
1196 if (!isFP) {
1197 switch (SetCCOpcode) {
1198 default: break;
1199 case ISD::SETEQ: X86CC = X86ISD::COND_E; break;
1200 case ISD::SETGT: X86CC = X86ISD::COND_G; break;
1201 case ISD::SETGE: X86CC = X86ISD::COND_GE; break;
1202 case ISD::SETLT: X86CC = X86ISD::COND_L; break;
1203 case ISD::SETLE: X86CC = X86ISD::COND_LE; break;
1204 case ISD::SETNE: X86CC = X86ISD::COND_NE; break;
1205 case ISD::SETULT: X86CC = X86ISD::COND_B; break;
1206 case ISD::SETUGT: X86CC = X86ISD::COND_A; break;
1207 case ISD::SETULE: X86CC = X86ISD::COND_BE; break;
1208 case ISD::SETUGE: X86CC = X86ISD::COND_AE; break;
1209 }
1210 } else {
1211 // On a floating point condition, the flags are set as follows:
1212 // ZF PF CF op
1213 // 0 | 0 | 0 | X > Y
1214 // 0 | 0 | 1 | X < Y
1215 // 1 | 0 | 0 | X == Y
1216 // 1 | 1 | 1 | unordered
1217 switch (SetCCOpcode) {
1218 default: break;
1219 case ISD::SETUEQ:
1220 case ISD::SETEQ: X86CC = X86ISD::COND_E; break;
1221 case ISD::SETOGT:
1222 case ISD::SETGT: X86CC = X86ISD::COND_A; break;
1223 case ISD::SETOGE:
1224 case ISD::SETGE: X86CC = X86ISD::COND_AE; break;
1225 case ISD::SETULT:
1226 case ISD::SETLT: X86CC = X86ISD::COND_B; break;
1227 case ISD::SETULE:
1228 case ISD::SETLE: X86CC = X86ISD::COND_BE; break;
1229 case ISD::SETONE:
1230 case ISD::SETNE: X86CC = X86ISD::COND_NE; break;
1231 case ISD::SETUO: X86CC = X86ISD::COND_P; break;
1232 case ISD::SETO: X86CC = X86ISD::COND_NP; break;
1233 }
1234 }
1235 return X86CC;
1236}
1237
Evan Cheng339edad2006-01-11 00:33:36 +00001238/// hasFPCMov - is there a floating point cmov for the specific X86 condition
1239/// code. Current x86 isa includes the following FP cmov instructions:
Evan Cheng73a1ad92006-01-10 20:26:56 +00001240/// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu.
Evan Cheng339edad2006-01-11 00:33:36 +00001241static bool hasFPCMov(unsigned X86CC) {
Evan Cheng73a1ad92006-01-10 20:26:56 +00001242 switch (X86CC) {
1243 default:
1244 return false;
1245 case X86ISD::COND_B:
1246 case X86ISD::COND_BE:
1247 case X86ISD::COND_E:
1248 case X86ISD::COND_P:
1249 case X86ISD::COND_A:
1250 case X86ISD::COND_AE:
1251 case X86ISD::COND_NE:
1252 case X86ISD::COND_NP:
1253 return true;
1254 }
1255}
1256
Evan Cheng339edad2006-01-11 00:33:36 +00001257MachineBasicBlock *
1258X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
1259 MachineBasicBlock *BB) {
1260 assert((MI->getOpcode() == X86::CMOV_FR32 ||
1261 MI->getOpcode() == X86::CMOV_FR64) &&
1262 "Unexpected instr type to insert");
1263
1264 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1265 // control-flow pattern. The incoming instruction knows the destination vreg
1266 // to set, the condition code register to branch on, the true/false values to
1267 // select between, and a branch opcode to use.
1268 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1269 ilist<MachineBasicBlock>::iterator It = BB;
1270 ++It;
1271
1272 // thisMBB:
1273 // ...
1274 // TrueVal = ...
1275 // cmpTY ccX, r1, r2
1276 // bCC copy1MBB
1277 // fallthrough --> copy0MBB
1278 MachineBasicBlock *thisMBB = BB;
1279 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
1280 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
1281 unsigned Opc = getCondBrOpcodeForX86CC(MI->getOperand(3).getImmedValue());
1282 BuildMI(BB, Opc, 1).addMBB(sinkMBB);
1283 MachineFunction *F = BB->getParent();
1284 F->getBasicBlockList().insert(It, copy0MBB);
1285 F->getBasicBlockList().insert(It, sinkMBB);
1286 // Update machine-CFG edges
1287 BB->addSuccessor(copy0MBB);
1288 BB->addSuccessor(sinkMBB);
1289
1290 // copy0MBB:
1291 // %FalseValue = ...
1292 // # fallthrough to sinkMBB
1293 BB = copy0MBB;
1294
1295 // Update machine-CFG edges
1296 BB->addSuccessor(sinkMBB);
1297
1298 // sinkMBB:
1299 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1300 // ...
1301 BB = sinkMBB;
1302 BuildMI(BB, X86::PHI, 4, MI->getOperand(0).getReg())
1303 .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB)
1304 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
1305
1306 delete MI; // The pseudo instruction is gone now.
1307 return BB;
1308}
1309
1310
1311//===----------------------------------------------------------------------===//
1312// X86 Custom Lowering Hooks
1313//===----------------------------------------------------------------------===//
1314
Chris Lattner76ac0682005-11-15 00:40:23 +00001315/// LowerOperation - Provide custom lowering hooks for some operations.
1316///
1317SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
1318 switch (Op.getOpcode()) {
1319 default: assert(0 && "Should not custom lower this!");
Evan Cheng9c249c32006-01-09 18:33:28 +00001320 case ISD::ADD_PARTS:
1321 case ISD::SUB_PARTS: {
1322 assert(Op.getNumOperands() == 4 && Op.getValueType() == MVT::i32 &&
1323 "Not an i64 add/sub!");
1324 bool isAdd = Op.getOpcode() == ISD::ADD_PARTS;
1325 std::vector<MVT::ValueType> Tys;
1326 Tys.push_back(MVT::i32);
1327 Tys.push_back(MVT::Flag);
1328 std::vector<SDOperand> Ops;
1329 Ops.push_back(Op.getOperand(0));
1330 Ops.push_back(Op.getOperand(2));
1331 SDOperand Lo = DAG.getNode(isAdd ? X86ISD::ADD_FLAG : X86ISD::SUB_FLAG,
1332 Tys, Ops);
1333 SDOperand Hi = DAG.getNode(isAdd ? X86ISD::ADC : X86ISD::SBB, MVT::i32,
1334 Op.getOperand(1), Op.getOperand(3),
1335 Lo.getValue(1));
1336 Tys.clear();
1337 Tys.push_back(MVT::i32);
1338 Tys.push_back(MVT::i32);
1339 Ops.clear();
1340 Ops.push_back(Lo);
1341 Ops.push_back(Hi);
1342 return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
1343 }
1344 case ISD::SHL_PARTS:
1345 case ISD::SRA_PARTS:
1346 case ISD::SRL_PARTS: {
1347 assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
1348 "Not an i64 shift!");
1349 bool isSRA = Op.getOpcode() == ISD::SRA_PARTS;
1350 SDOperand ShOpLo = Op.getOperand(0);
1351 SDOperand ShOpHi = Op.getOperand(1);
1352 SDOperand ShAmt = Op.getOperand(2);
1353 SDOperand Tmp1 = isSRA ? DAG.getNode(ISD::SRA, MVT::i32, ShOpHi,
Evan Cheng12181af2006-01-09 22:29:54 +00001354 DAG.getConstant(31, MVT::i32))
Evan Cheng9c249c32006-01-09 18:33:28 +00001355 : DAG.getConstant(0, MVT::i32);
1356
1357 SDOperand Tmp2, Tmp3;
1358 if (Op.getOpcode() == ISD::SHL_PARTS) {
1359 Tmp2 = DAG.getNode(X86ISD::SHLD, MVT::i32, ShOpHi, ShOpLo, ShAmt);
1360 Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, ShOpLo, ShAmt);
1361 } else {
1362 Tmp2 = DAG.getNode(X86ISD::SHRD, MVT::i32, ShOpLo, ShOpHi, ShAmt);
1363 Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SHL, MVT::i32, ShOpHi, ShAmt);
1364 }
1365
1366 SDOperand InFlag = DAG.getNode(X86ISD::TEST, MVT::Flag,
1367 ShAmt, DAG.getConstant(32, MVT::i8));
1368
1369 SDOperand Hi, Lo;
Evan Cheng77fa9192006-01-09 20:49:21 +00001370 SDOperand CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8);
Evan Cheng9c249c32006-01-09 18:33:28 +00001371
1372 std::vector<MVT::ValueType> Tys;
1373 Tys.push_back(MVT::i32);
1374 Tys.push_back(MVT::Flag);
1375 std::vector<SDOperand> Ops;
1376 if (Op.getOpcode() == ISD::SHL_PARTS) {
1377 Ops.push_back(Tmp2);
1378 Ops.push_back(Tmp3);
1379 Ops.push_back(CC);
1380 Ops.push_back(InFlag);
1381 Hi = DAG.getNode(X86ISD::CMOV, Tys, Ops);
1382 InFlag = Hi.getValue(1);
1383
1384 Ops.clear();
1385 Ops.push_back(Tmp3);
1386 Ops.push_back(Tmp1);
1387 Ops.push_back(CC);
1388 Ops.push_back(InFlag);
1389 Lo = DAG.getNode(X86ISD::CMOV, Tys, Ops);
1390 } else {
1391 Ops.push_back(Tmp2);
1392 Ops.push_back(Tmp3);
1393 Ops.push_back(CC);
Evan Cheng12181af2006-01-09 22:29:54 +00001394 Ops.push_back(InFlag);
Evan Cheng9c249c32006-01-09 18:33:28 +00001395 Lo = DAG.getNode(X86ISD::CMOV, Tys, Ops);
1396 InFlag = Lo.getValue(1);
1397
1398 Ops.clear();
1399 Ops.push_back(Tmp3);
1400 Ops.push_back(Tmp1);
1401 Ops.push_back(CC);
1402 Ops.push_back(InFlag);
1403 Hi = DAG.getNode(X86ISD::CMOV, Tys, Ops);
1404 }
1405
1406 Tys.clear();
1407 Tys.push_back(MVT::i32);
1408 Tys.push_back(MVT::i32);
1409 Ops.clear();
1410 Ops.push_back(Lo);
1411 Ops.push_back(Hi);
1412 return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
1413 }
Chris Lattner76ac0682005-11-15 00:40:23 +00001414 case ISD::SINT_TO_FP: {
1415 assert(Op.getValueType() == MVT::f64 &&
Evan Cheng6305e502006-01-12 22:54:21 +00001416 Op.getOperand(0).getValueType() <= MVT::i64 &&
1417 Op.getOperand(0).getValueType() >= MVT::i16 &&
Chris Lattner76ac0682005-11-15 00:40:23 +00001418 "Unknown SINT_TO_FP to lower!");
Evan Cheng6305e502006-01-12 22:54:21 +00001419
1420 SDOperand Result;
1421 MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
1422 unsigned Size = MVT::getSizeInBits(SrcVT)/8;
Chris Lattner76ac0682005-11-15 00:40:23 +00001423 MachineFunction &MF = DAG.getMachineFunction();
Evan Cheng6305e502006-01-12 22:54:21 +00001424 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
Chris Lattner76ac0682005-11-15 00:40:23 +00001425 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
Evan Cheng6305e502006-01-12 22:54:21 +00001426 SDOperand Chain = DAG.getNode(ISD::STORE, MVT::Other,
1427 DAG.getEntryNode(), Op.getOperand(0),
1428 StackSlot, DAG.getSrcValue(NULL));
1429
1430 // Build the FILD
1431 std::vector<MVT::ValueType> Tys;
1432 Tys.push_back(MVT::f64);
1433 Tys.push_back(MVT::Flag);
Chris Lattner76ac0682005-11-15 00:40:23 +00001434 std::vector<SDOperand> Ops;
Evan Cheng6305e502006-01-12 22:54:21 +00001435 Ops.push_back(Chain);
Chris Lattner76ac0682005-11-15 00:40:23 +00001436 Ops.push_back(StackSlot);
Evan Cheng6305e502006-01-12 22:54:21 +00001437 Ops.push_back(DAG.getValueType(SrcVT));
1438 Result = DAG.getNode(X86ISD::FILD, Tys, Ops);
1439 return Result;
Chris Lattner76ac0682005-11-15 00:40:23 +00001440 }
1441 case ISD::FP_TO_SINT: {
1442 assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
1443 Op.getOperand(0).getValueType() == MVT::f64 &&
1444 "Unknown FP_TO_SINT to lower!");
1445 // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
1446 // stack slot.
1447 MachineFunction &MF = DAG.getMachineFunction();
1448 unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
1449 int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
1450 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
1451
1452 unsigned Opc;
1453 switch (Op.getValueType()) {
1454 default: assert(0 && "Invalid FP_TO_SINT to lower!");
1455 case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
1456 case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
1457 case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
1458 }
1459
1460 // Build the FP_TO_INT*_IN_MEM
1461 std::vector<SDOperand> Ops;
1462 Ops.push_back(DAG.getEntryNode());
1463 Ops.push_back(Op.getOperand(0));
1464 Ops.push_back(StackSlot);
1465 SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
1466
1467 // Load the result.
1468 return DAG.getLoad(Op.getValueType(), FIST, StackSlot,
1469 DAG.getSrcValue(NULL));
1470 }
Andrew Lenharth0bf68ae2005-11-20 21:41:10 +00001471 case ISD::READCYCLECOUNTER: {
Chris Lattner6df9e112005-11-20 22:01:40 +00001472 std::vector<MVT::ValueType> Tys;
1473 Tys.push_back(MVT::Other);
1474 Tys.push_back(MVT::Flag);
1475 std::vector<SDOperand> Ops;
1476 Ops.push_back(Op.getOperand(0));
1477 SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, Ops);
Chris Lattner6c1ca882005-11-20 22:57:19 +00001478 Ops.clear();
1479 Ops.push_back(DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)));
1480 Ops.push_back(DAG.getCopyFromReg(Ops[0].getValue(1), X86::EDX,
1481 MVT::i32, Ops[0].getValue(2)));
1482 Ops.push_back(Ops[1].getValue(1));
1483 Tys[0] = Tys[1] = MVT::i32;
1484 Tys.push_back(MVT::Other);
1485 return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
Andrew Lenharth0bf68ae2005-11-20 21:41:10 +00001486 }
Evan Chengc1583db2005-12-21 20:21:51 +00001487 case ISD::SETCC: {
1488 assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
1489 SDOperand CC = Op.getOperand(2);
1490 SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
1491 Op.getOperand(0), Op.getOperand(1));
Evan Cheng172fce72006-01-06 00:43:03 +00001492 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
1493 bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType());
Evan Cheng339edad2006-01-11 00:33:36 +00001494 unsigned X86CC = getX86CC(CC, isFP);
Evan Cheng172fce72006-01-06 00:43:03 +00001495 if (X86CC != X86ISD::COND_INVALID) {
1496 return DAG.getNode(X86ISD::SETCC, MVT::i8,
1497 DAG.getConstant(X86CC, MVT::i8), Cond);
1498 } else {
1499 assert(isFP && "Illegal integer SetCC!");
1500
1501 std::vector<MVT::ValueType> Tys;
1502 std::vector<SDOperand> Ops;
1503 switch (SetCCOpcode) {
1504 default: assert(false && "Illegal floating point SetCC!");
1505 case ISD::SETOEQ: { // !PF & ZF
1506 Tys.push_back(MVT::i8);
1507 Tys.push_back(MVT::Flag);
1508 Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8));
1509 Ops.push_back(Cond);
1510 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1511 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1512 DAG.getConstant(X86ISD::COND_E, MVT::i8),
1513 Tmp1.getValue(1));
1514 return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
1515 }
1516 case ISD::SETOLT: { // !PF & CF
1517 Tys.push_back(MVT::i8);
1518 Tys.push_back(MVT::Flag);
1519 Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8));
1520 Ops.push_back(Cond);
1521 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1522 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1523 DAG.getConstant(X86ISD::COND_B, MVT::i8),
1524 Tmp1.getValue(1));
1525 return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
1526 }
1527 case ISD::SETOLE: { // !PF & (CF || ZF)
1528 Tys.push_back(MVT::i8);
1529 Tys.push_back(MVT::Flag);
1530 Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8));
1531 Ops.push_back(Cond);
1532 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1533 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1534 DAG.getConstant(X86ISD::COND_BE, MVT::i8),
1535 Tmp1.getValue(1));
1536 return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
1537 }
1538 case ISD::SETUGT: { // PF | (!ZF & !CF)
1539 Tys.push_back(MVT::i8);
1540 Tys.push_back(MVT::Flag);
1541 Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8));
1542 Ops.push_back(Cond);
1543 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1544 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1545 DAG.getConstant(X86ISD::COND_A, MVT::i8),
1546 Tmp1.getValue(1));
1547 return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
1548 }
1549 case ISD::SETUGE: { // PF | !CF
1550 Tys.push_back(MVT::i8);
1551 Tys.push_back(MVT::Flag);
1552 Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8));
1553 Ops.push_back(Cond);
1554 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1555 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1556 DAG.getConstant(X86ISD::COND_AE, MVT::i8),
1557 Tmp1.getValue(1));
1558 return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
1559 }
1560 case ISD::SETUNE: { // PF | !ZF
1561 Tys.push_back(MVT::i8);
1562 Tys.push_back(MVT::Flag);
1563 Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8));
1564 Ops.push_back(Cond);
1565 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops);
1566 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
1567 DAG.getConstant(X86ISD::COND_NE, MVT::i8),
1568 Tmp1.getValue(1));
1569 return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
1570 }
1571 }
1572 }
Evan Chengc1583db2005-12-21 20:21:51 +00001573 }
Evan Cheng225a4d02005-12-17 01:21:05 +00001574 case ISD::SELECT: {
Evan Cheng73a1ad92006-01-10 20:26:56 +00001575 MVT::ValueType VT = Op.getValueType();
1576 bool isFP = MVT::isFloatingPoint(VT);
1577 bool isFPStack = isFP && (X86Vector < SSE2);
1578 bool isFPSSE = isFP && (X86Vector >= SSE2);
Evan Chengfb22e862006-01-13 01:03:02 +00001579 bool addTest = false;
Evan Cheng73a1ad92006-01-10 20:26:56 +00001580 SDOperand Op0 = Op.getOperand(0);
1581 SDOperand Cond, CC;
1582 if (Op0.getOpcode() == X86ISD::SETCC) {
Evan Chengfb22e862006-01-13 01:03:02 +00001583 // If condition flag is set by a X86ISD::CMP, then make a copy of it
1584 // (since flag operand cannot be shared). If the X86ISD::SETCC does not
1585 // have another use it will be eliminated.
1586 // If the X86ISD::SETCC has more than one use, then it's probably better
1587 // to use a test instead of duplicating the X86ISD::CMP (for register
1588 // pressure reason).
Evan Chengd7faa4b2006-01-13 01:17:24 +00001589 if (Op0.hasOneUse() && Op0.getOperand(1).getOpcode() == X86ISD::CMP) {
Evan Chengfb22e862006-01-13 01:03:02 +00001590 CC = Op0.getOperand(0);
1591 Cond = Op0.getOperand(1);
1592 addTest =
Evan Chengd7faa4b2006-01-13 01:17:24 +00001593 isFPStack && !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
Evan Chengfb22e862006-01-13 01:03:02 +00001594 } else
1595 addTest = true;
Evan Cheng73a1ad92006-01-10 20:26:56 +00001596 } else if (Op0.getOpcode() == ISD::SETCC) {
1597 CC = Op0.getOperand(2);
1598 bool isFP = MVT::isFloatingPoint(Op0.getOperand(1).getValueType());
Evan Cheng339edad2006-01-11 00:33:36 +00001599 unsigned X86CC = getX86CC(CC, isFP);
Evan Cheng172fce72006-01-06 00:43:03 +00001600 CC = DAG.getConstant(X86CC, MVT::i8);
Evan Cheng225a4d02005-12-17 01:21:05 +00001601 Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
Evan Cheng73a1ad92006-01-10 20:26:56 +00001602 Op0.getOperand(0), Op0.getOperand(1));
Evan Chengfb22e862006-01-13 01:03:02 +00001603 addTest = true;
1604 } else
1605 addTest = true;
Evan Cheng73a1ad92006-01-10 20:26:56 +00001606
Evan Cheng731423f2006-01-13 01:06:49 +00001607 if (addTest) {
Evan Cheng172fce72006-01-06 00:43:03 +00001608 CC = DAG.getConstant(X86ISD::COND_E, MVT::i8);
Evan Cheng73a1ad92006-01-10 20:26:56 +00001609 Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Op0, Op0);
Evan Cheng225a4d02005-12-17 01:21:05 +00001610 }
Evan Cheng9c249c32006-01-09 18:33:28 +00001611
1612 std::vector<MVT::ValueType> Tys;
1613 Tys.push_back(Op.getValueType());
1614 Tys.push_back(MVT::Flag);
1615 std::vector<SDOperand> Ops;
1616 Ops.push_back(Op.getOperand(1));
1617 Ops.push_back(Op.getOperand(2));
1618 Ops.push_back(CC);
1619 Ops.push_back(Cond);
1620 return DAG.getNode(X86ISD::CMOV, Tys, Ops);
Evan Cheng225a4d02005-12-17 01:21:05 +00001621 }
Evan Cheng6fc31042005-12-19 23:12:38 +00001622 case ISD::BRCOND: {
Evan Chengfb22e862006-01-13 01:03:02 +00001623 bool addTest = false;
Evan Cheng6fc31042005-12-19 23:12:38 +00001624 SDOperand Cond = Op.getOperand(1);
1625 SDOperand Dest = Op.getOperand(2);
1626 SDOperand CC;
Evan Chengc1583db2005-12-21 20:21:51 +00001627 if (Cond.getOpcode() == X86ISD::SETCC) {
Evan Chengfb22e862006-01-13 01:03:02 +00001628 // If condition flag is set by a X86ISD::CMP, then make a copy of it
1629 // (since flag operand cannot be shared). If the X86ISD::SETCC does not
1630 // have another use it will be eliminated.
1631 // If the X86ISD::SETCC has more than one use, then it's probably better
1632 // to use a test instead of duplicating the X86ISD::CMP (for register
1633 // pressure reason).
1634 if (Cond.hasOneUse() && Cond.getOperand(1).getOpcode() == X86ISD::CMP) {
1635 CC = Cond.getOperand(0);
1636 Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
1637 Cond.getOperand(1).getOperand(0),
1638 Cond.getOperand(1).getOperand(1));
1639 } else
1640 addTest = true;
Evan Chengc1583db2005-12-21 20:21:51 +00001641 } else if (Cond.getOpcode() == ISD::SETCC) {
Evan Cheng6fc31042005-12-19 23:12:38 +00001642 CC = Cond.getOperand(2);
Evan Cheng172fce72006-01-06 00:43:03 +00001643 bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType());
Evan Cheng339edad2006-01-11 00:33:36 +00001644 unsigned X86CC = getX86CC(CC, isFP);
Evan Cheng172fce72006-01-06 00:43:03 +00001645 CC = DAG.getConstant(X86CC, MVT::i8);
Evan Cheng6fc31042005-12-19 23:12:38 +00001646 Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
1647 Cond.getOperand(0), Cond.getOperand(1));
Evan Chengfb22e862006-01-13 01:03:02 +00001648 } else
1649 addTest = true;
1650
1651 if (addTest) {
Evan Cheng172fce72006-01-06 00:43:03 +00001652 CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8);
Evan Cheng6fc31042005-12-19 23:12:38 +00001653 Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond);
1654 }
1655 return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
1656 Op.getOperand(0), Op.getOperand(2), CC, Cond);
1657 }
Evan Cheng172fce72006-01-06 00:43:03 +00001658 case ISD::RET: {
1659 // Can only be return void.
Evan Cheng9c249c32006-01-09 18:33:28 +00001660 return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
Evan Cheng172fce72006-01-06 00:43:03 +00001661 DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
1662 }
Evan Chengae986f12006-01-11 22:15:48 +00001663 case ISD::MEMSET: {
1664 SDOperand InFlag;
1665 SDOperand Chain = Op.getOperand(0);
1666 unsigned Align =
1667 (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
1668 if (Align == 0) Align = 1;
1669
1670 MVT::ValueType AVT;
1671 SDOperand Count;
1672 if (ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Op.getOperand(2))) {
1673 unsigned ValReg;
1674 unsigned Val = ValC->getValue() & 255;
1675
1676 // If the value is a constant, then we can potentially use larger sets.
1677 switch (Align & 3) {
1678 case 2: // WORD aligned
1679 AVT = MVT::i16;
1680 if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
1681 Count = DAG.getConstant(I->getValue() / 2, MVT::i32);
1682 else
1683 Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
1684 DAG.getConstant(1, MVT::i8));
1685 Val = (Val << 8) | Val;
1686 ValReg = X86::AX;
1687 break;
1688 case 0: // DWORD aligned
1689 AVT = MVT::i32;
1690 if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
1691 Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
1692 else
1693 Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
1694 DAG.getConstant(2, MVT::i8));
1695 Val = (Val << 8) | Val;
1696 Val = (Val << 16) | Val;
1697 ValReg = X86::EAX;
1698 break;
1699 default: // Byte aligned
1700 AVT = MVT::i8;
1701 Count = Op.getOperand(3);
1702 ValReg = X86::AL;
1703 break;
1704 }
1705
1706 Chain = DAG.getCopyToReg(Chain, ValReg, DAG.getConstant(Val, AVT),
1707 InFlag);
1708 InFlag = Chain.getValue(1);
1709 } else {
1710 AVT = MVT::i8;
1711 Count = Op.getOperand(3);
1712 Chain = DAG.getCopyToReg(Chain, X86::AL, Op.getOperand(2), InFlag);
1713 InFlag = Chain.getValue(1);
1714 }
1715
1716 Chain = DAG.getCopyToReg(Chain, X86::ECX, Count, InFlag);
1717 InFlag = Chain.getValue(1);
1718 Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag);
1719 InFlag = Chain.getValue(1);
1720
1721 return DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain,
1722 DAG.getValueType(AVT), InFlag);
1723 }
1724 case ISD::MEMCPY: {
1725 SDOperand Chain = Op.getOperand(0);
1726 unsigned Align =
1727 (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
1728 if (Align == 0) Align = 1;
1729
1730 MVT::ValueType AVT;
1731 SDOperand Count;
1732 switch (Align & 3) {
1733 case 2: // WORD aligned
1734 AVT = MVT::i16;
1735 if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
1736 Count = DAG.getConstant(I->getValue() / 2, MVT::i32);
1737 else
1738 Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
1739 DAG.getConstant(1, MVT::i8));
1740 break;
1741 case 0: // DWORD aligned
1742 AVT = MVT::i32;
1743 if (ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3)))
1744 Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
1745 else
1746 Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
1747 DAG.getConstant(2, MVT::i8));
1748 break;
1749 default: // Byte aligned
1750 AVT = MVT::i8;
1751 Count = Op.getOperand(3);
1752 break;
1753 }
1754
1755 SDOperand InFlag;
1756 Chain = DAG.getCopyToReg(Chain, X86::ECX, Count, InFlag);
1757 InFlag = Chain.getValue(1);
1758 Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag);
1759 InFlag = Chain.getValue(1);
1760 Chain = DAG.getCopyToReg(Chain, X86::ESI, Op.getOperand(2), InFlag);
1761 InFlag = Chain.getValue(1);
1762
1763 return DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain,
1764 DAG.getValueType(AVT), InFlag);
1765 }
Evan Cheng5c59d492005-12-23 07:31:11 +00001766 case ISD::GlobalAddress: {
Evan Chengb94db9e2006-01-12 07:56:47 +00001767 SDOperand Result;
Evan Chenga74ce622005-12-21 02:39:21 +00001768 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1769 // For Darwin, external and weak symbols are indirect, so we want to load
1770 // the value at address GV, not the value of GV itself. This means that
1771 // the GlobalAddress must be in the base or index register of the address,
1772 // not the GV offset field.
1773 if (getTargetMachine().
1774 getSubtarget<X86Subtarget>().getIndirectExternAndWeakGlobals() &&
1775 (GV->hasWeakLinkage() || GV->isExternal()))
Evan Chengb94db9e2006-01-12 07:56:47 +00001776 Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(),
1777 DAG.getTargetGlobalAddress(GV, getPointerTy()),
1778 DAG.getSrcValue(NULL));
1779 return Result;
Chris Lattner76ac0682005-11-15 00:40:23 +00001780 }
Evan Cheng5c59d492005-12-23 07:31:11 +00001781 }
Chris Lattner76ac0682005-11-15 00:40:23 +00001782}
Evan Cheng6af02632005-12-20 06:22:03 +00001783
1784const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
1785 switch (Opcode) {
1786 default: return NULL;
Evan Cheng9c249c32006-01-09 18:33:28 +00001787 case X86ISD::ADD_FLAG: return "X86ISD::ADD_FLAG";
1788 case X86ISD::SUB_FLAG: return "X86ISD::SUB_FLAG";
1789 case X86ISD::ADC: return "X86ISD::ADC";
1790 case X86ISD::SBB: return "X86ISD::SBB";
1791 case X86ISD::SHLD: return "X86ISD::SHLD";
1792 case X86ISD::SHRD: return "X86ISD::SHRD";
Evan Cheng6305e502006-01-12 22:54:21 +00001793 case X86ISD::FILD: return "X86ISD::FILD";
Evan Cheng6af02632005-12-20 06:22:03 +00001794 case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM";
1795 case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM";
1796 case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM";
Evan Chenga74ce622005-12-21 02:39:21 +00001797 case X86ISD::FLD: return "X86ISD::FLD";
Evan Cheng45e190982006-01-05 00:27:02 +00001798 case X86ISD::FST: return "X86ISD::FST";
1799 case X86ISD::FP_GET_RESULT: return "X86ISD::FP_GET_RESULT";
Evan Chenga74ce622005-12-21 02:39:21 +00001800 case X86ISD::FP_SET_RESULT: return "X86ISD::FP_SET_RESULT";
Evan Cheng6af02632005-12-20 06:22:03 +00001801 case X86ISD::CALL: return "X86ISD::CALL";
1802 case X86ISD::TAILCALL: return "X86ISD::TAILCALL";
1803 case X86ISD::RDTSC_DAG: return "X86ISD::RDTSC_DAG";
1804 case X86ISD::CMP: return "X86ISD::CMP";
1805 case X86ISD::TEST: return "X86ISD::TEST";
Evan Chengc1583db2005-12-21 20:21:51 +00001806 case X86ISD::SETCC: return "X86ISD::SETCC";
Evan Cheng6af02632005-12-20 06:22:03 +00001807 case X86ISD::CMOV: return "X86ISD::CMOV";
1808 case X86ISD::BRCOND: return "X86ISD::BRCOND";
Evan Chenga74ce622005-12-21 02:39:21 +00001809 case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG";
Evan Chengae986f12006-01-11 22:15:48 +00001810 case X86ISD::REP_STOS: return "X86ISD::RET_STOS";
1811 case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS";
Evan Cheng6af02632005-12-20 06:22:03 +00001812 }
1813}
Evan Cheng9cdc16c2005-12-21 23:05:39 +00001814
1815bool X86TargetLowering::isMaskedValueZeroForTargetNode(const SDOperand &Op,
1816 uint64_t Mask) const {
1817
1818 unsigned Opc = Op.getOpcode();
1819
1820 switch (Opc) {
1821 default:
1822 assert(Opc >= ISD::BUILTIN_OP_END && "Expected a target specific node");
1823 break;
1824 case X86ISD::SETCC: return (Mask & 1) == 0;
1825 }
1826
1827 return false;
1828}