blob: 6de5032ff302b429a482b90d859296328e0e93d2 [file] [log] [blame]
Chris Lattnerc6d05672006-05-23 23:20:42 +00001//===-- X86ISelLowering.cpp - X86 DAG Lowering Implementation -------------===//
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002//
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"
Evan Cheng0cc39452006-01-16 21:21:29 +000016#include "X86InstrBuilder.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000017#include "X86ISelLowering.h"
Evan Chenge8bd0a32006-06-06 23:30:24 +000018#include "X86MachineFunctionInfo.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000019#include "X86TargetMachine.h"
20#include "llvm/CallingConv.h"
Evan Cheng223547a2006-01-31 22:28:30 +000021#include "llvm/Constants.h"
Evan Cheng347d5f72006-04-28 21:29:37 +000022#include "llvm/DerivedTypes.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000023#include "llvm/Function.h"
Evan Cheng6be2c582006-04-05 23:38:46 +000024#include "llvm/Intrinsics.h"
Evan Cheng30b37b52006-03-13 23:18:16 +000025#include "llvm/ADT/VectorExtras.h"
26#include "llvm/Analysis/ScalarEvolutionExpressions.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000027#include "llvm/CodeGen/MachineFrameInfo.h"
Evan Cheng4a460802006-01-11 00:33:36 +000028#include "llvm/CodeGen/MachineFunction.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000030#include "llvm/CodeGen/SelectionDAG.h"
31#include "llvm/CodeGen/SSARegMap.h"
Evan Chengef6ffb12006-01-31 03:14:29 +000032#include "llvm/Support/MathExtras.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000033#include "llvm/Target/TargetOptions.h"
Evan Chenge1113032006-10-04 18:33:38 +000034#include "llvm/Support/CommandLine.h"
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000035using namespace llvm;
36
37// FIXME: temporary.
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000038static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
39 cl::desc("Enable fastcc on X86"));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000040X86TargetLowering::X86TargetLowering(TargetMachine &TM)
41 : TargetLowering(TM) {
Evan Cheng559806f2006-01-27 08:10:46 +000042 Subtarget = &TM.getSubtarget<X86Subtarget>();
43 X86ScalarSSE = Subtarget->hasSSE2();
Evan Cheng25ab6902006-09-08 06:48:29 +000044 X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
Evan Cheng559806f2006-01-27 08:10:46 +000045
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000046 // Set up the TargetLowering object.
47
48 // X86 is weird, it always uses i8 for shift amounts and setcc results.
49 setShiftAmountType(MVT::i8);
50 setSetCCResultType(MVT::i8);
51 setSetCCResultContents(ZeroOrOneSetCCResult);
Evan Cheng0b2afbd2006-01-25 09:15:17 +000052 setSchedulingPreference(SchedulingForRegPressure);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000053 setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0
Evan Cheng25ab6902006-09-08 06:48:29 +000054 setStackPointerRegisterToSaveRestore(X86StackPtr);
Evan Cheng714554d2006-03-16 21:47:42 +000055
Evan Chenga88973f2006-03-22 19:22:18 +000056 if (!Subtarget->isTargetDarwin())
Evan Chengdf57fa02006-03-17 20:31:41 +000057 // Darwin should use _setjmp/_longjmp instead of setjmp/longjmp.
58 setUseUnderscoreSetJmpLongJmp(true);
59
Evan Cheng714554d2006-03-16 21:47:42 +000060 // Add legal addressing mode scale values.
61 addLegalAddressScale(8);
62 addLegalAddressScale(4);
63 addLegalAddressScale(2);
64 // Enter the ones which require both scale + index last. These are more
65 // expensive.
66 addLegalAddressScale(9);
67 addLegalAddressScale(5);
68 addLegalAddressScale(3);
Chris Lattnera54aa942006-01-29 06:26:08 +000069
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000070 // Set up the register classes.
Evan Cheng069287d2006-05-16 07:21:53 +000071 addRegisterClass(MVT::i8, X86::GR8RegisterClass);
72 addRegisterClass(MVT::i16, X86::GR16RegisterClass);
73 addRegisterClass(MVT::i32, X86::GR32RegisterClass);
Evan Cheng25ab6902006-09-08 06:48:29 +000074 if (Subtarget->is64Bit())
75 addRegisterClass(MVT::i64, X86::GR64RegisterClass);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000076
Evan Chengc5484282006-10-04 00:56:09 +000077 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
78
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000079 // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
80 // operation.
81 setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote);
82 setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote);
83 setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote);
Evan Cheng6892f282006-01-17 02:32:49 +000084
Evan Cheng25ab6902006-09-08 06:48:29 +000085 if (Subtarget->is64Bit()) {
86 setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand);
Evan Cheng6892f282006-01-17 02:32:49 +000087 setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
Evan Cheng25ab6902006-09-08 06:48:29 +000088 } else {
89 if (X86ScalarSSE)
90 // If SSE i64 SINT_TO_FP is not available, expand i32 UINT_TO_FP.
91 setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Expand);
92 else
93 setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
94 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +000095
96 // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
97 // this operation.
98 setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
99 setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000100 // SSE has no i16 to fp conversion, only i32
Evan Cheng02568ff2006-01-30 22:13:22 +0000101 if (X86ScalarSSE)
Evan Cheng02568ff2006-01-30 22:13:22 +0000102 setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote);
Evan Cheng5298bcc2006-02-17 07:01:52 +0000103 else {
104 setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Custom);
105 setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Custom);
106 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000107
Evan Cheng25ab6902006-09-08 06:48:29 +0000108 if (!Subtarget->is64Bit()) {
109 // Custom lower SINT_TO_FP and FP_TO_SINT from/to i64 in 32-bit mode.
110 setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
111 setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom);
112 }
Evan Cheng6dab0532006-01-30 08:02:57 +0000113
Evan Cheng02568ff2006-01-30 22:13:22 +0000114 // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
115 // this operation.
116 setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote);
117 setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote);
118
119 if (X86ScalarSSE) {
120 setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote);
121 } else {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000122 setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom);
Evan Cheng02568ff2006-01-30 22:13:22 +0000123 setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000124 }
125
126 // Handle FP_TO_UINT by promoting the destination to a larger signed
127 // conversion.
128 setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote);
129 setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote);
130 setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote);
131
Evan Cheng25ab6902006-09-08 06:48:29 +0000132 if (Subtarget->is64Bit()) {
133 setOperationAction(ISD::FP_TO_UINT , MVT::i64 , Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000134 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
Evan Cheng25ab6902006-09-08 06:48:29 +0000135 } else {
136 if (X86ScalarSSE && !Subtarget->hasSSE3())
137 // Expand FP_TO_UINT into a select.
138 // FIXME: We would like to use a Custom expander here eventually to do
139 // the optimal thing for SSE vs. the default expansion in the legalizer.
140 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand);
141 else
142 // With SSE3 we can use fisttpll to convert to a signed i64.
143 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
144 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000145
Evan Cheng02568ff2006-01-30 22:13:22 +0000146 setOperationAction(ISD::BIT_CONVERT , MVT::f32 , Expand);
147 setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand);
Chris Lattner21f66852005-12-23 05:15:23 +0000148
Evan Chengc35497f2006-10-30 08:02:39 +0000149 setOperationAction(ISD::BR_JT , MVT::Other, Expand);
Evan Cheng5298bcc2006-02-17 07:01:52 +0000150 setOperationAction(ISD::BRCOND , MVT::Other, Custom);
Nate Begeman750ac1b2006-02-01 07:19:44 +0000151 setOperationAction(ISD::BR_CC , MVT::Other, Expand);
152 setOperationAction(ISD::SELECT_CC , MVT::Other, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000153 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
Evan Cheng25ab6902006-09-08 06:48:29 +0000154 if (Subtarget->is64Bit())
155 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000156 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
Chris Lattnere80242a2005-12-07 17:59:14 +0000157 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000158 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
159 setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000160 setOperationAction(ISD::FREM , MVT::f64 , Expand);
Evan Cheng25ab6902006-09-08 06:48:29 +0000161
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000162 setOperationAction(ISD::CTPOP , MVT::i8 , Expand);
163 setOperationAction(ISD::CTTZ , MVT::i8 , Expand);
164 setOperationAction(ISD::CTLZ , MVT::i8 , Expand);
165 setOperationAction(ISD::CTPOP , MVT::i16 , Expand);
166 setOperationAction(ISD::CTTZ , MVT::i16 , Expand);
167 setOperationAction(ISD::CTLZ , MVT::i16 , Expand);
168 setOperationAction(ISD::CTPOP , MVT::i32 , Expand);
169 setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
170 setOperationAction(ISD::CTLZ , MVT::i32 , Expand);
Evan Cheng25ab6902006-09-08 06:48:29 +0000171 if (Subtarget->is64Bit()) {
172 setOperationAction(ISD::CTPOP , MVT::i64 , Expand);
173 setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
174 setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
175 }
176
Andrew Lenharthb873ff32005-11-20 21:41:10 +0000177 setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
Nate Begemand88fc032006-01-14 03:14:10 +0000178 setOperationAction(ISD::BSWAP , MVT::i16 , Expand);
Nate Begeman35ef9132006-01-11 21:21:00 +0000179
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000180 // These should be promoted to a larger select which is supported.
181 setOperationAction(ISD::SELECT , MVT::i1 , Promote);
182 setOperationAction(ISD::SELECT , MVT::i8 , Promote);
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000183 // X86 wants to expand cmov itself.
Evan Cheng5298bcc2006-02-17 07:01:52 +0000184 setOperationAction(ISD::SELECT , MVT::i16 , Custom);
185 setOperationAction(ISD::SELECT , MVT::i32 , Custom);
186 setOperationAction(ISD::SELECT , MVT::f32 , Custom);
187 setOperationAction(ISD::SELECT , MVT::f64 , Custom);
188 setOperationAction(ISD::SETCC , MVT::i8 , Custom);
189 setOperationAction(ISD::SETCC , MVT::i16 , Custom);
190 setOperationAction(ISD::SETCC , MVT::i32 , Custom);
191 setOperationAction(ISD::SETCC , MVT::f32 , Custom);
192 setOperationAction(ISD::SETCC , MVT::f64 , Custom);
Evan Cheng25ab6902006-09-08 06:48:29 +0000193 if (Subtarget->is64Bit()) {
194 setOperationAction(ISD::SELECT , MVT::i64 , Custom);
195 setOperationAction(ISD::SETCC , MVT::i64 , Custom);
196 }
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000197 // X86 ret instruction may pop stack.
Evan Cheng5298bcc2006-02-17 07:01:52 +0000198 setOperationAction(ISD::RET , MVT::Other, Custom);
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000199 // Darwin ABI issue.
Evan Cheng7ccced62006-02-18 00:15:05 +0000200 setOperationAction(ISD::ConstantPool , MVT::i32 , Custom);
Nate Begeman37efe672006-04-22 18:53:45 +0000201 setOperationAction(ISD::JumpTable , MVT::i32 , Custom);
Evan Cheng5298bcc2006-02-17 07:01:52 +0000202 setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
Evan Cheng020d2e82006-02-23 20:41:18 +0000203 setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom);
Evan Cheng25ab6902006-09-08 06:48:29 +0000204 if (Subtarget->is64Bit()) {
205 setOperationAction(ISD::ConstantPool , MVT::i64 , Custom);
206 setOperationAction(ISD::JumpTable , MVT::i64 , Custom);
207 setOperationAction(ISD::GlobalAddress , MVT::i64 , Custom);
208 setOperationAction(ISD::ExternalSymbol, MVT::i64 , Custom);
209 }
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000210 // 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
Evan Cheng5298bcc2006-02-17 07:01:52 +0000211 setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom);
212 setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom);
213 setOperationAction(ISD::SRL_PARTS , MVT::i32 , Custom);
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000214 // X86 wants to expand memset / memcpy itself.
Evan Cheng5298bcc2006-02-17 07:01:52 +0000215 setOperationAction(ISD::MEMSET , MVT::Other, Custom);
216 setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000217
Chris Lattnerf73bae12005-11-29 06:16:21 +0000218 // We don't have line number support yet.
219 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
Jim Laskeye0bce712006-01-05 01:47:43 +0000220 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Evan Cheng3c992d22006-03-07 02:02:57 +0000221 // FIXME - use subtarget debug flags
Reid Spencer02b85112006-10-30 22:32:30 +0000222 if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetELF())
Evan Cheng3c992d22006-03-07 02:02:57 +0000223 setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
Chris Lattnerf73bae12005-11-29 06:16:21 +0000224
Nate Begemanacc398c2006-01-25 18:21:52 +0000225 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
226 setOperationAction(ISD::VASTART , MVT::Other, Custom);
227
228 // Use the default implementation.
229 setOperationAction(ISD::VAARG , MVT::Other, Expand);
230 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
231 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Chris Lattnere1125522006-01-15 09:00:21 +0000232 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
233 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
Evan Cheng25ab6902006-09-08 06:48:29 +0000234 if (Subtarget->is64Bit())
235 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
Chris Lattnere1125522006-01-15 09:00:21 +0000236 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
Chris Lattnerb99329e2006-01-13 02:42:53 +0000237
Chris Lattner9601a862006-03-05 05:08:37 +0000238 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
239 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
240
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000241 if (X86ScalarSSE) {
242 // Set up the FP register classes.
Evan Cheng5ee4ccc2006-01-12 08:27:59 +0000243 addRegisterClass(MVT::f32, X86::FR32RegisterClass);
244 addRegisterClass(MVT::f64, X86::FR64RegisterClass);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000245
Evan Cheng223547a2006-01-31 22:28:30 +0000246 // Use ANDPD to simulate FABS.
247 setOperationAction(ISD::FABS , MVT::f64, Custom);
248 setOperationAction(ISD::FABS , MVT::f32, Custom);
249
250 // Use XORP to simulate FNEG.
251 setOperationAction(ISD::FNEG , MVT::f64, Custom);
252 setOperationAction(ISD::FNEG , MVT::f32, Custom);
253
Evan Chengd25e9e82006-02-02 00:28:23 +0000254 // We don't support sin/cos/fmod
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000255 setOperationAction(ISD::FSIN , MVT::f64, Expand);
256 setOperationAction(ISD::FCOS , MVT::f64, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000257 setOperationAction(ISD::FREM , MVT::f64, Expand);
258 setOperationAction(ISD::FSIN , MVT::f32, Expand);
259 setOperationAction(ISD::FCOS , MVT::f32, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000260 setOperationAction(ISD::FREM , MVT::f32, Expand);
261
Chris Lattnera54aa942006-01-29 06:26:08 +0000262 // Expand FP immediates into loads from the stack, except for the special
263 // cases we handle.
264 setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
265 setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000266 addLegalFPImmediate(+0.0); // xorps / xorpd
267 } else {
268 // Set up the FP register classes.
269 addRegisterClass(MVT::f64, X86::RFPRegisterClass);
Chris Lattner44d9b9b2006-01-29 06:44:22 +0000270
271 setOperationAction(ISD::UNDEF, MVT::f64, Expand);
272
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000273 if (!UnsafeFPMath) {
274 setOperationAction(ISD::FSIN , MVT::f64 , Expand);
275 setOperationAction(ISD::FCOS , MVT::f64 , Expand);
276 }
277
Chris Lattnera54aa942006-01-29 06:26:08 +0000278 setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000279 addLegalFPImmediate(+0.0); // FLD0
280 addLegalFPImmediate(+1.0); // FLD1
281 addLegalFPImmediate(-0.0); // FLD0/FCHS
282 addLegalFPImmediate(-1.0); // FLD1/FCHS
283 }
Evan Cheng470a6ad2006-02-22 02:26:30 +0000284
Evan Chengd30bf012006-03-01 01:11:20 +0000285 // First set operation action for all vector types to expand. Then we
286 // will selectively turn on ones that can be effectively codegen'd.
287 for (unsigned VT = (unsigned)MVT::Vector + 1;
288 VT != (unsigned)MVT::LAST_VALUETYPE; VT++) {
289 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Expand);
290 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand);
Evan Cheng6bdb3f62006-10-27 18:49:08 +0000291 setOperationAction(ISD::FADD, (MVT::ValueType)VT, Expand);
292 setOperationAction(ISD::FSUB, (MVT::ValueType)VT, Expand);
Evan Chengd30bf012006-03-01 01:11:20 +0000293 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand);
Evan Cheng6bdb3f62006-10-27 18:49:08 +0000294 setOperationAction(ISD::FMUL, (MVT::ValueType)VT, Expand);
295 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
296 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
297 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand);
298 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
299 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
Evan Chengd30bf012006-03-01 01:11:20 +0000300 setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand);
Evan Chengb067a1e2006-03-31 19:22:53 +0000301 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand);
Chris Lattner9b3bd462006-03-21 20:51:05 +0000302 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand);
Evan Chengb067a1e2006-03-31 19:22:53 +0000303 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand);
Evan Chengd30bf012006-03-01 01:11:20 +0000304 }
305
Evan Chenga88973f2006-03-22 19:22:18 +0000306 if (Subtarget->hasMMX()) {
Evan Cheng470a6ad2006-02-22 02:26:30 +0000307 addRegisterClass(MVT::v8i8, X86::VR64RegisterClass);
308 addRegisterClass(MVT::v4i16, X86::VR64RegisterClass);
309 addRegisterClass(MVT::v2i32, X86::VR64RegisterClass);
310
Evan Chengd30bf012006-03-01 01:11:20 +0000311 // FIXME: add MMX packed arithmetics
Evan Cheng48090aa2006-03-21 23:01:21 +0000312 setOperationAction(ISD::BUILD_VECTOR, MVT::v8i8, Expand);
313 setOperationAction(ISD::BUILD_VECTOR, MVT::v4i16, Expand);
314 setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Expand);
Evan Cheng470a6ad2006-02-22 02:26:30 +0000315 }
316
Evan Chenga88973f2006-03-22 19:22:18 +0000317 if (Subtarget->hasSSE1()) {
Evan Cheng470a6ad2006-02-22 02:26:30 +0000318 addRegisterClass(MVT::v4f32, X86::VR128RegisterClass);
319
Evan Cheng6bdb3f62006-10-27 18:49:08 +0000320 setOperationAction(ISD::FADD, MVT::v4f32, Legal);
321 setOperationAction(ISD::FSUB, MVT::v4f32, Legal);
322 setOperationAction(ISD::FMUL, MVT::v4f32, Legal);
323 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Evan Chengf7c378e2006-04-10 07:23:14 +0000324 setOperationAction(ISD::LOAD, MVT::v4f32, Legal);
325 setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom);
326 setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4f32, Custom);
Evan Cheng11e15b32006-04-03 20:53:28 +0000327 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);
Evan Chengf7c378e2006-04-10 07:23:14 +0000328 setOperationAction(ISD::SELECT, MVT::v4f32, Custom);
Evan Cheng470a6ad2006-02-22 02:26:30 +0000329 }
330
Evan Chenga88973f2006-03-22 19:22:18 +0000331 if (Subtarget->hasSSE2()) {
Evan Cheng470a6ad2006-02-22 02:26:30 +0000332 addRegisterClass(MVT::v2f64, X86::VR128RegisterClass);
333 addRegisterClass(MVT::v16i8, X86::VR128RegisterClass);
334 addRegisterClass(MVT::v8i16, X86::VR128RegisterClass);
335 addRegisterClass(MVT::v4i32, X86::VR128RegisterClass);
336 addRegisterClass(MVT::v2i64, X86::VR128RegisterClass);
337
Evan Chengf7c378e2006-04-10 07:23:14 +0000338 setOperationAction(ISD::ADD, MVT::v16i8, Legal);
339 setOperationAction(ISD::ADD, MVT::v8i16, Legal);
340 setOperationAction(ISD::ADD, MVT::v4i32, Legal);
Evan Chengf7c378e2006-04-10 07:23:14 +0000341 setOperationAction(ISD::SUB, MVT::v16i8, Legal);
342 setOperationAction(ISD::SUB, MVT::v8i16, Legal);
343 setOperationAction(ISD::SUB, MVT::v4i32, Legal);
Evan Chengf9989842006-04-13 05:10:25 +0000344 setOperationAction(ISD::MUL, MVT::v8i16, Legal);
Evan Cheng6bdb3f62006-10-27 18:49:08 +0000345 setOperationAction(ISD::FADD, MVT::v2f64, Legal);
346 setOperationAction(ISD::FSUB, MVT::v2f64, Legal);
347 setOperationAction(ISD::FMUL, MVT::v2f64, Legal);
348 setOperationAction(ISD::FDIV, MVT::v2f64, Legal);
Evan Cheng2c3ae372006-04-12 21:21:57 +0000349
Evan Chengf7c378e2006-04-10 07:23:14 +0000350 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Custom);
351 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Custom);
Evan Chengb067a1e2006-03-31 19:22:53 +0000352 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Custom);
Evan Cheng5edb8d22006-04-17 22:04:06 +0000353 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom);
354 // Implement v4f32 insert_vector_elt in terms of SSE2 v8i16 ones.
355 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
Evan Chengf7c378e2006-04-10 07:23:14 +0000356
Evan Cheng2c3ae372006-04-12 21:21:57 +0000357 // Custom lower build_vector, vector_shuffle, and extract_vector_elt.
358 for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)MVT::v2i64; VT++) {
359 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
360 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
361 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
362 }
363 setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Custom);
364 setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Custom);
365 setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Custom);
366 setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Custom);
367 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f64, Custom);
368 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i64, Custom);
369
370 // Promote v16i8, v8i16, v4i32 load, select, and, or, xor to v2i64.
371 for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)MVT::v2i64; VT++) {
372 setOperationAction(ISD::AND, (MVT::ValueType)VT, Promote);
373 AddPromotedToType (ISD::AND, (MVT::ValueType)VT, MVT::v2i64);
374 setOperationAction(ISD::OR, (MVT::ValueType)VT, Promote);
375 AddPromotedToType (ISD::OR, (MVT::ValueType)VT, MVT::v2i64);
376 setOperationAction(ISD::XOR, (MVT::ValueType)VT, Promote);
377 AddPromotedToType (ISD::XOR, (MVT::ValueType)VT, MVT::v2i64);
Evan Cheng91b740d2006-04-12 17:12:36 +0000378 setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Promote);
379 AddPromotedToType (ISD::LOAD, (MVT::ValueType)VT, MVT::v2i64);
Evan Cheng2c3ae372006-04-12 21:21:57 +0000380 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Promote);
381 AddPromotedToType (ISD::SELECT, (MVT::ValueType)VT, MVT::v2i64);
Evan Chengf7c378e2006-04-10 07:23:14 +0000382 }
Evan Cheng2c3ae372006-04-12 21:21:57 +0000383
384 // Custom lower v2i64 and v2f64 selects.
385 setOperationAction(ISD::LOAD, MVT::v2f64, Legal);
Evan Cheng91b740d2006-04-12 17:12:36 +0000386 setOperationAction(ISD::LOAD, MVT::v2i64, Legal);
Evan Chengf7c378e2006-04-10 07:23:14 +0000387 setOperationAction(ISD::SELECT, MVT::v2f64, Custom);
Evan Cheng2c3ae372006-04-12 21:21:57 +0000388 setOperationAction(ISD::SELECT, MVT::v2i64, Custom);
Evan Cheng470a6ad2006-02-22 02:26:30 +0000389 }
390
Evan Cheng6be2c582006-04-05 23:38:46 +0000391 // We want to custom lower some of our intrinsics.
392 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
393
Evan Cheng206ee9d2006-07-07 08:33:52 +0000394 // We have target-specific dag combine patterns for the following nodes:
395 setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
Chris Lattner83e6c992006-10-04 06:57:07 +0000396 setTargetDAGCombine(ISD::SELECT);
Evan Cheng206ee9d2006-07-07 08:33:52 +0000397
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000398 computeRegisterProperties();
399
Evan Cheng87ed7162006-02-14 08:25:08 +0000400 // FIXME: These should be based on subtarget info. Plus, the values should
401 // be smaller when we are in optimizing for size mode.
Evan Chenga03a5dc2006-02-14 08:38:30 +0000402 maxStoresPerMemset = 16; // For %llvm.memset -> sequence of stores
403 maxStoresPerMemcpy = 16; // For %llvm.memcpy -> sequence of stores
404 maxStoresPerMemmove = 16; // For %llvm.memmove -> sequence of stores
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000405 allowUnalignedMemoryAccesses = true; // x86 supports it!
406}
407
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000408//===----------------------------------------------------------------------===//
409// C Calling Convention implementation
410//===----------------------------------------------------------------------===//
411
Evan Cheng85e38002006-04-27 05:35:28 +0000412/// AddLiveIn - This helper function adds the specified physical register to the
413/// MachineFunction as a live in value. It also creates a corresponding virtual
414/// register for it.
415static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
416 TargetRegisterClass *RC) {
417 assert(RC->contains(PReg) && "Not the correct regclass!");
418 unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
419 MF.addLiveIn(PReg, VReg);
420 return VReg;
421}
422
Evan Cheng2fdd95e2006-04-27 08:31:10 +0000423/// HowToPassCCCArgument - Returns how an formal argument of the specified type
424/// should be passed. If it is through stack, returns the size of the stack
Evan Chengf9ff7c52006-05-26 18:25:43 +0000425/// slot; if it is through XMM register, returns the number of XMM registers
Evan Cheng2fdd95e2006-04-27 08:31:10 +0000426/// are needed.
427static void
428HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs,
429 unsigned &ObjSize, unsigned &ObjXMMRegs) {
Evan Cheng26755342006-06-01 05:53:27 +0000430 ObjXMMRegs = 0;
Evan Chengcc1fc222006-05-25 23:31:23 +0000431
Evan Chengeda65fa2006-04-27 01:32:22 +0000432 switch (ObjectVT) {
433 default: assert(0 && "Unhandled argument type!");
Evan Chengeda65fa2006-04-27 01:32:22 +0000434 case MVT::i8: ObjSize = 1; break;
435 case MVT::i16: ObjSize = 2; break;
436 case MVT::i32: ObjSize = 4; break;
437 case MVT::i64: ObjSize = 8; break;
438 case MVT::f32: ObjSize = 4; break;
439 case MVT::f64: ObjSize = 8; break;
Evan Cheng2fdd95e2006-04-27 08:31:10 +0000440 case MVT::v16i8:
441 case MVT::v8i16:
442 case MVT::v4i32:
443 case MVT::v2i64:
444 case MVT::v4f32:
445 case MVT::v2f64:
Evan Cheng1d6a9b32006-05-26 19:22:06 +0000446 if (NumXMMRegs < 4)
Evan Cheng2fdd95e2006-04-27 08:31:10 +0000447 ObjXMMRegs = 1;
448 else
449 ObjSize = 16;
450 break;
Evan Chengeda65fa2006-04-27 01:32:22 +0000451 }
Evan Chengeda65fa2006-04-27 01:32:22 +0000452}
453
Evan Cheng25caf632006-05-23 21:06:34 +0000454SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) {
455 unsigned NumArgs = Op.Val->getNumValues() - 1;
Evan Cheng1bc78042006-04-26 01:20:17 +0000456 MachineFunction &MF = DAG.getMachineFunction();
457 MachineFrameInfo *MFI = MF.getFrameInfo();
Evan Cheng25caf632006-05-23 21:06:34 +0000458 SDOperand Root = Op.getOperand(0);
459 std::vector<SDOperand> ArgValues;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000460
Evan Chengeda65fa2006-04-27 01:32:22 +0000461 // Add DAG nodes to load the arguments... On entry to a function on the X86,
462 // the stack frame looks like this:
463 //
464 // [ESP] -- return address
465 // [ESP + 4] -- first argument (leftmost lexically)
Evan Chengf9d62dc2006-05-26 18:37:16 +0000466 // [ESP + 8] -- second argument, if first argument is <= 4 bytes in size
Evan Chengeda65fa2006-04-27 01:32:22 +0000467 // ...
468 //
Evan Cheng1bc78042006-04-26 01:20:17 +0000469 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
Evan Cheng2fdd95e2006-04-27 08:31:10 +0000470 unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
Evan Cheng1d6a9b32006-05-26 19:22:06 +0000471 static const unsigned XMMArgRegs[] = {
472 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
473 };
Evan Cheng1bc78042006-04-26 01:20:17 +0000474 for (unsigned i = 0; i < NumArgs; ++i) {
Evan Cheng25caf632006-05-23 21:06:34 +0000475 MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
476 unsigned ArgIncrement = 4;
477 unsigned ObjSize = 0;
478 unsigned ObjXMMRegs = 0;
479 HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs);
Evan Cheng052fb512006-05-26 18:39:59 +0000480 if (ObjSize > 4)
Evan Cheng25caf632006-05-23 21:06:34 +0000481 ArgIncrement = ObjSize;
Evan Chengeda65fa2006-04-27 01:32:22 +0000482
Evan Cheng25caf632006-05-23 21:06:34 +0000483 SDOperand ArgValue;
484 if (ObjXMMRegs) {
485 // Passed in a XMM register.
486 unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
Evan Cheng25ab6902006-09-08 06:48:29 +0000487 X86::VR128RegisterClass);
Evan Cheng25caf632006-05-23 21:06:34 +0000488 ArgValue= DAG.getCopyFromReg(Root, Reg, ObjectVT);
489 ArgValues.push_back(ArgValue);
490 NumXMMRegs += ObjXMMRegs;
491 } else {
Evan Cheng3fddf242006-05-26 20:37:47 +0000492 // XMM arguments have to be aligned on 16-byte boundary.
493 if (ObjSize == 16)
494 ArgOffset = ((ArgOffset + 15) / 16) * 16;
Evan Cheng25caf632006-05-23 21:06:34 +0000495 // Create the frame index object for this incoming parameter...
496 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
497 SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
Evan Cheng466685d2006-10-09 20:57:25 +0000498 ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
Evan Cheng25caf632006-05-23 21:06:34 +0000499 ArgValues.push_back(ArgValue);
500 ArgOffset += ArgIncrement; // Move on to the next argument...
Evan Cheng1bc78042006-04-26 01:20:17 +0000501 }
Evan Cheng1bc78042006-04-26 01:20:17 +0000502 }
503
Evan Cheng25caf632006-05-23 21:06:34 +0000504 ArgValues.push_back(Root);
505
Evan Cheng1bc78042006-04-26 01:20:17 +0000506 // If the function takes variable number of arguments, make a frame index for
507 // the start of the first vararg value... for expansion of llvm.va_start.
Evan Cheng4db3af32006-05-23 21:08:24 +0000508 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
509 if (isVarArg)
Evan Cheng1bc78042006-04-26 01:20:17 +0000510 VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
Evan Cheng25ab6902006-09-08 06:48:29 +0000511 RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
512 ReturnAddrIndex = 0; // No return address slot generated yet.
513 BytesToPopOnReturn = 0; // Callee pops nothing.
Evan Cheng1bc78042006-04-26 01:20:17 +0000514 BytesCallerReserves = ArgOffset;
Evan Cheng25caf632006-05-23 21:06:34 +0000515
Chris Lattner2d297092006-05-23 18:50:38 +0000516 // If this is a struct return on Darwin/X86, the callee pops the hidden struct
517 // pointer.
Evan Cheng25caf632006-05-23 21:06:34 +0000518 if (MF.getFunction()->getCallingConv() == CallingConv::CSRet &&
Chris Lattner2d297092006-05-23 18:50:38 +0000519 Subtarget->isTargetDarwin())
520 BytesToPopOnReturn = 4;
Evan Cheng1bc78042006-04-26 01:20:17 +0000521
Evan Cheng25caf632006-05-23 21:06:34 +0000522 // Return the new list of results.
523 std::vector<MVT::ValueType> RetVTs(Op.Val->value_begin(),
524 Op.Val->value_end());
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000525 return DAG.getNode(ISD::MERGE_VALUES, RetVTs, &ArgValues[0],ArgValues.size());
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000526}
527
Evan Cheng32fe1032006-05-25 00:59:30 +0000528
529SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) {
530 SDOperand Chain = Op.getOperand(0);
531 unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
532 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
533 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
534 SDOperand Callee = Op.getOperand(4);
535 MVT::ValueType RetVT= Op.Val->getValueType(0);
536 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000537
Evan Cheng347d5f72006-04-28 21:29:37 +0000538 // Keep track of the number of XMM regs passed so far.
539 unsigned NumXMMRegs = 0;
Evan Cheng32fe1032006-05-25 00:59:30 +0000540 static const unsigned XMMArgRegs[] = {
Evan Cheng1d6a9b32006-05-26 19:22:06 +0000541 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
Evan Cheng32fe1032006-05-25 00:59:30 +0000542 };
Evan Cheng347d5f72006-04-28 21:29:37 +0000543
Evan Cheng32fe1032006-05-25 00:59:30 +0000544 // Count how many bytes are to be pushed on the stack.
545 unsigned NumBytes = 0;
546 for (unsigned i = 0; i != NumOps; ++i) {
547 SDOperand Arg = Op.getOperand(5+2*i);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000548
Evan Cheng32fe1032006-05-25 00:59:30 +0000549 switch (Arg.getValueType()) {
550 default: assert(0 && "Unexpected ValueType for argument!");
551 case MVT::i8:
552 case MVT::i16:
553 case MVT::i32:
554 case MVT::f32:
555 NumBytes += 4;
556 break;
557 case MVT::i64:
558 case MVT::f64:
559 NumBytes += 8;
560 break;
561 case MVT::v16i8:
562 case MVT::v8i16:
563 case MVT::v4i32:
564 case MVT::v2i64:
565 case MVT::v4f32:
Evan Cheng25e71d12006-05-25 22:38:31 +0000566 case MVT::v2f64:
Evan Cheng1d6a9b32006-05-26 19:22:06 +0000567 if (NumXMMRegs < 4)
Evan Cheng32fe1032006-05-25 00:59:30 +0000568 ++NumXMMRegs;
Evan Cheng3fddf242006-05-26 20:37:47 +0000569 else {
570 // XMM arguments have to be aligned on 16-byte boundary.
571 NumBytes = ((NumBytes + 15) / 16) * 16;
Evan Cheng32fe1032006-05-25 00:59:30 +0000572 NumBytes += 16;
Evan Cheng3fddf242006-05-26 20:37:47 +0000573 }
Evan Cheng32fe1032006-05-25 00:59:30 +0000574 break;
575 }
Evan Cheng32fe1032006-05-25 00:59:30 +0000576 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000577
Evan Cheng32fe1032006-05-25 00:59:30 +0000578 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000579
Evan Cheng32fe1032006-05-25 00:59:30 +0000580 // Arguments go on the stack in reverse order, as specified by the ABI.
581 unsigned ArgOffset = 0;
582 NumXMMRegs = 0;
583 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
584 std::vector<SDOperand> MemOpChains;
Evan Cheng25ab6902006-09-08 06:48:29 +0000585 SDOperand StackPtr = DAG.getRegister(X86StackPtr, getPointerTy());
Evan Cheng32fe1032006-05-25 00:59:30 +0000586 for (unsigned i = 0; i != NumOps; ++i) {
587 SDOperand Arg = Op.getOperand(5+2*i);
588
589 switch (Arg.getValueType()) {
590 default: assert(0 && "Unexpected ValueType for argument!");
591 case MVT::i8:
Evan Cheng6b5783d2006-05-25 18:56:34 +0000592 case MVT::i16: {
Evan Cheng32fe1032006-05-25 00:59:30 +0000593 // Promote the integer to 32 bits. If the input type is signed use a
594 // sign extend, otherwise use a zero extend.
595 unsigned ExtOp =
596 dyn_cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue() ?
597 ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
598 Arg = DAG.getNode(ExtOp, MVT::i32, Arg);
Evan Cheng6b5783d2006-05-25 18:56:34 +0000599 }
600 // Fallthrough
Evan Cheng32fe1032006-05-25 00:59:30 +0000601
602 case MVT::i32:
603 case MVT::f32: {
604 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
605 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +0000606 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Evan Cheng32fe1032006-05-25 00:59:30 +0000607 ArgOffset += 4;
608 break;
609 }
610 case MVT::i64:
611 case MVT::f64: {
612 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
613 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +0000614 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Evan Cheng32fe1032006-05-25 00:59:30 +0000615 ArgOffset += 8;
616 break;
617 }
618 case MVT::v16i8:
619 case MVT::v8i16:
620 case MVT::v4i32:
621 case MVT::v2i64:
622 case MVT::v4f32:
Evan Cheng25e71d12006-05-25 22:38:31 +0000623 case MVT::v2f64:
Evan Cheng1d6a9b32006-05-26 19:22:06 +0000624 if (NumXMMRegs < 4) {
Evan Cheng32fe1032006-05-25 00:59:30 +0000625 RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg));
626 NumXMMRegs++;
627 } else {
Evan Cheng3fddf242006-05-26 20:37:47 +0000628 // XMM arguments have to be aligned on 16-byte boundary.
629 ArgOffset = ((ArgOffset + 15) / 16) * 16;
Evan Cheng347d5f72006-04-28 21:29:37 +0000630 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
Evan Cheng32fe1032006-05-25 00:59:30 +0000631 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +0000632 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Evan Cheng32fe1032006-05-25 00:59:30 +0000633 ArgOffset += 16;
Evan Cheng347d5f72006-04-28 21:29:37 +0000634 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000635 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000636 }
637
Evan Cheng32fe1032006-05-25 00:59:30 +0000638 if (!MemOpChains.empty())
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000639 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
640 &MemOpChains[0], MemOpChains.size());
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000641
Evan Cheng347d5f72006-04-28 21:29:37 +0000642 // Build a sequence of copy-to-reg nodes chained together with token chain
643 // and flag operands which copy the outgoing args into registers.
644 SDOperand InFlag;
Evan Cheng32fe1032006-05-25 00:59:30 +0000645 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
646 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
647 InFlag);
Evan Cheng347d5f72006-04-28 21:29:37 +0000648 InFlag = Chain.getValue(1);
649 }
650
Evan Cheng32fe1032006-05-25 00:59:30 +0000651 // If the callee is a GlobalAddress node (quite common, every direct call is)
652 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
653 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
654 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
655 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
656 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
657
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000658 std::vector<MVT::ValueType> NodeTys;
659 NodeTys.push_back(MVT::Other); // Returns a chain
660 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
661 std::vector<SDOperand> Ops;
662 Ops.push_back(Chain);
663 Ops.push_back(Callee);
Evan Chengb69d1132006-06-14 18:17:40 +0000664
665 // Add argument registers to the end of the list so that they are known live
666 // into the call.
667 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
668 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
669 RegsToPass[i].second.getValueType()));
670
Evan Cheng347d5f72006-04-28 21:29:37 +0000671 if (InFlag.Val)
672 Ops.push_back(InFlag);
Evan Chengd90eb7f2006-01-05 00:27:02 +0000673
Evan Cheng32fe1032006-05-25 00:59:30 +0000674 Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000675 NodeTys, &Ops[0], Ops.size());
Evan Cheng347d5f72006-04-28 21:29:37 +0000676 InFlag = Chain.getValue(1);
Evan Chengd90eb7f2006-01-05 00:27:02 +0000677
Chris Lattner2d297092006-05-23 18:50:38 +0000678 // Create the CALLSEQ_END node.
679 unsigned NumBytesForCalleeToPush = 0;
680
681 // If this is is a call to a struct-return function on Darwin/X86, the callee
682 // pops the hidden struct pointer, so we have to push it back.
683 if (CallingConv == CallingConv::CSRet && Subtarget->isTargetDarwin())
684 NumBytesForCalleeToPush = 4;
685
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000686 NodeTys.clear();
687 NodeTys.push_back(MVT::Other); // Returns a chain
Evan Cheng32fe1032006-05-25 00:59:30 +0000688 if (RetVT != MVT::Other)
689 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000690 Ops.clear();
691 Ops.push_back(Chain);
692 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
Chris Lattner2d297092006-05-23 18:50:38 +0000693 Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy()));
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000694 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000695 Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
Evan Cheng32fe1032006-05-25 00:59:30 +0000696 if (RetVT != MVT::Other)
697 InFlag = Chain.getValue(1);
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000698
Evan Cheng32fe1032006-05-25 00:59:30 +0000699 std::vector<SDOperand> ResultVals;
700 NodeTys.clear();
701 switch (RetVT) {
702 default: assert(0 && "Unknown value type to return!");
703 case MVT::Other: break;
704 case MVT::i8:
705 Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1);
706 ResultVals.push_back(Chain.getValue(0));
707 NodeTys.push_back(MVT::i8);
708 break;
709 case MVT::i16:
710 Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1);
711 ResultVals.push_back(Chain.getValue(0));
712 NodeTys.push_back(MVT::i16);
713 break;
714 case MVT::i32:
715 if (Op.Val->getValueType(1) == MVT::i32) {
716 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
717 ResultVals.push_back(Chain.getValue(0));
718 Chain = DAG.getCopyFromReg(Chain, X86::EDX, MVT::i32,
719 Chain.getValue(2)).getValue(1);
720 ResultVals.push_back(Chain.getValue(0));
721 NodeTys.push_back(MVT::i32);
722 } else {
723 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
724 ResultVals.push_back(Chain.getValue(0));
Evan Chengd90eb7f2006-01-05 00:27:02 +0000725 }
Evan Cheng32fe1032006-05-25 00:59:30 +0000726 NodeTys.push_back(MVT::i32);
727 break;
728 case MVT::v16i8:
729 case MVT::v8i16:
730 case MVT::v4i32:
731 case MVT::v2i64:
732 case MVT::v4f32:
733 case MVT::v2f64:
Evan Cheng32fe1032006-05-25 00:59:30 +0000734 Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1);
735 ResultVals.push_back(Chain.getValue(0));
736 NodeTys.push_back(RetVT);
737 break;
738 case MVT::f32:
739 case MVT::f64: {
740 std::vector<MVT::ValueType> Tys;
741 Tys.push_back(MVT::f64);
742 Tys.push_back(MVT::Other);
743 Tys.push_back(MVT::Flag);
744 std::vector<SDOperand> Ops;
745 Ops.push_back(Chain);
746 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000747 SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys,
748 &Ops[0], Ops.size());
Evan Cheng32fe1032006-05-25 00:59:30 +0000749 Chain = RetVal.getValue(1);
750 InFlag = RetVal.getValue(2);
751 if (X86ScalarSSE) {
752 // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
753 // shouldn't be necessary except that RFP cannot be live across
754 // multiple blocks. When stackifier is fixed, they can be uncoupled.
755 MachineFunction &MF = DAG.getMachineFunction();
756 int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
757 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
758 Tys.clear();
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000759 Tys.push_back(MVT::Other);
Evan Cheng32fe1032006-05-25 00:59:30 +0000760 Ops.clear();
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000761 Ops.push_back(Chain);
Evan Cheng32fe1032006-05-25 00:59:30 +0000762 Ops.push_back(RetVal);
763 Ops.push_back(StackSlot);
764 Ops.push_back(DAG.getValueType(RetVT));
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000765 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000766 Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
Evan Cheng466685d2006-10-09 20:57:25 +0000767 RetVal = DAG.getLoad(RetVT, Chain, StackSlot, NULL, 0);
Evan Cheng347d5f72006-04-28 21:29:37 +0000768 Chain = RetVal.getValue(1);
Evan Cheng347d5f72006-04-28 21:29:37 +0000769 }
Evan Cheng32fe1032006-05-25 00:59:30 +0000770
771 if (RetVT == MVT::f32 && !X86ScalarSSE)
772 // FIXME: we would really like to remember that this FP_ROUND
773 // operation is okay to eliminate if we allow excess FP precision.
774 RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
775 ResultVals.push_back(RetVal);
776 NodeTys.push_back(RetVT);
777 break;
778 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000779 }
Nate Begeman4c5dcf52006-02-17 00:03:04 +0000780
Evan Cheng32fe1032006-05-25 00:59:30 +0000781 // If the function returns void, just return the chain.
782 if (ResultVals.empty())
783 return Chain;
784
785 // Otherwise, merge everything together with a MERGE_VALUES node.
786 NodeTys.push_back(MVT::Other);
787 ResultVals.push_back(Chain);
Chris Lattnerbd564bf2006-08-08 02:23:42 +0000788 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
789 &ResultVals[0], ResultVals.size());
Evan Cheng32fe1032006-05-25 00:59:30 +0000790 return Res.getValue(Op.ResNo);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +0000791}
792
Evan Cheng25ab6902006-09-08 06:48:29 +0000793
794//===----------------------------------------------------------------------===//
795// X86-64 C Calling Convention implementation
796//===----------------------------------------------------------------------===//
797
798/// HowToPassX86_64CCCArgument - Returns how an formal argument of the specified
799/// type should be passed. If it is through stack, returns the size of the stack
800/// slot; if it is through integer or XMM register, returns the number of
801/// integer or XMM registers are needed.
802static void
803HowToPassX86_64CCCArgument(MVT::ValueType ObjectVT,
804 unsigned NumIntRegs, unsigned NumXMMRegs,
805 unsigned &ObjSize, unsigned &ObjIntRegs,
806 unsigned &ObjXMMRegs) {
807 ObjSize = 0;
808 ObjIntRegs = 0;
809 ObjXMMRegs = 0;
810
811 switch (ObjectVT) {
812 default: assert(0 && "Unhandled argument type!");
813 case MVT::i8:
814 case MVT::i16:
815 case MVT::i32:
816 case MVT::i64:
817 if (NumIntRegs < 6)
818 ObjIntRegs = 1;
819 else {
820 switch (ObjectVT) {
821 default: break;
822 case MVT::i8: ObjSize = 1; break;
823 case MVT::i16: ObjSize = 2; break;
824 case MVT::i32: ObjSize = 4; break;
825 case MVT::i64: ObjSize = 8; break;
826 }
827 }
828 break;
829 case MVT::f32:
830 case MVT::f64:
831 case MVT::v16i8:
832 case MVT::v8i16:
833 case MVT::v4i32:
834 case MVT::v2i64:
835 case MVT::v4f32:
836 case MVT::v2f64:
837 if (NumXMMRegs < 8)
838 ObjXMMRegs = 1;
839 else {
840 switch (ObjectVT) {
841 default: break;
842 case MVT::f32: ObjSize = 4; break;
843 case MVT::f64: ObjSize = 8; break;
844 case MVT::v16i8:
845 case MVT::v8i16:
846 case MVT::v4i32:
847 case MVT::v2i64:
848 case MVT::v4f32:
849 case MVT::v2f64: ObjSize = 16; break;
850 }
851 break;
852 }
853 }
854}
855
856SDOperand
857X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
858 unsigned NumArgs = Op.Val->getNumValues() - 1;
859 MachineFunction &MF = DAG.getMachineFunction();
860 MachineFrameInfo *MFI = MF.getFrameInfo();
861 SDOperand Root = Op.getOperand(0);
862 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
863 std::vector<SDOperand> ArgValues;
864
865 // Add DAG nodes to load the arguments... On entry to a function on the X86,
866 // the stack frame looks like this:
867 //
868 // [RSP] -- return address
869 // [RSP + 8] -- first nonreg argument (leftmost lexically)
870 // [RSP +16] -- second nonreg argument, if 1st argument is <= 8 bytes in size
871 // ...
872 //
873 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
874 unsigned NumIntRegs = 0; // Int regs used for parameter passing.
875 unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
876
877 static const unsigned GPR8ArgRegs[] = {
878 X86::DIL, X86::SIL, X86::DL, X86::CL, X86::R8B, X86::R9B
879 };
880 static const unsigned GPR16ArgRegs[] = {
881 X86::DI, X86::SI, X86::DX, X86::CX, X86::R8W, X86::R9W
882 };
883 static const unsigned GPR32ArgRegs[] = {
884 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
885 };
886 static const unsigned GPR64ArgRegs[] = {
887 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9
888 };
889 static const unsigned XMMArgRegs[] = {
890 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
891 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
892 };
893
894 for (unsigned i = 0; i < NumArgs; ++i) {
895 MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
896 unsigned ArgIncrement = 8;
897 unsigned ObjSize = 0;
898 unsigned ObjIntRegs = 0;
899 unsigned ObjXMMRegs = 0;
900
901 // FIXME: __int128 and long double support?
902 HowToPassX86_64CCCArgument(ObjectVT, NumIntRegs, NumXMMRegs,
903 ObjSize, ObjIntRegs, ObjXMMRegs);
904 if (ObjSize > 8)
905 ArgIncrement = ObjSize;
906
907 unsigned Reg = 0;
908 SDOperand ArgValue;
909 if (ObjIntRegs || ObjXMMRegs) {
910 switch (ObjectVT) {
911 default: assert(0 && "Unhandled argument type!");
912 case MVT::i8:
913 case MVT::i16:
914 case MVT::i32:
915 case MVT::i64: {
916 TargetRegisterClass *RC = NULL;
917 switch (ObjectVT) {
918 default: break;
919 case MVT::i8:
920 RC = X86::GR8RegisterClass;
921 Reg = GPR8ArgRegs[NumIntRegs];
922 break;
923 case MVT::i16:
924 RC = X86::GR16RegisterClass;
925 Reg = GPR16ArgRegs[NumIntRegs];
926 break;
927 case MVT::i32:
928 RC = X86::GR32RegisterClass;
929 Reg = GPR32ArgRegs[NumIntRegs];
930 break;
931 case MVT::i64:
932 RC = X86::GR64RegisterClass;
933 Reg = GPR64ArgRegs[NumIntRegs];
934 break;
935 }
936 Reg = AddLiveIn(MF, Reg, RC);
937 ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
938 break;
939 }
940 case MVT::f32:
941 case MVT::f64:
942 case MVT::v16i8:
943 case MVT::v8i16:
944 case MVT::v4i32:
945 case MVT::v2i64:
946 case MVT::v4f32:
947 case MVT::v2f64: {
948 TargetRegisterClass *RC= (ObjectVT == MVT::f32) ?
949 X86::FR32RegisterClass : ((ObjectVT == MVT::f64) ?
950 X86::FR64RegisterClass : X86::VR128RegisterClass);
951 Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], RC);
952 ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
953 break;
954 }
955 }
956 NumIntRegs += ObjIntRegs;
957 NumXMMRegs += ObjXMMRegs;
958 } else if (ObjSize) {
959 // XMM arguments have to be aligned on 16-byte boundary.
960 if (ObjSize == 16)
961 ArgOffset = ((ArgOffset + 15) / 16) * 16;
962 // Create the SelectionDAG nodes corresponding to a load from this
963 // parameter.
964 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
965 SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
Evan Cheng466685d2006-10-09 20:57:25 +0000966 ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +0000967 ArgOffset += ArgIncrement; // Move on to the next argument.
968 }
969
970 ArgValues.push_back(ArgValue);
971 }
972
973 // If the function takes variable number of arguments, make a frame index for
974 // the start of the first vararg value... for expansion of llvm.va_start.
975 if (isVarArg) {
976 // For X86-64, if there are vararg parameters that are passed via
977 // registers, then we must store them to their spots on the stack so they
978 // may be loaded by deferencing the result of va_next.
979 VarArgsGPOffset = NumIntRegs * 8;
980 VarArgsFPOffset = 6 * 8 + NumXMMRegs * 16;
981 VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
982 RegSaveFrameIndex = MFI->CreateStackObject(6 * 8 + 8 * 16, 16);
983
984 // Store the integer parameter registers.
985 std::vector<SDOperand> MemOps;
986 SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
987 SDOperand FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
988 DAG.getConstant(VarArgsGPOffset, getPointerTy()));
989 for (; NumIntRegs != 6; ++NumIntRegs) {
990 unsigned VReg = AddLiveIn(MF, GPR64ArgRegs[NumIntRegs],
991 X86::GR64RegisterClass);
992 SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i64);
Evan Cheng8b2794a2006-10-13 21:14:26 +0000993 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +0000994 MemOps.push_back(Store);
995 FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
996 DAG.getConstant(8, getPointerTy()));
997 }
998
999 // Now store the XMM (fp + vector) parameter registers.
1000 FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
1001 DAG.getConstant(VarArgsFPOffset, getPointerTy()));
1002 for (; NumXMMRegs != 8; ++NumXMMRegs) {
1003 unsigned VReg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
1004 X86::VR128RegisterClass);
1005 SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::v4f32);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001006 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +00001007 MemOps.push_back(Store);
1008 FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
1009 DAG.getConstant(16, getPointerTy()));
1010 }
1011 if (!MemOps.empty())
1012 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
1013 &MemOps[0], MemOps.size());
1014 }
1015
1016 ArgValues.push_back(Root);
1017
1018 ReturnAddrIndex = 0; // No return address slot generated yet.
1019 BytesToPopOnReturn = 0; // Callee pops nothing.
1020 BytesCallerReserves = ArgOffset;
1021
1022 // Return the new list of results.
1023 std::vector<MVT::ValueType> RetVTs(Op.Val->value_begin(),
1024 Op.Val->value_end());
1025 return DAG.getNode(ISD::MERGE_VALUES, RetVTs, &ArgValues[0],ArgValues.size());
1026}
1027
1028SDOperand
1029X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG) {
1030 SDOperand Chain = Op.getOperand(0);
1031 unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
1032 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1033 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1034 SDOperand Callee = Op.getOperand(4);
1035 MVT::ValueType RetVT= Op.Val->getValueType(0);
1036 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1037
1038 // Count how many bytes are to be pushed on the stack.
1039 unsigned NumBytes = 0;
1040 unsigned NumIntRegs = 0; // Int regs used for parameter passing.
1041 unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
1042
1043 static const unsigned GPR8ArgRegs[] = {
1044 X86::DIL, X86::SIL, X86::DL, X86::CL, X86::R8B, X86::R9B
1045 };
1046 static const unsigned GPR16ArgRegs[] = {
1047 X86::DI, X86::SI, X86::DX, X86::CX, X86::R8W, X86::R9W
1048 };
1049 static const unsigned GPR32ArgRegs[] = {
1050 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
1051 };
1052 static const unsigned GPR64ArgRegs[] = {
1053 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9
1054 };
1055 static const unsigned XMMArgRegs[] = {
1056 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
1057 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
1058 };
1059
1060 for (unsigned i = 0; i != NumOps; ++i) {
1061 SDOperand Arg = Op.getOperand(5+2*i);
1062 MVT::ValueType ArgVT = Arg.getValueType();
1063
1064 switch (ArgVT) {
1065 default: assert(0 && "Unknown value type!");
1066 case MVT::i8:
1067 case MVT::i16:
1068 case MVT::i32:
1069 case MVT::i64:
1070 if (NumIntRegs < 6)
1071 ++NumIntRegs;
1072 else
1073 NumBytes += 8;
1074 break;
1075 case MVT::f32:
1076 case MVT::f64:
1077 case MVT::v16i8:
1078 case MVT::v8i16:
1079 case MVT::v4i32:
1080 case MVT::v2i64:
1081 case MVT::v4f32:
1082 case MVT::v2f64:
1083 if (NumXMMRegs < 8)
1084 NumXMMRegs++;
1085 else if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
1086 NumBytes += 8;
1087 else {
1088 // XMM arguments have to be aligned on 16-byte boundary.
1089 NumBytes = ((NumBytes + 15) / 16) * 16;
1090 NumBytes += 16;
1091 }
1092 break;
1093 }
1094 }
1095
1096 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
1097
1098 // Arguments go on the stack in reverse order, as specified by the ABI.
1099 unsigned ArgOffset = 0;
1100 NumIntRegs = 0;
1101 NumXMMRegs = 0;
1102 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1103 std::vector<SDOperand> MemOpChains;
1104 SDOperand StackPtr = DAG.getRegister(X86StackPtr, getPointerTy());
1105 for (unsigned i = 0; i != NumOps; ++i) {
1106 SDOperand Arg = Op.getOperand(5+2*i);
1107 MVT::ValueType ArgVT = Arg.getValueType();
1108
1109 switch (ArgVT) {
1110 default: assert(0 && "Unexpected ValueType for argument!");
1111 case MVT::i8:
1112 case MVT::i16:
1113 case MVT::i32:
1114 case MVT::i64:
1115 if (NumIntRegs < 6) {
1116 unsigned Reg = 0;
1117 switch (ArgVT) {
1118 default: break;
1119 case MVT::i8: Reg = GPR8ArgRegs[NumIntRegs]; break;
1120 case MVT::i16: Reg = GPR16ArgRegs[NumIntRegs]; break;
1121 case MVT::i32: Reg = GPR32ArgRegs[NumIntRegs]; break;
1122 case MVT::i64: Reg = GPR64ArgRegs[NumIntRegs]; break;
1123 }
1124 RegsToPass.push_back(std::make_pair(Reg, Arg));
1125 ++NumIntRegs;
1126 } else {
1127 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
1128 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001129 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Evan Cheng25ab6902006-09-08 06:48:29 +00001130 ArgOffset += 8;
1131 }
1132 break;
1133 case MVT::f32:
1134 case MVT::f64:
1135 case MVT::v16i8:
1136 case MVT::v8i16:
1137 case MVT::v4i32:
1138 case MVT::v2i64:
1139 case MVT::v4f32:
1140 case MVT::v2f64:
1141 if (NumXMMRegs < 8) {
1142 RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg));
1143 NumXMMRegs++;
1144 } else {
1145 if (ArgVT != MVT::f32 && ArgVT != MVT::f64) {
1146 // XMM arguments have to be aligned on 16-byte boundary.
1147 ArgOffset = ((ArgOffset + 15) / 16) * 16;
1148 }
1149 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
1150 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001151 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Evan Cheng25ab6902006-09-08 06:48:29 +00001152 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
1153 ArgOffset += 8;
1154 else
1155 ArgOffset += 16;
1156 }
1157 }
1158 }
1159
1160 if (!MemOpChains.empty())
1161 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1162 &MemOpChains[0], MemOpChains.size());
1163
1164 // Build a sequence of copy-to-reg nodes chained together with token chain
1165 // and flag operands which copy the outgoing args into registers.
1166 SDOperand InFlag;
1167 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1168 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1169 InFlag);
1170 InFlag = Chain.getValue(1);
1171 }
1172
1173 if (isVarArg) {
1174 // From AMD64 ABI document:
1175 // For calls that may call functions that use varargs or stdargs
1176 // (prototype-less calls or calls to functions containing ellipsis (...) in
1177 // the declaration) %al is used as hidden argument to specify the number
1178 // of SSE registers used. The contents of %al do not need to match exactly
1179 // the number of registers, but must be an ubound on the number of SSE
1180 // registers used and is in the range 0 - 8 inclusive.
1181 Chain = DAG.getCopyToReg(Chain, X86::AL,
1182 DAG.getConstant(NumXMMRegs, MVT::i8), InFlag);
1183 InFlag = Chain.getValue(1);
1184 }
1185
1186 // If the callee is a GlobalAddress node (quite common, every direct call is)
1187 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1188 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1189 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
1190 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1191 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
1192
1193 std::vector<MVT::ValueType> NodeTys;
1194 NodeTys.push_back(MVT::Other); // Returns a chain
1195 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1196 std::vector<SDOperand> Ops;
1197 Ops.push_back(Chain);
1198 Ops.push_back(Callee);
1199
1200 // Add argument registers to the end of the list so that they are known live
1201 // into the call.
1202 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1203 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1204 RegsToPass[i].second.getValueType()));
1205
1206 if (InFlag.Val)
1207 Ops.push_back(InFlag);
1208
1209 // FIXME: Do not generate X86ISD::TAILCALL for now.
1210 Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
1211 NodeTys, &Ops[0], Ops.size());
1212 InFlag = Chain.getValue(1);
1213
1214 NodeTys.clear();
1215 NodeTys.push_back(MVT::Other); // Returns a chain
1216 if (RetVT != MVT::Other)
1217 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1218 Ops.clear();
1219 Ops.push_back(Chain);
1220 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
1221 Ops.push_back(DAG.getConstant(0, getPointerTy()));
1222 Ops.push_back(InFlag);
1223 Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
1224 if (RetVT != MVT::Other)
1225 InFlag = Chain.getValue(1);
1226
1227 std::vector<SDOperand> ResultVals;
1228 NodeTys.clear();
1229 switch (RetVT) {
1230 default: assert(0 && "Unknown value type to return!");
1231 case MVT::Other: break;
1232 case MVT::i8:
1233 Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1);
1234 ResultVals.push_back(Chain.getValue(0));
1235 NodeTys.push_back(MVT::i8);
1236 break;
1237 case MVT::i16:
1238 Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1);
1239 ResultVals.push_back(Chain.getValue(0));
1240 NodeTys.push_back(MVT::i16);
1241 break;
1242 case MVT::i32:
1243 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
1244 ResultVals.push_back(Chain.getValue(0));
1245 NodeTys.push_back(MVT::i32);
1246 break;
1247 case MVT::i64:
1248 if (Op.Val->getValueType(1) == MVT::i64) {
1249 // FIXME: __int128 support?
1250 Chain = DAG.getCopyFromReg(Chain, X86::RAX, MVT::i64, InFlag).getValue(1);
1251 ResultVals.push_back(Chain.getValue(0));
1252 Chain = DAG.getCopyFromReg(Chain, X86::RDX, MVT::i64,
1253 Chain.getValue(2)).getValue(1);
1254 ResultVals.push_back(Chain.getValue(0));
1255 NodeTys.push_back(MVT::i64);
1256 } else {
1257 Chain = DAG.getCopyFromReg(Chain, X86::RAX, MVT::i64, InFlag).getValue(1);
1258 ResultVals.push_back(Chain.getValue(0));
1259 }
1260 NodeTys.push_back(MVT::i64);
1261 break;
1262 case MVT::f32:
1263 case MVT::f64:
1264 case MVT::v16i8:
1265 case MVT::v8i16:
1266 case MVT::v4i32:
1267 case MVT::v2i64:
1268 case MVT::v4f32:
1269 case MVT::v2f64:
1270 // FIXME: long double support?
1271 Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1);
1272 ResultVals.push_back(Chain.getValue(0));
1273 NodeTys.push_back(RetVT);
1274 break;
1275 }
1276
1277 // If the function returns void, just return the chain.
1278 if (ResultVals.empty())
1279 return Chain;
1280
1281 // Otherwise, merge everything together with a MERGE_VALUES node.
1282 NodeTys.push_back(MVT::Other);
1283 ResultVals.push_back(Chain);
1284 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1285 &ResultVals[0], ResultVals.size());
1286 return Res.getValue(Op.ResNo);
1287}
1288
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001289//===----------------------------------------------------------------------===//
1290// Fast Calling Convention implementation
1291//===----------------------------------------------------------------------===//
1292//
1293// The X86 'fast' calling convention passes up to two integer arguments in
1294// registers (an appropriate portion of EAX/EDX), passes arguments in C order,
1295// and requires that the callee pop its arguments off the stack (allowing proper
1296// tail calls), and has the same return value conventions as C calling convs.
1297//
1298// This calling convention always arranges for the callee pop value to be 8n+4
1299// bytes, which is needed for tail recursion elimination and stack alignment
1300// reasons.
1301//
1302// Note that this can be enhanced in the future to pass fp vals in registers
1303// (when we have a global fp allocator) and do other tricks.
1304//
1305
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001306/// HowToPassFastCCArgument - Returns how an formal argument of the specified
1307/// type should be passed. If it is through stack, returns the size of the stack
Evan Chengf9ff7c52006-05-26 18:25:43 +00001308/// slot; if it is through integer or XMM register, returns the number of
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001309/// integer or XMM registers are needed.
Evan Chengeda65fa2006-04-27 01:32:22 +00001310static void
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001311HowToPassFastCCArgument(MVT::ValueType ObjectVT,
1312 unsigned NumIntRegs, unsigned NumXMMRegs,
1313 unsigned &ObjSize, unsigned &ObjIntRegs,
1314 unsigned &ObjXMMRegs) {
Evan Chengeda65fa2006-04-27 01:32:22 +00001315 ObjSize = 0;
Evan Cheng26755342006-06-01 05:53:27 +00001316 ObjIntRegs = 0;
1317 ObjXMMRegs = 0;
Evan Chengeda65fa2006-04-27 01:32:22 +00001318
1319 switch (ObjectVT) {
1320 default: assert(0 && "Unhandled argument type!");
Evan Chengeda65fa2006-04-27 01:32:22 +00001321 case MVT::i8:
Evan Chengda08d2c2006-06-24 08:36:10 +00001322#if FASTCC_NUM_INT_ARGS_INREGS > 0
Evan Chengeda65fa2006-04-27 01:32:22 +00001323 if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
Evan Cheng85e38002006-04-27 05:35:28 +00001324 ObjIntRegs = 1;
Evan Chengeda65fa2006-04-27 01:32:22 +00001325 else
Evan Chengda08d2c2006-06-24 08:36:10 +00001326#endif
Evan Chengeda65fa2006-04-27 01:32:22 +00001327 ObjSize = 1;
1328 break;
1329 case MVT::i16:
Evan Chengda08d2c2006-06-24 08:36:10 +00001330#if FASTCC_NUM_INT_ARGS_INREGS > 0
Evan Chengeda65fa2006-04-27 01:32:22 +00001331 if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
Evan Cheng85e38002006-04-27 05:35:28 +00001332 ObjIntRegs = 1;
Evan Chengeda65fa2006-04-27 01:32:22 +00001333 else
Evan Chengda08d2c2006-06-24 08:36:10 +00001334#endif
Evan Chengeda65fa2006-04-27 01:32:22 +00001335 ObjSize = 2;
1336 break;
1337 case MVT::i32:
Evan Chengda08d2c2006-06-24 08:36:10 +00001338#if FASTCC_NUM_INT_ARGS_INREGS > 0
Evan Chengeda65fa2006-04-27 01:32:22 +00001339 if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS)
Evan Cheng85e38002006-04-27 05:35:28 +00001340 ObjIntRegs = 1;
Evan Chengeda65fa2006-04-27 01:32:22 +00001341 else
Evan Chengda08d2c2006-06-24 08:36:10 +00001342#endif
Evan Chengeda65fa2006-04-27 01:32:22 +00001343 ObjSize = 4;
1344 break;
1345 case MVT::i64:
Evan Chengda08d2c2006-06-24 08:36:10 +00001346#if FASTCC_NUM_INT_ARGS_INREGS > 0
Evan Chengeda65fa2006-04-27 01:32:22 +00001347 if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
Evan Cheng85e38002006-04-27 05:35:28 +00001348 ObjIntRegs = 2;
Evan Chengeda65fa2006-04-27 01:32:22 +00001349 } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
Evan Cheng85e38002006-04-27 05:35:28 +00001350 ObjIntRegs = 1;
Evan Chengeda65fa2006-04-27 01:32:22 +00001351 ObjSize = 4;
1352 } else
Evan Chengda08d2c2006-06-24 08:36:10 +00001353#endif
Evan Chengeda65fa2006-04-27 01:32:22 +00001354 ObjSize = 8;
1355 case MVT::f32:
1356 ObjSize = 4;
1357 break;
1358 case MVT::f64:
1359 ObjSize = 8;
1360 break;
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001361 case MVT::v16i8:
1362 case MVT::v8i16:
1363 case MVT::v4i32:
1364 case MVT::v2i64:
1365 case MVT::v4f32:
1366 case MVT::v2f64:
Evan Cheng1d6a9b32006-05-26 19:22:06 +00001367 if (NumXMMRegs < 4)
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001368 ObjXMMRegs = 1;
1369 else
1370 ObjSize = 16;
1371 break;
Evan Chengeda65fa2006-04-27 01:32:22 +00001372 }
1373}
1374
Evan Cheng25caf632006-05-23 21:06:34 +00001375SDOperand
1376X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) {
1377 unsigned NumArgs = Op.Val->getNumValues()-1;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001378 MachineFunction &MF = DAG.getMachineFunction();
1379 MachineFrameInfo *MFI = MF.getFrameInfo();
Evan Cheng25caf632006-05-23 21:06:34 +00001380 SDOperand Root = Op.getOperand(0);
1381 std::vector<SDOperand> ArgValues;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001382
Evan Chengeda65fa2006-04-27 01:32:22 +00001383 // Add DAG nodes to load the arguments... On entry to a function the stack
1384 // frame looks like this:
1385 //
1386 // [ESP] -- return address
1387 // [ESP + 4] -- first nonreg argument (leftmost lexically)
Evan Chengf9d62dc2006-05-26 18:37:16 +00001388 // [ESP + 8] -- second nonreg argument, if 1st argument is <= 4 bytes in size
Evan Chengeda65fa2006-04-27 01:32:22 +00001389 // ...
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001390 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
1391
1392 // Keep track of the number of integer regs passed so far. This can be either
1393 // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
1394 // used).
1395 unsigned NumIntRegs = 0;
Evan Cheng2fdd95e2006-04-27 08:31:10 +00001396 unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
Evan Cheng32fe1032006-05-25 00:59:30 +00001397
1398 static const unsigned XMMArgRegs[] = {
Evan Cheng1d6a9b32006-05-26 19:22:06 +00001399 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
Evan Cheng32fe1032006-05-25 00:59:30 +00001400 };
Chris Lattner1c636e92006-03-17 05:10:20 +00001401
Evan Cheng1bc78042006-04-26 01:20:17 +00001402 for (unsigned i = 0; i < NumArgs; ++i) {
Evan Cheng25caf632006-05-23 21:06:34 +00001403 MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
1404 unsigned ArgIncrement = 4;
1405 unsigned ObjSize = 0;
1406 unsigned ObjIntRegs = 0;
1407 unsigned ObjXMMRegs = 0;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001408
Evan Cheng25caf632006-05-23 21:06:34 +00001409 HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs,
1410 ObjSize, ObjIntRegs, ObjXMMRegs);
Evan Cheng052fb512006-05-26 18:39:59 +00001411 if (ObjSize > 4)
Evan Cheng25caf632006-05-23 21:06:34 +00001412 ArgIncrement = ObjSize;
Evan Chengeda65fa2006-04-27 01:32:22 +00001413
Evan Cheng04b25622006-06-01 00:30:39 +00001414 unsigned Reg = 0;
Evan Cheng25caf632006-05-23 21:06:34 +00001415 SDOperand ArgValue;
1416 if (ObjIntRegs || ObjXMMRegs) {
1417 switch (ObjectVT) {
1418 default: assert(0 && "Unhandled argument type!");
Evan Cheng25caf632006-05-23 21:06:34 +00001419 case MVT::i8:
1420 Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
1421 X86::GR8RegisterClass);
1422 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i8);
1423 break;
1424 case MVT::i16:
1425 Reg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
1426 X86::GR16RegisterClass);
1427 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i16);
1428 break;
1429 case MVT::i32:
1430 Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
1431 X86::GR32RegisterClass);
1432 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32);
1433 break;
1434 case MVT::i64:
1435 Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
1436 X86::GR32RegisterClass);
1437 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32);
1438 if (ObjIntRegs == 2) {
1439 Reg = AddLiveIn(MF, X86::EDX, X86::GR32RegisterClass);
1440 SDOperand ArgValue2 = DAG.getCopyFromReg(Root, Reg, MVT::i32);
1441 ArgValue= DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
Evan Cheng85e38002006-04-27 05:35:28 +00001442 }
Evan Cheng25caf632006-05-23 21:06:34 +00001443 break;
1444 case MVT::v16i8:
1445 case MVT::v8i16:
1446 case MVT::v4i32:
1447 case MVT::v2i64:
1448 case MVT::v4f32:
1449 case MVT::v2f64:
1450 Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass);
1451 ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT);
1452 break;
Evan Chengeda65fa2006-04-27 01:32:22 +00001453 }
Evan Cheng25caf632006-05-23 21:06:34 +00001454 NumIntRegs += ObjIntRegs;
1455 NumXMMRegs += ObjXMMRegs;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001456 }
Evan Cheng25caf632006-05-23 21:06:34 +00001457
1458 if (ObjSize) {
Evan Cheng3fddf242006-05-26 20:37:47 +00001459 // XMM arguments have to be aligned on 16-byte boundary.
1460 if (ObjSize == 16)
1461 ArgOffset = ((ArgOffset + 15) / 16) * 16;
Evan Cheng25caf632006-05-23 21:06:34 +00001462 // Create the SelectionDAG nodes corresponding to a load from this
1463 // parameter.
1464 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1465 SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
1466 if (ObjectVT == MVT::i64 && ObjIntRegs) {
1467 SDOperand ArgValue2 = DAG.getLoad(Op.Val->getValueType(i), Root, FIN,
Evan Cheng466685d2006-10-09 20:57:25 +00001468 NULL, 0);
Evan Cheng25caf632006-05-23 21:06:34 +00001469 ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
1470 } else
Evan Cheng466685d2006-10-09 20:57:25 +00001471 ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
Evan Cheng25caf632006-05-23 21:06:34 +00001472 ArgOffset += ArgIncrement; // Move on to the next argument.
1473 }
1474
1475 ArgValues.push_back(ArgValue);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001476 }
1477
Evan Cheng25caf632006-05-23 21:06:34 +00001478 ArgValues.push_back(Root);
1479
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001480 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
1481 // arguments and the arguments after the retaddr has been pushed are aligned.
1482 if ((ArgOffset & 7) == 0)
1483 ArgOffset += 4;
1484
1485 VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs.
Evan Cheng25ab6902006-09-08 06:48:29 +00001486 RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001487 ReturnAddrIndex = 0; // No return address slot generated yet.
1488 BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments.
1489 BytesCallerReserves = 0;
1490
1491 // Finally, inform the code generator which regs we return values in.
Evan Cheng25caf632006-05-23 21:06:34 +00001492 switch (getValueType(MF.getFunction()->getReturnType())) {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001493 default: assert(0 && "Unknown type!");
1494 case MVT::isVoid: break;
Chris Lattner13bf6c12006-10-03 17:18:42 +00001495 case MVT::i1:
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001496 case MVT::i8:
1497 case MVT::i16:
1498 case MVT::i32:
1499 MF.addLiveOut(X86::EAX);
1500 break;
1501 case MVT::i64:
1502 MF.addLiveOut(X86::EAX);
1503 MF.addLiveOut(X86::EDX);
1504 break;
1505 case MVT::f32:
1506 case MVT::f64:
1507 MF.addLiveOut(X86::ST0);
1508 break;
Evan Cheng6b5783d2006-05-25 18:56:34 +00001509 case MVT::v16i8:
1510 case MVT::v8i16:
1511 case MVT::v4i32:
1512 case MVT::v2i64:
1513 case MVT::v4f32:
1514 case MVT::v2f64:
Evan Cheng347d5f72006-04-28 21:29:37 +00001515 MF.addLiveOut(X86::XMM0);
1516 break;
1517 }
Evan Cheng347d5f72006-04-28 21:29:37 +00001518
Evan Cheng25caf632006-05-23 21:06:34 +00001519 // Return the new list of results.
1520 std::vector<MVT::ValueType> RetVTs(Op.Val->value_begin(),
1521 Op.Val->value_end());
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001522 return DAG.getNode(ISD::MERGE_VALUES, RetVTs, &ArgValues[0],ArgValues.size());
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001523}
1524
Chris Lattnere87e1152006-09-26 03:57:53 +00001525SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG,
1526 bool isFastCall) {
Evan Cheng32fe1032006-05-25 00:59:30 +00001527 SDOperand Chain = Op.getOperand(0);
1528 unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
1529 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1530 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1531 SDOperand Callee = Op.getOperand(4);
1532 MVT::ValueType RetVT= Op.Val->getValueType(0);
1533 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1534
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001535 // Count how many bytes are to be pushed on the stack.
1536 unsigned NumBytes = 0;
1537
1538 // Keep track of the number of integer regs passed so far. This can be either
1539 // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
1540 // used).
1541 unsigned NumIntRegs = 0;
Evan Cheng32fe1032006-05-25 00:59:30 +00001542 unsigned NumXMMRegs = 0; // XMM regs used for parameter passing.
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001543
Evan Cheng32fe1032006-05-25 00:59:30 +00001544 static const unsigned GPRArgRegs[][2] = {
1545 { X86::AL, X86::DL },
1546 { X86::AX, X86::DX },
1547 { X86::EAX, X86::EDX }
1548 };
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001549 static const unsigned FastCallGPRArgRegs[][2] = {
1550 { X86::CL, X86::DL },
1551 { X86::CX, X86::DX },
1552 { X86::ECX, X86::EDX }
1553 };
Evan Cheng32fe1032006-05-25 00:59:30 +00001554 static const unsigned XMMArgRegs[] = {
Evan Cheng1d6a9b32006-05-26 19:22:06 +00001555 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
Evan Cheng32fe1032006-05-25 00:59:30 +00001556 };
1557
1558 for (unsigned i = 0; i != NumOps; ++i) {
1559 SDOperand Arg = Op.getOperand(5+2*i);
1560
1561 switch (Arg.getValueType()) {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001562 default: assert(0 && "Unknown value type!");
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001563 case MVT::i8:
1564 case MVT::i16:
Nick Lewycky70084fd2006-09-21 02:08:31 +00001565 case MVT::i32: {
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001566 unsigned MaxNumIntRegs = (isFastCall ? 2 : FASTCC_NUM_INT_ARGS_INREGS);
1567 if (NumIntRegs < MaxNumIntRegs) {
1568 ++NumIntRegs;
1569 break;
1570 }
Nick Lewycky70084fd2006-09-21 02:08:31 +00001571 } // Fall through
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001572 case MVT::f32:
1573 NumBytes += 4;
1574 break;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001575 case MVT::f64:
1576 NumBytes += 8;
1577 break;
Evan Cheng32fe1032006-05-25 00:59:30 +00001578 case MVT::v16i8:
1579 case MVT::v8i16:
1580 case MVT::v4i32:
1581 case MVT::v2i64:
1582 case MVT::v4f32:
Evan Cheng6b5783d2006-05-25 18:56:34 +00001583 case MVT::v2f64:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001584 if (isFastCall) {
1585 assert(0 && "Unknown value type!");
1586 } else {
1587 if (NumXMMRegs < 4)
1588 NumXMMRegs++;
1589 else {
1590 // XMM arguments have to be aligned on 16-byte boundary.
1591 NumBytes = ((NumBytes + 15) / 16) * 16;
1592 NumBytes += 16;
1593 }
1594 }
1595 break;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001596 }
Evan Cheng32fe1032006-05-25 00:59:30 +00001597 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001598
1599 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
1600 // arguments and the arguments after the retaddr has been pushed are aligned.
1601 if ((NumBytes & 7) == 0)
1602 NumBytes += 4;
1603
Chris Lattner94dd2922006-02-13 09:00:43 +00001604 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001605
1606 // Arguments go on the stack in reverse order, as specified by the ABI.
1607 unsigned ArgOffset = 0;
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001608 NumIntRegs = 0;
Evan Cheng32fe1032006-05-25 00:59:30 +00001609 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1610 std::vector<SDOperand> MemOpChains;
Evan Cheng25ab6902006-09-08 06:48:29 +00001611 SDOperand StackPtr = DAG.getRegister(X86StackPtr, getPointerTy());
Evan Cheng32fe1032006-05-25 00:59:30 +00001612 for (unsigned i = 0; i != NumOps; ++i) {
1613 SDOperand Arg = Op.getOperand(5+2*i);
1614
1615 switch (Arg.getValueType()) {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001616 default: assert(0 && "Unexpected ValueType for argument!");
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001617 case MVT::i8:
1618 case MVT::i16:
Nick Lewycky70084fd2006-09-21 02:08:31 +00001619 case MVT::i32: {
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001620 unsigned MaxNumIntRegs = (isFastCall ? 2 : FASTCC_NUM_INT_ARGS_INREGS);
1621 if (NumIntRegs < MaxNumIntRegs) {
1622 RegsToPass.push_back(
1623 std::make_pair(GPRArgRegs[Arg.getValueType()-MVT::i8][NumIntRegs],
1624 Arg));
1625 ++NumIntRegs;
1626 break;
1627 }
Nick Lewycky70084fd2006-09-21 02:08:31 +00001628 } // Fall through
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001629 case MVT::f32: {
1630 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
Evan Cheng32fe1032006-05-25 00:59:30 +00001631 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001632 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001633 ArgOffset += 4;
1634 break;
1635 }
Evan Cheng32fe1032006-05-25 00:59:30 +00001636 case MVT::f64: {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001637 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
Evan Cheng32fe1032006-05-25 00:59:30 +00001638 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001639 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001640 ArgOffset += 8;
1641 break;
1642 }
Evan Cheng32fe1032006-05-25 00:59:30 +00001643 case MVT::v16i8:
1644 case MVT::v8i16:
1645 case MVT::v4i32:
1646 case MVT::v2i64:
1647 case MVT::v4f32:
Evan Cheng6b5783d2006-05-25 18:56:34 +00001648 case MVT::v2f64:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001649 if (isFastCall) {
1650 assert(0 && "Unexpected ValueType for argument!");
1651 } else {
1652 if (NumXMMRegs < 4) {
1653 RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg));
1654 NumXMMRegs++;
1655 } else {
1656 // XMM arguments have to be aligned on 16-byte boundary.
1657 ArgOffset = ((ArgOffset + 15) / 16) * 16;
1658 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
1659 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001660 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001661 ArgOffset += 16;
1662 }
1663 }
1664 break;
Evan Cheng32fe1032006-05-25 00:59:30 +00001665 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001666 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001667
Evan Cheng32fe1032006-05-25 00:59:30 +00001668 if (!MemOpChains.empty())
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001669 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1670 &MemOpChains[0], MemOpChains.size());
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001671
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001672 // Build a sequence of copy-to-reg nodes chained together with token chain
1673 // and flag operands which copy the outgoing args into registers.
1674 SDOperand InFlag;
Evan Cheng32fe1032006-05-25 00:59:30 +00001675 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1676 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1677 InFlag);
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001678 InFlag = Chain.getValue(1);
1679 }
1680
Evan Cheng32fe1032006-05-25 00:59:30 +00001681 // If the callee is a GlobalAddress node (quite common, every direct call is)
1682 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1683 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1684 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
1685 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1686 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
1687
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001688 std::vector<MVT::ValueType> NodeTys;
1689 NodeTys.push_back(MVT::Other); // Returns a chain
1690 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1691 std::vector<SDOperand> Ops;
1692 Ops.push_back(Chain);
1693 Ops.push_back(Callee);
Evan Chengb69d1132006-06-14 18:17:40 +00001694
1695 // Add argument registers to the end of the list so that they are known live
1696 // into the call.
1697 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1698 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1699 RegsToPass[i].second.getValueType()));
1700
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001701 if (InFlag.Val)
1702 Ops.push_back(InFlag);
1703
1704 // FIXME: Do not generate X86ISD::TAILCALL for now.
Chris Lattner8c0c10c2006-05-16 06:45:34 +00001705 Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001706 NodeTys, &Ops[0], Ops.size());
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001707 InFlag = Chain.getValue(1);
1708
1709 NodeTys.clear();
1710 NodeTys.push_back(MVT::Other); // Returns a chain
Evan Cheng32fe1032006-05-25 00:59:30 +00001711 if (RetVT != MVT::Other)
1712 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001713 Ops.clear();
1714 Ops.push_back(Chain);
Evan Cheng32fe1032006-05-25 00:59:30 +00001715 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
1716 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001717 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001718 Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
Evan Cheng32fe1032006-05-25 00:59:30 +00001719 if (RetVT != MVT::Other)
1720 InFlag = Chain.getValue(1);
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001721
Evan Cheng32fe1032006-05-25 00:59:30 +00001722 std::vector<SDOperand> ResultVals;
1723 NodeTys.clear();
1724 switch (RetVT) {
1725 default: assert(0 && "Unknown value type to return!");
1726 case MVT::Other: break;
1727 case MVT::i8:
1728 Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1);
1729 ResultVals.push_back(Chain.getValue(0));
1730 NodeTys.push_back(MVT::i8);
1731 break;
1732 case MVT::i16:
1733 Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1);
1734 ResultVals.push_back(Chain.getValue(0));
1735 NodeTys.push_back(MVT::i16);
1736 break;
1737 case MVT::i32:
1738 if (Op.Val->getValueType(1) == MVT::i32) {
1739 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
1740 ResultVals.push_back(Chain.getValue(0));
1741 Chain = DAG.getCopyFromReg(Chain, X86::EDX, MVT::i32,
1742 Chain.getValue(2)).getValue(1);
1743 ResultVals.push_back(Chain.getValue(0));
1744 NodeTys.push_back(MVT::i32);
1745 } else {
1746 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
1747 ResultVals.push_back(Chain.getValue(0));
Evan Chengd9558e02006-01-06 00:43:03 +00001748 }
Evan Cheng32fe1032006-05-25 00:59:30 +00001749 NodeTys.push_back(MVT::i32);
1750 break;
1751 case MVT::v16i8:
1752 case MVT::v8i16:
1753 case MVT::v4i32:
1754 case MVT::v2i64:
1755 case MVT::v4f32:
1756 case MVT::v2f64:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001757 if (isFastCall) {
1758 assert(0 && "Unknown value type to return!");
1759 } else {
1760 Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1);
1761 ResultVals.push_back(Chain.getValue(0));
1762 NodeTys.push_back(RetVT);
1763 }
1764 break;
Evan Cheng32fe1032006-05-25 00:59:30 +00001765 case MVT::f32:
1766 case MVT::f64: {
1767 std::vector<MVT::ValueType> Tys;
1768 Tys.push_back(MVT::f64);
1769 Tys.push_back(MVT::Other);
1770 Tys.push_back(MVT::Flag);
1771 std::vector<SDOperand> Ops;
1772 Ops.push_back(Chain);
1773 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001774 SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys,
1775 &Ops[0], Ops.size());
Evan Cheng32fe1032006-05-25 00:59:30 +00001776 Chain = RetVal.getValue(1);
1777 InFlag = RetVal.getValue(2);
1778 if (X86ScalarSSE) {
1779 // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
1780 // shouldn't be necessary except that RFP cannot be live across
1781 // multiple blocks. When stackifier is fixed, they can be uncoupled.
1782 MachineFunction &MF = DAG.getMachineFunction();
1783 int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
1784 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
1785 Tys.clear();
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001786 Tys.push_back(MVT::Other);
Evan Cheng32fe1032006-05-25 00:59:30 +00001787 Ops.clear();
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001788 Ops.push_back(Chain);
Evan Cheng32fe1032006-05-25 00:59:30 +00001789 Ops.push_back(RetVal);
1790 Ops.push_back(StackSlot);
1791 Ops.push_back(DAG.getValueType(RetVT));
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001792 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001793 Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
Evan Cheng466685d2006-10-09 20:57:25 +00001794 RetVal = DAG.getLoad(RetVT, Chain, StackSlot, NULL, 0);
Evan Cheng32fe1032006-05-25 00:59:30 +00001795 Chain = RetVal.getValue(1);
1796 }
Evan Chengd9558e02006-01-06 00:43:03 +00001797
Evan Cheng32fe1032006-05-25 00:59:30 +00001798 if (RetVT == MVT::f32 && !X86ScalarSSE)
1799 // FIXME: we would really like to remember that this FP_ROUND
1800 // operation is okay to eliminate if we allow excess FP precision.
1801 RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
1802 ResultVals.push_back(RetVal);
1803 NodeTys.push_back(RetVT);
1804 break;
1805 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001806 }
Nate Begeman4c5dcf52006-02-17 00:03:04 +00001807
Evan Cheng32fe1032006-05-25 00:59:30 +00001808
1809 // If the function returns void, just return the chain.
1810 if (ResultVals.empty())
1811 return Chain;
1812
1813 // Otherwise, merge everything together with a MERGE_VALUES node.
1814 NodeTys.push_back(MVT::Other);
1815 ResultVals.push_back(Chain);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00001816 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1817 &ResultVals[0], ResultVals.size());
Evan Cheng32fe1032006-05-25 00:59:30 +00001818 return Res.getValue(Op.ResNo);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00001819}
1820
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001821//===----------------------------------------------------------------------===//
1822// StdCall Calling Convention implementation
1823//===----------------------------------------------------------------------===//
1824// StdCall calling convention seems to be standard for many Windows' API
1825// routines and around. It differs from C calling convention just a little:
1826// callee should clean up the stack, not caller. Symbols should be also
1827// decorated in some fancy way :) It doesn't support any vector arguments.
1828
1829/// HowToPassStdCallCCArgument - Returns how an formal argument of the specified
1830/// type should be passed. Returns the size of the stack slot
1831static void
1832HowToPassStdCallCCArgument(MVT::ValueType ObjectVT, unsigned &ObjSize) {
1833 switch (ObjectVT) {
1834 default: assert(0 && "Unhandled argument type!");
1835 case MVT::i8: ObjSize = 1; break;
1836 case MVT::i16: ObjSize = 2; break;
1837 case MVT::i32: ObjSize = 4; break;
1838 case MVT::i64: ObjSize = 8; break;
1839 case MVT::f32: ObjSize = 4; break;
1840 case MVT::f64: ObjSize = 8; break;
1841 }
1842}
1843
1844SDOperand X86TargetLowering::LowerStdCallCCArguments(SDOperand Op,
1845 SelectionDAG &DAG) {
1846 unsigned NumArgs = Op.Val->getNumValues() - 1;
1847 MachineFunction &MF = DAG.getMachineFunction();
1848 MachineFrameInfo *MFI = MF.getFrameInfo();
1849 SDOperand Root = Op.getOperand(0);
1850 std::vector<SDOperand> ArgValues;
1851
1852 // Add DAG nodes to load the arguments... On entry to a function on the X86,
1853 // the stack frame looks like this:
1854 //
1855 // [ESP] -- return address
1856 // [ESP + 4] -- first argument (leftmost lexically)
1857 // [ESP + 8] -- second argument, if first argument is <= 4 bytes in size
1858 // ...
1859 //
1860 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
1861 for (unsigned i = 0; i < NumArgs; ++i) {
1862 MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
1863 unsigned ArgIncrement = 4;
1864 unsigned ObjSize = 0;
1865 HowToPassStdCallCCArgument(ObjectVT, ObjSize);
1866 if (ObjSize > 4)
1867 ArgIncrement = ObjSize;
1868
1869 SDOperand ArgValue;
1870 // Create the frame index object for this incoming parameter...
1871 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1872 SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
Evan Cheng466685d2006-10-09 20:57:25 +00001873 ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001874 ArgValues.push_back(ArgValue);
1875 ArgOffset += ArgIncrement; // Move on to the next argument...
1876 }
1877
1878 ArgValues.push_back(Root);
1879
1880 // If the function takes variable number of arguments, make a frame index for
1881 // the start of the first vararg value... for expansion of llvm.va_start.
1882 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1883 if (isVarArg) {
1884 BytesToPopOnReturn = 0; // Callee pops nothing.
1885 BytesCallerReserves = ArgOffset;
1886 VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
1887 } else {
1888 BytesToPopOnReturn = ArgOffset; // Callee pops everything..
1889 BytesCallerReserves = 0;
1890 }
1891 RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
1892 ReturnAddrIndex = 0; // No return address slot generated yet.
1893
1894 MF.getInfo<X86FunctionInfo>()->setBytesToPopOnReturn(BytesToPopOnReturn);
1895
1896 // Return the new list of results.
1897 std::vector<MVT::ValueType> RetVTs(Op.Val->value_begin(),
1898 Op.Val->value_end());
1899 return DAG.getNode(ISD::MERGE_VALUES, RetVTs, &ArgValues[0],ArgValues.size());
1900}
1901
1902
1903SDOperand X86TargetLowering::LowerStdCallCCCallTo(SDOperand Op,
1904 SelectionDAG &DAG) {
1905 SDOperand Chain = Op.getOperand(0);
1906 unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
1907 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1908 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1909 SDOperand Callee = Op.getOperand(4);
1910 MVT::ValueType RetVT= Op.Val->getValueType(0);
1911 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1912
1913 // Count how many bytes are to be pushed on the stack.
1914 unsigned NumBytes = 0;
1915 for (unsigned i = 0; i != NumOps; ++i) {
1916 SDOperand Arg = Op.getOperand(5+2*i);
1917
1918 switch (Arg.getValueType()) {
1919 default: assert(0 && "Unexpected ValueType for argument!");
1920 case MVT::i8:
1921 case MVT::i16:
1922 case MVT::i32:
1923 case MVT::f32:
1924 NumBytes += 4;
1925 break;
1926 case MVT::i64:
1927 case MVT::f64:
1928 NumBytes += 8;
1929 break;
1930 }
1931 }
1932
1933 Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
1934
1935 // Arguments go on the stack in reverse order, as specified by the ABI.
1936 unsigned ArgOffset = 0;
1937 std::vector<SDOperand> MemOpChains;
1938 SDOperand StackPtr = DAG.getRegister(X86StackPtr, getPointerTy());
1939 for (unsigned i = 0; i != NumOps; ++i) {
1940 SDOperand Arg = Op.getOperand(5+2*i);
1941
1942 switch (Arg.getValueType()) {
1943 default: assert(0 && "Unexpected ValueType for argument!");
1944 case MVT::i8:
1945 case MVT::i16: {
1946 // Promote the integer to 32 bits. If the input type is signed use a
1947 // sign extend, otherwise use a zero extend.
1948 unsigned ExtOp =
1949 dyn_cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue() ?
1950 ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
1951 Arg = DAG.getNode(ExtOp, MVT::i32, Arg);
1952 }
1953 // Fallthrough
1954
1955 case MVT::i32:
1956 case MVT::f32: {
1957 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
1958 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001959 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001960 ArgOffset += 4;
1961 break;
1962 }
1963 case MVT::i64:
1964 case MVT::f64: {
1965 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
1966 PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
Evan Cheng8b2794a2006-10-13 21:14:26 +00001967 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Anton Korobeynikovf8248682006-09-20 22:03:51 +00001968 ArgOffset += 8;
1969 break;
1970 }
1971 }
1972 }
1973
1974 if (!MemOpChains.empty())
1975 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1976 &MemOpChains[0], MemOpChains.size());
1977
1978 // If the callee is a GlobalAddress node (quite common, every direct call is)
1979 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
1980 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1981 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
1982 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1983 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
1984
1985 std::vector<MVT::ValueType> NodeTys;
1986 NodeTys.push_back(MVT::Other); // Returns a chain
1987 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1988 std::vector<SDOperand> Ops;
1989 Ops.push_back(Chain);
1990 Ops.push_back(Callee);
1991
1992 Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
1993 NodeTys, &Ops[0], Ops.size());
1994 SDOperand InFlag = Chain.getValue(1);
1995
1996 // Create the CALLSEQ_END node.
1997 unsigned NumBytesForCalleeToPush;
1998
1999 if (isVarArg) {
2000 NumBytesForCalleeToPush = 0;
2001 } else {
2002 NumBytesForCalleeToPush = NumBytes;
2003 }
2004
2005 NodeTys.clear();
2006 NodeTys.push_back(MVT::Other); // Returns a chain
2007 if (RetVT != MVT::Other)
2008 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
2009 Ops.clear();
2010 Ops.push_back(Chain);
2011 Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
2012 Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy()));
2013 Ops.push_back(InFlag);
2014 Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
2015 if (RetVT != MVT::Other)
2016 InFlag = Chain.getValue(1);
2017
2018 std::vector<SDOperand> ResultVals;
2019 NodeTys.clear();
2020 switch (RetVT) {
2021 default: assert(0 && "Unknown value type to return!");
2022 case MVT::Other: break;
2023 case MVT::i8:
2024 Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1);
2025 ResultVals.push_back(Chain.getValue(0));
2026 NodeTys.push_back(MVT::i8);
2027 break;
2028 case MVT::i16:
2029 Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1);
2030 ResultVals.push_back(Chain.getValue(0));
2031 NodeTys.push_back(MVT::i16);
2032 break;
2033 case MVT::i32:
2034 if (Op.Val->getValueType(1) == MVT::i32) {
2035 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
2036 ResultVals.push_back(Chain.getValue(0));
2037 Chain = DAG.getCopyFromReg(Chain, X86::EDX, MVT::i32,
2038 Chain.getValue(2)).getValue(1);
2039 ResultVals.push_back(Chain.getValue(0));
2040 NodeTys.push_back(MVT::i32);
2041 } else {
2042 Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1);
2043 ResultVals.push_back(Chain.getValue(0));
2044 }
2045 NodeTys.push_back(MVT::i32);
2046 break;
2047 case MVT::f32:
2048 case MVT::f64: {
2049 std::vector<MVT::ValueType> Tys;
2050 Tys.push_back(MVT::f64);
2051 Tys.push_back(MVT::Other);
2052 Tys.push_back(MVT::Flag);
2053 std::vector<SDOperand> Ops;
2054 Ops.push_back(Chain);
2055 Ops.push_back(InFlag);
2056 SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys,
2057 &Ops[0], Ops.size());
2058 Chain = RetVal.getValue(1);
2059 InFlag = RetVal.getValue(2);
2060 if (X86ScalarSSE) {
2061 // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
2062 // shouldn't be necessary except that RFP cannot be live across
2063 // multiple blocks. When stackifier is fixed, they can be uncoupled.
2064 MachineFunction &MF = DAG.getMachineFunction();
2065 int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
2066 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
2067 Tys.clear();
2068 Tys.push_back(MVT::Other);
2069 Ops.clear();
2070 Ops.push_back(Chain);
2071 Ops.push_back(RetVal);
2072 Ops.push_back(StackSlot);
2073 Ops.push_back(DAG.getValueType(RetVT));
2074 Ops.push_back(InFlag);
2075 Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
Evan Cheng466685d2006-10-09 20:57:25 +00002076 RetVal = DAG.getLoad(RetVT, Chain, StackSlot, NULL, 0);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00002077 Chain = RetVal.getValue(1);
2078 }
2079
2080 if (RetVT == MVT::f32 && !X86ScalarSSE)
2081 // FIXME: we would really like to remember that this FP_ROUND
2082 // operation is okay to eliminate if we allow excess FP precision.
2083 RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
2084 ResultVals.push_back(RetVal);
2085 NodeTys.push_back(RetVT);
2086 break;
2087 }
2088 }
2089
2090 // If the function returns void, just return the chain.
2091 if (ResultVals.empty())
2092 return Chain;
2093
2094 // Otherwise, merge everything together with a MERGE_VALUES node.
2095 NodeTys.push_back(MVT::Other);
2096 ResultVals.push_back(Chain);
2097 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
2098 &ResultVals[0], ResultVals.size());
2099 return Res.getValue(Op.ResNo);
2100}
2101
2102//===----------------------------------------------------------------------===//
2103// FastCall Calling Convention implementation
2104//===----------------------------------------------------------------------===//
2105//
2106// The X86 'fastcall' calling convention passes up to two integer arguments in
2107// registers (an appropriate portion of ECX/EDX), passes arguments in C order,
2108// and requires that the callee pop its arguments off the stack (allowing proper
2109// tail calls), and has the same return value conventions as C calling convs.
2110//
2111// This calling convention always arranges for the callee pop value to be 8n+4
2112// bytes, which is needed for tail recursion elimination and stack alignment
2113// reasons.
2114//
2115
2116/// HowToPassFastCallCCArgument - Returns how an formal argument of the
2117/// specified type should be passed. If it is through stack, returns the size of
2118/// the stack slot; if it is through integer register, returns the number of
2119/// integer registers are needed.
2120static void
2121HowToPassFastCallCCArgument(MVT::ValueType ObjectVT,
2122 unsigned NumIntRegs,
2123 unsigned &ObjSize,
2124 unsigned &ObjIntRegs)
2125{
2126 ObjSize = 0;
2127 ObjIntRegs = 0;
2128
2129 switch (ObjectVT) {
2130 default: assert(0 && "Unhandled argument type!");
2131 case MVT::i8:
2132 if (NumIntRegs < 2)
2133 ObjIntRegs = 1;
2134 else
2135 ObjSize = 1;
2136 break;
2137 case MVT::i16:
2138 if (NumIntRegs < 2)
2139 ObjIntRegs = 1;
2140 else
2141 ObjSize = 2;
2142 break;
2143 case MVT::i32:
2144 if (NumIntRegs < 2)
2145 ObjIntRegs = 1;
2146 else
2147 ObjSize = 4;
2148 break;
2149 case MVT::i64:
2150 if (NumIntRegs+2 <= 2) {
2151 ObjIntRegs = 2;
2152 } else if (NumIntRegs+1 <= 2) {
2153 ObjIntRegs = 1;
2154 ObjSize = 4;
2155 } else
2156 ObjSize = 8;
2157 case MVT::f32:
2158 ObjSize = 4;
2159 break;
2160 case MVT::f64:
2161 ObjSize = 8;
2162 break;
2163 }
2164}
2165
2166SDOperand
2167X86TargetLowering::LowerFastCallCCArguments(SDOperand Op, SelectionDAG &DAG) {
2168 unsigned NumArgs = Op.Val->getNumValues()-1;
2169 MachineFunction &MF = DAG.getMachineFunction();
2170 MachineFrameInfo *MFI = MF.getFrameInfo();
2171 SDOperand Root = Op.getOperand(0);
2172 std::vector<SDOperand> ArgValues;
2173
2174 // Add DAG nodes to load the arguments... On entry to a function the stack
2175 // frame looks like this:
2176 //
2177 // [ESP] -- return address
2178 // [ESP + 4] -- first nonreg argument (leftmost lexically)
2179 // [ESP + 8] -- second nonreg argument, if 1st argument is <= 4 bytes in size
2180 // ...
2181 unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
2182
2183 // Keep track of the number of integer regs passed so far. This can be either
2184 // 0 (neither ECX or EDX used), 1 (ECX is used) or 2 (ECX and EDX are both
2185 // used).
2186 unsigned NumIntRegs = 0;
2187
2188 for (unsigned i = 0; i < NumArgs; ++i) {
2189 MVT::ValueType ObjectVT = Op.getValue(i).getValueType();
2190 unsigned ArgIncrement = 4;
2191 unsigned ObjSize = 0;
2192 unsigned ObjIntRegs = 0;
2193
2194 HowToPassFastCallCCArgument(ObjectVT, NumIntRegs, ObjSize, ObjIntRegs);
2195 if (ObjSize > 4)
2196 ArgIncrement = ObjSize;
2197
2198 unsigned Reg = 0;
2199 SDOperand ArgValue;
2200 if (ObjIntRegs) {
2201 switch (ObjectVT) {
2202 default: assert(0 && "Unhandled argument type!");
2203 case MVT::i8:
2204 Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::CL,
2205 X86::GR8RegisterClass);
2206 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i8);
2207 break;
2208 case MVT::i16:
2209 Reg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::CX,
2210 X86::GR16RegisterClass);
2211 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i16);
2212 break;
2213 case MVT::i32:
2214 Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::ECX,
2215 X86::GR32RegisterClass);
2216 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32);
2217 break;
2218 case MVT::i64:
2219 Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::ECX,
2220 X86::GR32RegisterClass);
2221 ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32);
2222 if (ObjIntRegs == 2) {
2223 Reg = AddLiveIn(MF, X86::EDX, X86::GR32RegisterClass);
2224 SDOperand ArgValue2 = DAG.getCopyFromReg(Root, Reg, MVT::i32);
2225 ArgValue= DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
2226 }
2227 break;
2228 }
2229
2230 NumIntRegs += ObjIntRegs;
2231 }
2232
2233 if (ObjSize) {
2234 // Create the SelectionDAG nodes corresponding to a load from this
2235 // parameter.
2236 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
2237 SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
2238 if (ObjectVT == MVT::i64 && ObjIntRegs) {
2239 SDOperand ArgValue2 = DAG.getLoad(Op.Val->getValueType(i), Root, FIN,
Evan Cheng466685d2006-10-09 20:57:25 +00002240 NULL, 0);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00002241 ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
2242 } else
Evan Cheng466685d2006-10-09 20:57:25 +00002243 ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, NULL, 0);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00002244 ArgOffset += ArgIncrement; // Move on to the next argument.
2245 }
2246
2247 ArgValues.push_back(ArgValue);
2248 }
2249
2250 ArgValues.push_back(Root);
2251
2252 // Make sure the instruction takes 8n+4 bytes to make sure the start of the
2253 // arguments and the arguments after the retaddr has been pushed are aligned.
2254 if ((ArgOffset & 7) == 0)
2255 ArgOffset += 4;
2256
2257 VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs.
2258 RegSaveFrameIndex = 0xAAAAAAA; // X86-64 only.
2259 ReturnAddrIndex = 0; // No return address slot generated yet.
2260 BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments.
2261 BytesCallerReserves = 0;
2262
2263 MF.getInfo<X86FunctionInfo>()->setBytesToPopOnReturn(BytesToPopOnReturn);
2264
2265 // Finally, inform the code generator which regs we return values in.
2266 switch (getValueType(MF.getFunction()->getReturnType())) {
2267 default: assert(0 && "Unknown type!");
2268 case MVT::isVoid: break;
Chris Lattner13bf6c12006-10-03 17:18:42 +00002269 case MVT::i1:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00002270 case MVT::i8:
2271 case MVT::i16:
2272 case MVT::i32:
2273 MF.addLiveOut(X86::ECX);
2274 break;
2275 case MVT::i64:
2276 MF.addLiveOut(X86::ECX);
2277 MF.addLiveOut(X86::EDX);
2278 break;
2279 case MVT::f32:
2280 case MVT::f64:
2281 MF.addLiveOut(X86::ST0);
2282 break;
2283 }
2284
2285 // Return the new list of results.
2286 std::vector<MVT::ValueType> RetVTs(Op.Val->value_begin(),
2287 Op.Val->value_end());
2288 return DAG.getNode(ISD::MERGE_VALUES, RetVTs, &ArgValues[0],ArgValues.size());
2289}
2290
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002291SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
2292 if (ReturnAddrIndex == 0) {
2293 // Set up a frame object for the return address.
2294 MachineFunction &MF = DAG.getMachineFunction();
Evan Cheng25ab6902006-09-08 06:48:29 +00002295 if (Subtarget->is64Bit())
2296 ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(8, -8);
2297 else
2298 ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002299 }
2300
Evan Cheng25ab6902006-09-08 06:48:29 +00002301 return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002302}
2303
2304
2305
2306std::pair<SDOperand, SDOperand> X86TargetLowering::
2307LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
2308 SelectionDAG &DAG) {
2309 SDOperand Result;
2310 if (Depth) // Depths > 0 not supported yet!
2311 Result = DAG.getConstant(0, getPointerTy());
2312 else {
2313 SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
2314 if (!isFrameAddress)
2315 // Just load the return address
Evan Cheng25ab6902006-09-08 06:48:29 +00002316 Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI,
Evan Cheng466685d2006-10-09 20:57:25 +00002317 NULL, 0);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002318 else
Evan Cheng25ab6902006-09-08 06:48:29 +00002319 Result = DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
2320 DAG.getConstant(4, getPointerTy()));
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00002321 }
2322 return std::make_pair(Result, Chain);
2323}
2324
Evan Cheng6dfa9992006-01-30 23:41:35 +00002325/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86
2326/// specific condition code. It returns a false if it cannot do a direct
Chris Lattnerf9570512006-09-13 03:22:10 +00002327/// translation. X86CC is the translated CondCode. LHS/RHS are modified as
2328/// needed.
Evan Cheng6be2c582006-04-05 23:38:46 +00002329static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP,
Chris Lattnerf9570512006-09-13 03:22:10 +00002330 unsigned &X86CC, SDOperand &LHS, SDOperand &RHS,
2331 SelectionDAG &DAG) {
Chris Lattner7fbe9722006-10-20 17:42:20 +00002332 X86CC = X86::COND_INVALID;
Evan Chengd9558e02006-01-06 00:43:03 +00002333 if (!isFP) {
Chris Lattnerbfd68a72006-09-13 17:04:54 +00002334 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
2335 if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnesValue()) {
2336 // X > -1 -> X == 0, jump !sign.
2337 RHS = DAG.getConstant(0, RHS.getValueType());
Chris Lattner7fbe9722006-10-20 17:42:20 +00002338 X86CC = X86::COND_NS;
Chris Lattnerbfd68a72006-09-13 17:04:54 +00002339 return true;
2340 } else if (SetCCOpcode == ISD::SETLT && RHSC->isNullValue()) {
2341 // X < 0 -> X == 0, jump on sign.
Chris Lattner7fbe9722006-10-20 17:42:20 +00002342 X86CC = X86::COND_S;
Chris Lattnerbfd68a72006-09-13 17:04:54 +00002343 return true;
2344 }
Chris Lattnerf9570512006-09-13 03:22:10 +00002345 }
2346
Evan Chengd9558e02006-01-06 00:43:03 +00002347 switch (SetCCOpcode) {
2348 default: break;
Chris Lattner7fbe9722006-10-20 17:42:20 +00002349 case ISD::SETEQ: X86CC = X86::COND_E; break;
2350 case ISD::SETGT: X86CC = X86::COND_G; break;
2351 case ISD::SETGE: X86CC = X86::COND_GE; break;
2352 case ISD::SETLT: X86CC = X86::COND_L; break;
2353 case ISD::SETLE: X86CC = X86::COND_LE; break;
2354 case ISD::SETNE: X86CC = X86::COND_NE; break;
2355 case ISD::SETULT: X86CC = X86::COND_B; break;
2356 case ISD::SETUGT: X86CC = X86::COND_A; break;
2357 case ISD::SETULE: X86CC = X86::COND_BE; break;
2358 case ISD::SETUGE: X86CC = X86::COND_AE; break;
Evan Chengd9558e02006-01-06 00:43:03 +00002359 }
2360 } else {
2361 // On a floating point condition, the flags are set as follows:
2362 // ZF PF CF op
2363 // 0 | 0 | 0 | X > Y
2364 // 0 | 0 | 1 | X < Y
2365 // 1 | 0 | 0 | X == Y
2366 // 1 | 1 | 1 | unordered
Chris Lattnerf9570512006-09-13 03:22:10 +00002367 bool Flip = false;
Evan Chengd9558e02006-01-06 00:43:03 +00002368 switch (SetCCOpcode) {
2369 default: break;
2370 case ISD::SETUEQ:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002371 case ISD::SETEQ: X86CC = X86::COND_E; break;
Evan Cheng5001ea12006-04-17 07:24:10 +00002372 case ISD::SETOLT: Flip = true; // Fallthrough
Evan Chengd9558e02006-01-06 00:43:03 +00002373 case ISD::SETOGT:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002374 case ISD::SETGT: X86CC = X86::COND_A; break;
Evan Cheng5001ea12006-04-17 07:24:10 +00002375 case ISD::SETOLE: Flip = true; // Fallthrough
Evan Chengd9558e02006-01-06 00:43:03 +00002376 case ISD::SETOGE:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002377 case ISD::SETGE: X86CC = X86::COND_AE; break;
Evan Cheng5001ea12006-04-17 07:24:10 +00002378 case ISD::SETUGT: Flip = true; // Fallthrough
Evan Chengd9558e02006-01-06 00:43:03 +00002379 case ISD::SETULT:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002380 case ISD::SETLT: X86CC = X86::COND_B; break;
Evan Cheng5001ea12006-04-17 07:24:10 +00002381 case ISD::SETUGE: Flip = true; // Fallthrough
Evan Chengd9558e02006-01-06 00:43:03 +00002382 case ISD::SETULE:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002383 case ISD::SETLE: X86CC = X86::COND_BE; break;
Evan Chengd9558e02006-01-06 00:43:03 +00002384 case ISD::SETONE:
Chris Lattner7fbe9722006-10-20 17:42:20 +00002385 case ISD::SETNE: X86CC = X86::COND_NE; break;
2386 case ISD::SETUO: X86CC = X86::COND_P; break;
2387 case ISD::SETO: X86CC = X86::COND_NP; break;
Evan Chengd9558e02006-01-06 00:43:03 +00002388 }
Chris Lattnerf9570512006-09-13 03:22:10 +00002389 if (Flip)
2390 std::swap(LHS, RHS);
Evan Chengd9558e02006-01-06 00:43:03 +00002391 }
Evan Cheng6dfa9992006-01-30 23:41:35 +00002392
Chris Lattner7fbe9722006-10-20 17:42:20 +00002393 return X86CC != X86::COND_INVALID;
Evan Chengd9558e02006-01-06 00:43:03 +00002394}
2395
Evan Cheng4a460802006-01-11 00:33:36 +00002396/// hasFPCMov - is there a floating point cmov for the specific X86 condition
2397/// code. Current x86 isa includes the following FP cmov instructions:
Evan Chengaaca22c2006-01-10 20:26:56 +00002398/// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu.
Evan Cheng4a460802006-01-11 00:33:36 +00002399static bool hasFPCMov(unsigned X86CC) {
Evan Chengaaca22c2006-01-10 20:26:56 +00002400 switch (X86CC) {
2401 default:
2402 return false;
Chris Lattner7fbe9722006-10-20 17:42:20 +00002403 case X86::COND_B:
2404 case X86::COND_BE:
2405 case X86::COND_E:
2406 case X86::COND_P:
2407 case X86::COND_A:
2408 case X86::COND_AE:
2409 case X86::COND_NE:
2410 case X86::COND_NP:
Evan Chengaaca22c2006-01-10 20:26:56 +00002411 return true;
2412 }
2413}
2414
Evan Cheng30b37b52006-03-13 23:18:16 +00002415/// DarwinGVRequiresExtraLoad - true if accessing the GV requires an extra
2416/// load. For Darwin, external and weak symbols are indirect, loading the value
2417/// at address GV rather then the value of GV itself. This means that the
2418/// GlobalAddress must be in the base or index register of the address, not the
2419/// GV offset field.
2420static bool DarwinGVRequiresExtraLoad(GlobalValue *GV) {
2421 return (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
2422 (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
2423}
2424
Anton Korobeynikov93c2b372006-09-17 13:06:18 +00002425/// WindowsGVRequiresExtraLoad - true if accessing the GV requires an extra
Anton Korobeynikovf8248682006-09-20 22:03:51 +00002426/// load. For Windows, dllimported symbols are indirect, loading the value at
2427/// address GV rather then the value of GV itself. This means that the
2428/// GlobalAddress must be in the base or index register of the address, not the
2429/// GV offset field.
Anton Korobeynikovb74ed072006-09-14 18:23:27 +00002430static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) {
Anton Korobeynikov93c2b372006-09-17 13:06:18 +00002431 return (GV->hasDLLImportLinkage());
Anton Korobeynikovb74ed072006-09-14 18:23:27 +00002432}
2433
Evan Cheng5ced1d82006-04-06 23:23:56 +00002434/// isUndefOrInRange - Op is either an undef node or a ConstantSDNode. Return
Evan Chengc5cdff22006-04-07 21:53:05 +00002435/// true if Op is undef or if its value falls within the specified range (L, H].
Evan Cheng5ced1d82006-04-06 23:23:56 +00002436static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) {
2437 if (Op.getOpcode() == ISD::UNDEF)
2438 return true;
2439
2440 unsigned Val = cast<ConstantSDNode>(Op)->getValue();
Evan Chengc5cdff22006-04-07 21:53:05 +00002441 return (Val >= Low && Val < Hi);
2442}
2443
2444/// isUndefOrEqual - Op is either an undef node or a ConstantSDNode. Return
2445/// true if Op is undef or if its value equal to the specified value.
2446static bool isUndefOrEqual(SDOperand Op, unsigned Val) {
2447 if (Op.getOpcode() == ISD::UNDEF)
2448 return true;
2449 return cast<ConstantSDNode>(Op)->getValue() == Val;
Evan Cheng5ced1d82006-04-06 23:23:56 +00002450}
2451
Evan Cheng0188ecb2006-03-22 18:59:22 +00002452/// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand
2453/// specifies a shuffle of elements that is suitable for input to PSHUFD.
2454bool X86::isPSHUFDMask(SDNode *N) {
2455 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2456
2457 if (N->getNumOperands() != 4)
2458 return false;
2459
2460 // Check if the value doesn't reference the second vector.
Evan Cheng506d3df2006-03-29 23:07:14 +00002461 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002462 SDOperand Arg = N->getOperand(i);
2463 if (Arg.getOpcode() == ISD::UNDEF) continue;
2464 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2465 if (cast<ConstantSDNode>(Arg)->getValue() >= 4)
Evan Cheng506d3df2006-03-29 23:07:14 +00002466 return false;
2467 }
2468
2469 return true;
2470}
2471
2472/// isPSHUFHWMask - Return true if the specified VECTOR_SHUFFLE operand
Evan Chengc21a0532006-04-05 01:47:37 +00002473/// specifies a shuffle of elements that is suitable for input to PSHUFHW.
Evan Cheng506d3df2006-03-29 23:07:14 +00002474bool X86::isPSHUFHWMask(SDNode *N) {
2475 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2476
2477 if (N->getNumOperands() != 8)
2478 return false;
2479
2480 // Lower quadword copied in order.
2481 for (unsigned i = 0; i != 4; ++i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002482 SDOperand Arg = N->getOperand(i);
2483 if (Arg.getOpcode() == ISD::UNDEF) continue;
2484 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2485 if (cast<ConstantSDNode>(Arg)->getValue() != i)
Evan Cheng506d3df2006-03-29 23:07:14 +00002486 return false;
2487 }
2488
2489 // Upper quadword shuffled.
2490 for (unsigned i = 4; i != 8; ++i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002491 SDOperand Arg = N->getOperand(i);
2492 if (Arg.getOpcode() == ISD::UNDEF) continue;
2493 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2494 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
Evan Cheng506d3df2006-03-29 23:07:14 +00002495 if (Val < 4 || Val > 7)
2496 return false;
2497 }
2498
2499 return true;
2500}
2501
2502/// isPSHUFLWMask - Return true if the specified VECTOR_SHUFFLE operand
Evan Chengc21a0532006-04-05 01:47:37 +00002503/// specifies a shuffle of elements that is suitable for input to PSHUFLW.
Evan Cheng506d3df2006-03-29 23:07:14 +00002504bool X86::isPSHUFLWMask(SDNode *N) {
2505 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2506
2507 if (N->getNumOperands() != 8)
2508 return false;
2509
2510 // Upper quadword copied in order.
Evan Chengc5cdff22006-04-07 21:53:05 +00002511 for (unsigned i = 4; i != 8; ++i)
2512 if (!isUndefOrEqual(N->getOperand(i), i))
Evan Cheng506d3df2006-03-29 23:07:14 +00002513 return false;
Evan Cheng506d3df2006-03-29 23:07:14 +00002514
2515 // Lower quadword shuffled.
Evan Chengc5cdff22006-04-07 21:53:05 +00002516 for (unsigned i = 0; i != 4; ++i)
2517 if (!isUndefOrInRange(N->getOperand(i), 0, 4))
Evan Cheng506d3df2006-03-29 23:07:14 +00002518 return false;
Evan Cheng0188ecb2006-03-22 18:59:22 +00002519
2520 return true;
2521}
2522
Evan Cheng14aed5e2006-03-24 01:18:28 +00002523/// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand
2524/// specifies a shuffle of elements that is suitable for input to SHUFP*.
Evan Cheng39623da2006-04-20 08:58:49 +00002525static bool isSHUFPMask(std::vector<SDOperand> &N) {
2526 unsigned NumElems = N.size();
2527 if (NumElems != 2 && NumElems != 4) return false;
Evan Cheng14aed5e2006-03-24 01:18:28 +00002528
Evan Cheng39623da2006-04-20 08:58:49 +00002529 unsigned Half = NumElems / 2;
2530 for (unsigned i = 0; i < Half; ++i)
2531 if (!isUndefOrInRange(N[i], 0, NumElems))
2532 return false;
2533 for (unsigned i = Half; i < NumElems; ++i)
2534 if (!isUndefOrInRange(N[i], NumElems, NumElems*2))
2535 return false;
Evan Cheng14aed5e2006-03-24 01:18:28 +00002536
2537 return true;
2538}
2539
Evan Cheng39623da2006-04-20 08:58:49 +00002540bool X86::isSHUFPMask(SDNode *N) {
2541 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2542 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
2543 return ::isSHUFPMask(Ops);
2544}
2545
2546/// isCommutedSHUFP - Returns true if the shuffle mask is except
2547/// the reverse of what x86 shuffles want. x86 shuffles requires the lower
2548/// half elements to come from vector 1 (which would equal the dest.) and
2549/// the upper half to come from vector 2.
2550static bool isCommutedSHUFP(std::vector<SDOperand> &Ops) {
2551 unsigned NumElems = Ops.size();
2552 if (NumElems != 2 && NumElems != 4) return false;
2553
2554 unsigned Half = NumElems / 2;
2555 for (unsigned i = 0; i < Half; ++i)
2556 if (!isUndefOrInRange(Ops[i], NumElems, NumElems*2))
2557 return false;
2558 for (unsigned i = Half; i < NumElems; ++i)
2559 if (!isUndefOrInRange(Ops[i], 0, NumElems))
2560 return false;
2561 return true;
2562}
2563
2564static bool isCommutedSHUFP(SDNode *N) {
2565 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2566 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
2567 return isCommutedSHUFP(Ops);
2568}
2569
Evan Cheng2c0dbd02006-03-24 02:58:06 +00002570/// isMOVHLPSMask - Return true if the specified VECTOR_SHUFFLE operand
2571/// specifies a shuffle of elements that is suitable for input to MOVHLPS.
2572bool X86::isMOVHLPSMask(SDNode *N) {
2573 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2574
Evan Cheng2064a2b2006-03-28 06:50:32 +00002575 if (N->getNumOperands() != 4)
Evan Cheng2c0dbd02006-03-24 02:58:06 +00002576 return false;
2577
Evan Cheng2064a2b2006-03-28 06:50:32 +00002578 // Expect bit0 == 6, bit1 == 7, bit2 == 2, bit3 == 3
Evan Chengc5cdff22006-04-07 21:53:05 +00002579 return isUndefOrEqual(N->getOperand(0), 6) &&
2580 isUndefOrEqual(N->getOperand(1), 7) &&
2581 isUndefOrEqual(N->getOperand(2), 2) &&
2582 isUndefOrEqual(N->getOperand(3), 3);
Evan Cheng2064a2b2006-03-28 06:50:32 +00002583}
2584
Evan Cheng5ced1d82006-04-06 23:23:56 +00002585/// isMOVLPMask - Return true if the specified VECTOR_SHUFFLE operand
2586/// specifies a shuffle of elements that is suitable for input to MOVLP{S|D}.
2587bool X86::isMOVLPMask(SDNode *N) {
2588 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2589
2590 unsigned NumElems = N->getNumOperands();
2591 if (NumElems != 2 && NumElems != 4)
2592 return false;
2593
Evan Chengc5cdff22006-04-07 21:53:05 +00002594 for (unsigned i = 0; i < NumElems/2; ++i)
2595 if (!isUndefOrEqual(N->getOperand(i), i + NumElems))
2596 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00002597
Evan Chengc5cdff22006-04-07 21:53:05 +00002598 for (unsigned i = NumElems/2; i < NumElems; ++i)
2599 if (!isUndefOrEqual(N->getOperand(i), i))
2600 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00002601
2602 return true;
2603}
2604
2605/// isMOVHPMask - Return true if the specified VECTOR_SHUFFLE operand
Evan Cheng533a0aa2006-04-19 20:35:22 +00002606/// specifies a shuffle of elements that is suitable for input to MOVHP{S|D}
2607/// and MOVLHPS.
Evan Cheng5ced1d82006-04-06 23:23:56 +00002608bool X86::isMOVHPMask(SDNode *N) {
2609 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2610
2611 unsigned NumElems = N->getNumOperands();
2612 if (NumElems != 2 && NumElems != 4)
2613 return false;
2614
Evan Chengc5cdff22006-04-07 21:53:05 +00002615 for (unsigned i = 0; i < NumElems/2; ++i)
2616 if (!isUndefOrEqual(N->getOperand(i), i))
2617 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00002618
2619 for (unsigned i = 0; i < NumElems/2; ++i) {
2620 SDOperand Arg = N->getOperand(i + NumElems/2);
Evan Chengc5cdff22006-04-07 21:53:05 +00002621 if (!isUndefOrEqual(Arg, i + NumElems))
2622 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00002623 }
2624
2625 return true;
2626}
2627
Evan Cheng0038e592006-03-28 00:39:58 +00002628/// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand
2629/// specifies a shuffle of elements that is suitable for input to UNPCKL.
Evan Cheng39623da2006-04-20 08:58:49 +00002630bool static isUNPCKLMask(std::vector<SDOperand> &N, bool V2IsSplat = false) {
2631 unsigned NumElems = N.size();
Evan Cheng0038e592006-03-28 00:39:58 +00002632 if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16)
2633 return false;
2634
2635 for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) {
Evan Cheng39623da2006-04-20 08:58:49 +00002636 SDOperand BitI = N[i];
2637 SDOperand BitI1 = N[i+1];
Evan Chengc5cdff22006-04-07 21:53:05 +00002638 if (!isUndefOrEqual(BitI, j))
2639 return false;
Evan Cheng39623da2006-04-20 08:58:49 +00002640 if (V2IsSplat) {
2641 if (isUndefOrEqual(BitI1, NumElems))
2642 return false;
2643 } else {
2644 if (!isUndefOrEqual(BitI1, j + NumElems))
2645 return false;
2646 }
Evan Cheng0038e592006-03-28 00:39:58 +00002647 }
2648
2649 return true;
2650}
2651
Evan Cheng39623da2006-04-20 08:58:49 +00002652bool X86::isUNPCKLMask(SDNode *N, bool V2IsSplat) {
2653 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2654 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
2655 return ::isUNPCKLMask(Ops, V2IsSplat);
2656}
2657
Evan Cheng4fcb9222006-03-28 02:43:26 +00002658/// isUNPCKHMask - Return true if the specified VECTOR_SHUFFLE operand
2659/// specifies a shuffle of elements that is suitable for input to UNPCKH.
Evan Cheng39623da2006-04-20 08:58:49 +00002660bool static isUNPCKHMask(std::vector<SDOperand> &N, bool V2IsSplat = false) {
2661 unsigned NumElems = N.size();
Evan Cheng4fcb9222006-03-28 02:43:26 +00002662 if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16)
2663 return false;
2664
2665 for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) {
Evan Cheng39623da2006-04-20 08:58:49 +00002666 SDOperand BitI = N[i];
2667 SDOperand BitI1 = N[i+1];
Evan Chengc5cdff22006-04-07 21:53:05 +00002668 if (!isUndefOrEqual(BitI, j + NumElems/2))
2669 return false;
Evan Cheng39623da2006-04-20 08:58:49 +00002670 if (V2IsSplat) {
2671 if (isUndefOrEqual(BitI1, NumElems))
2672 return false;
2673 } else {
2674 if (!isUndefOrEqual(BitI1, j + NumElems/2 + NumElems))
2675 return false;
2676 }
Evan Cheng4fcb9222006-03-28 02:43:26 +00002677 }
2678
2679 return true;
2680}
2681
Evan Cheng39623da2006-04-20 08:58:49 +00002682bool X86::isUNPCKHMask(SDNode *N, bool V2IsSplat) {
2683 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2684 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
2685 return ::isUNPCKHMask(Ops, V2IsSplat);
2686}
2687
Evan Cheng1d5a8cc2006-04-05 07:20:06 +00002688/// isUNPCKL_v_undef_Mask - Special case of isUNPCKLMask for canonical form
2689/// of vector_shuffle v, v, <0, 4, 1, 5>, i.e. vector_shuffle v, undef,
2690/// <0, 0, 1, 1>
2691bool X86::isUNPCKL_v_undef_Mask(SDNode *N) {
2692 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2693
2694 unsigned NumElems = N->getNumOperands();
2695 if (NumElems != 4 && NumElems != 8 && NumElems != 16)
2696 return false;
2697
2698 for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) {
2699 SDOperand BitI = N->getOperand(i);
2700 SDOperand BitI1 = N->getOperand(i+1);
2701
Evan Chengc5cdff22006-04-07 21:53:05 +00002702 if (!isUndefOrEqual(BitI, j))
2703 return false;
2704 if (!isUndefOrEqual(BitI1, j))
2705 return false;
Evan Cheng1d5a8cc2006-04-05 07:20:06 +00002706 }
2707
2708 return true;
2709}
2710
Evan Cheng017dcc62006-04-21 01:05:10 +00002711/// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand
2712/// specifies a shuffle of elements that is suitable for input to MOVSS,
2713/// MOVSD, and MOVD, i.e. setting the lowest element.
2714static bool isMOVLMask(std::vector<SDOperand> &N) {
Evan Cheng39623da2006-04-20 08:58:49 +00002715 unsigned NumElems = N.size();
Evan Cheng017dcc62006-04-21 01:05:10 +00002716 if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16)
Evan Chengd6d1cbd2006-04-11 00:19:04 +00002717 return false;
2718
Evan Cheng39623da2006-04-20 08:58:49 +00002719 if (!isUndefOrEqual(N[0], NumElems))
Evan Chengd6d1cbd2006-04-11 00:19:04 +00002720 return false;
2721
2722 for (unsigned i = 1; i < NumElems; ++i) {
Evan Cheng39623da2006-04-20 08:58:49 +00002723 SDOperand Arg = N[i];
Evan Chengd6d1cbd2006-04-11 00:19:04 +00002724 if (!isUndefOrEqual(Arg, i))
2725 return false;
2726 }
2727
2728 return true;
2729}
Evan Cheng1d5a8cc2006-04-05 07:20:06 +00002730
Evan Cheng017dcc62006-04-21 01:05:10 +00002731bool X86::isMOVLMask(SDNode *N) {
Evan Cheng39623da2006-04-20 08:58:49 +00002732 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2733 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
Evan Cheng017dcc62006-04-21 01:05:10 +00002734 return ::isMOVLMask(Ops);
Evan Cheng39623da2006-04-20 08:58:49 +00002735}
2736
Evan Cheng017dcc62006-04-21 01:05:10 +00002737/// isCommutedMOVL - Returns true if the shuffle mask is except the reverse
2738/// of what x86 movss want. X86 movs requires the lowest element to be lowest
Evan Cheng39623da2006-04-20 08:58:49 +00002739/// element of vector 2 and the other elements to come from vector 1 in order.
Evan Cheng8cf723d2006-09-08 01:50:06 +00002740static bool isCommutedMOVL(std::vector<SDOperand> &Ops, bool V2IsSplat = false,
2741 bool V2IsUndef = false) {
Evan Cheng39623da2006-04-20 08:58:49 +00002742 unsigned NumElems = Ops.size();
Evan Cheng017dcc62006-04-21 01:05:10 +00002743 if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16)
Evan Cheng39623da2006-04-20 08:58:49 +00002744 return false;
2745
2746 if (!isUndefOrEqual(Ops[0], 0))
2747 return false;
2748
2749 for (unsigned i = 1; i < NumElems; ++i) {
2750 SDOperand Arg = Ops[i];
Evan Cheng8cf723d2006-09-08 01:50:06 +00002751 if (!(isUndefOrEqual(Arg, i+NumElems) ||
2752 (V2IsUndef && isUndefOrInRange(Arg, NumElems, NumElems*2)) ||
2753 (V2IsSplat && isUndefOrEqual(Arg, NumElems))))
2754 return false;
Evan Cheng39623da2006-04-20 08:58:49 +00002755 }
2756
2757 return true;
2758}
2759
Evan Cheng8cf723d2006-09-08 01:50:06 +00002760static bool isCommutedMOVL(SDNode *N, bool V2IsSplat = false,
2761 bool V2IsUndef = false) {
Evan Cheng39623da2006-04-20 08:58:49 +00002762 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2763 std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
Evan Cheng8cf723d2006-09-08 01:50:06 +00002764 return isCommutedMOVL(Ops, V2IsSplat, V2IsUndef);
Evan Cheng39623da2006-04-20 08:58:49 +00002765}
2766
Evan Chengd9539472006-04-14 21:59:03 +00002767/// isMOVSHDUPMask - Return true if the specified VECTOR_SHUFFLE operand
2768/// specifies a shuffle of elements that is suitable for input to MOVSHDUP.
2769bool X86::isMOVSHDUPMask(SDNode *N) {
2770 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2771
2772 if (N->getNumOperands() != 4)
2773 return false;
2774
2775 // Expect 1, 1, 3, 3
2776 for (unsigned i = 0; i < 2; ++i) {
2777 SDOperand Arg = N->getOperand(i);
2778 if (Arg.getOpcode() == ISD::UNDEF) continue;
2779 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2780 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2781 if (Val != 1) return false;
2782 }
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002783
2784 bool HasHi = false;
Evan Chengd9539472006-04-14 21:59:03 +00002785 for (unsigned i = 2; i < 4; ++i) {
2786 SDOperand Arg = N->getOperand(i);
2787 if (Arg.getOpcode() == ISD::UNDEF) continue;
2788 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2789 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2790 if (Val != 3) return false;
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002791 HasHi = true;
Evan Chengd9539472006-04-14 21:59:03 +00002792 }
Evan Cheng39fc1452006-04-15 03:13:24 +00002793
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002794 // Don't use movshdup if it can be done with a shufps.
2795 return HasHi;
Evan Chengd9539472006-04-14 21:59:03 +00002796}
2797
2798/// isMOVSLDUPMask - Return true if the specified VECTOR_SHUFFLE operand
2799/// specifies a shuffle of elements that is suitable for input to MOVSLDUP.
2800bool X86::isMOVSLDUPMask(SDNode *N) {
2801 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2802
2803 if (N->getNumOperands() != 4)
2804 return false;
2805
2806 // Expect 0, 0, 2, 2
2807 for (unsigned i = 0; i < 2; ++i) {
2808 SDOperand Arg = N->getOperand(i);
2809 if (Arg.getOpcode() == ISD::UNDEF) continue;
2810 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2811 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2812 if (Val != 0) return false;
2813 }
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002814
2815 bool HasHi = false;
Evan Chengd9539472006-04-14 21:59:03 +00002816 for (unsigned i = 2; i < 4; ++i) {
2817 SDOperand Arg = N->getOperand(i);
2818 if (Arg.getOpcode() == ISD::UNDEF) continue;
2819 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2820 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2821 if (Val != 2) return false;
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002822 HasHi = true;
Evan Chengd9539472006-04-14 21:59:03 +00002823 }
Evan Cheng39fc1452006-04-15 03:13:24 +00002824
Evan Cheng57ebe9f2006-04-15 05:37:34 +00002825 // Don't use movshdup if it can be done with a shufps.
2826 return HasHi;
Evan Chengd9539472006-04-14 21:59:03 +00002827}
2828
Evan Chengb9df0ca2006-03-22 02:53:00 +00002829/// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies
2830/// a splat of a single element.
Evan Chengc575ca22006-04-17 20:43:08 +00002831static bool isSplatMask(SDNode *N) {
Evan Chengb9df0ca2006-03-22 02:53:00 +00002832 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2833
Evan Chengb9df0ca2006-03-22 02:53:00 +00002834 // This is a splat operation if each element of the permute is the same, and
2835 // if the value doesn't reference the second vector.
Evan Cheng94fe5eb2006-04-19 23:28:59 +00002836 unsigned NumElems = N->getNumOperands();
2837 SDOperand ElementBase;
2838 unsigned i = 0;
2839 for (; i != NumElems; ++i) {
2840 SDOperand Elt = N->getOperand(i);
2841 if (ConstantSDNode *EltV = dyn_cast<ConstantSDNode>(Elt)) {
2842 ElementBase = Elt;
2843 break;
2844 }
2845 }
2846
2847 if (!ElementBase.Val)
2848 return false;
2849
2850 for (; i != NumElems; ++i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002851 SDOperand Arg = N->getOperand(i);
2852 if (Arg.getOpcode() == ISD::UNDEF) continue;
2853 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
Evan Cheng94fe5eb2006-04-19 23:28:59 +00002854 if (Arg != ElementBase) return false;
Evan Chengb9df0ca2006-03-22 02:53:00 +00002855 }
2856
2857 // Make sure it is a splat of the first vector operand.
Evan Cheng94fe5eb2006-04-19 23:28:59 +00002858 return cast<ConstantSDNode>(ElementBase)->getValue() < NumElems;
Evan Chengb9df0ca2006-03-22 02:53:00 +00002859}
2860
Evan Chengc575ca22006-04-17 20:43:08 +00002861/// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies
2862/// a splat of a single element and it's a 2 or 4 element mask.
2863bool X86::isSplatMask(SDNode *N) {
2864 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2865
Evan Cheng94fe5eb2006-04-19 23:28:59 +00002866 // We can only splat 64-bit, and 32-bit quantities with a single instruction.
Evan Chengc575ca22006-04-17 20:43:08 +00002867 if (N->getNumOperands() != 4 && N->getNumOperands() != 2)
2868 return false;
2869 return ::isSplatMask(N);
2870}
2871
Evan Chengf686d9b2006-10-27 21:08:32 +00002872/// isSplatLoMask - Return true if the specified VECTOR_SHUFFLE operand
2873/// specifies a splat of zero element.
2874bool X86::isSplatLoMask(SDNode *N) {
2875 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2876
2877 for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
2878 if (!isUndefOrEqual(N->getOperand(i), 0))
2879 return false;
2880 return true;
2881}
2882
Evan Cheng63d33002006-03-22 08:01:21 +00002883/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
2884/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
2885/// instructions.
2886unsigned X86::getShuffleSHUFImmediate(SDNode *N) {
Evan Chengb9df0ca2006-03-22 02:53:00 +00002887 unsigned NumOperands = N->getNumOperands();
2888 unsigned Shift = (NumOperands == 4) ? 2 : 1;
2889 unsigned Mask = 0;
Evan Cheng36b27f32006-03-28 23:41:33 +00002890 for (unsigned i = 0; i < NumOperands; ++i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002891 unsigned Val = 0;
2892 SDOperand Arg = N->getOperand(NumOperands-i-1);
2893 if (Arg.getOpcode() != ISD::UNDEF)
2894 Val = cast<ConstantSDNode>(Arg)->getValue();
Evan Cheng14aed5e2006-03-24 01:18:28 +00002895 if (Val >= NumOperands) Val -= NumOperands;
Evan Cheng63d33002006-03-22 08:01:21 +00002896 Mask |= Val;
Evan Cheng36b27f32006-03-28 23:41:33 +00002897 if (i != NumOperands - 1)
2898 Mask <<= Shift;
2899 }
Evan Cheng63d33002006-03-22 08:01:21 +00002900
2901 return Mask;
2902}
2903
Evan Cheng506d3df2006-03-29 23:07:14 +00002904/// getShufflePSHUFHWImmediate - Return the appropriate immediate to shuffle
2905/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFHW
2906/// instructions.
2907unsigned X86::getShufflePSHUFHWImmediate(SDNode *N) {
2908 unsigned Mask = 0;
2909 // 8 nodes, but we only care about the last 4.
2910 for (unsigned i = 7; i >= 4; --i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002911 unsigned Val = 0;
2912 SDOperand Arg = N->getOperand(i);
2913 if (Arg.getOpcode() != ISD::UNDEF)
2914 Val = cast<ConstantSDNode>(Arg)->getValue();
Evan Cheng506d3df2006-03-29 23:07:14 +00002915 Mask |= (Val - 4);
2916 if (i != 4)
2917 Mask <<= 2;
2918 }
2919
2920 return Mask;
2921}
2922
2923/// getShufflePSHUFLWImmediate - Return the appropriate immediate to shuffle
2924/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFLW
2925/// instructions.
2926unsigned X86::getShufflePSHUFLWImmediate(SDNode *N) {
2927 unsigned Mask = 0;
2928 // 8 nodes, but we only care about the first 4.
2929 for (int i = 3; i >= 0; --i) {
Evan Chengef698ca2006-03-31 00:30:29 +00002930 unsigned Val = 0;
2931 SDOperand Arg = N->getOperand(i);
2932 if (Arg.getOpcode() != ISD::UNDEF)
2933 Val = cast<ConstantSDNode>(Arg)->getValue();
Evan Cheng506d3df2006-03-29 23:07:14 +00002934 Mask |= Val;
2935 if (i != 0)
2936 Mask <<= 2;
2937 }
2938
2939 return Mask;
2940}
2941
Evan Chengc21a0532006-04-05 01:47:37 +00002942/// isPSHUFHW_PSHUFLWMask - true if the specified VECTOR_SHUFFLE operand
2943/// specifies a 8 element shuffle that can be broken into a pair of
2944/// PSHUFHW and PSHUFLW.
2945static bool isPSHUFHW_PSHUFLWMask(SDNode *N) {
2946 assert(N->getOpcode() == ISD::BUILD_VECTOR);
2947
2948 if (N->getNumOperands() != 8)
2949 return false;
2950
2951 // Lower quadword shuffled.
2952 for (unsigned i = 0; i != 4; ++i) {
2953 SDOperand Arg = N->getOperand(i);
2954 if (Arg.getOpcode() == ISD::UNDEF) continue;
2955 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2956 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2957 if (Val > 4)
2958 return false;
2959 }
2960
2961 // Upper quadword shuffled.
2962 for (unsigned i = 4; i != 8; ++i) {
2963 SDOperand Arg = N->getOperand(i);
2964 if (Arg.getOpcode() == ISD::UNDEF) continue;
2965 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2966 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2967 if (Val < 4 || Val > 7)
2968 return false;
2969 }
2970
2971 return true;
2972}
2973
Evan Cheng5ced1d82006-04-06 23:23:56 +00002974/// CommuteVectorShuffle - Swap vector_shuffle operandsas well as
2975/// values in ther permute mask.
Evan Cheng9eca5e82006-10-25 21:49:50 +00002976static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1,
2977 SDOperand &V2, SDOperand &Mask,
2978 SelectionDAG &DAG) {
Evan Cheng5ced1d82006-04-06 23:23:56 +00002979 MVT::ValueType VT = Op.getValueType();
2980 MVT::ValueType MaskVT = Mask.getValueType();
2981 MVT::ValueType EltVT = MVT::getVectorBaseType(MaskVT);
2982 unsigned NumElems = Mask.getNumOperands();
2983 std::vector<SDOperand> MaskVec;
2984
2985 for (unsigned i = 0; i != NumElems; ++i) {
2986 SDOperand Arg = Mask.getOperand(i);
Evan Cheng80d428c2006-04-19 22:48:17 +00002987 if (Arg.getOpcode() == ISD::UNDEF) {
2988 MaskVec.push_back(DAG.getNode(ISD::UNDEF, EltVT));
2989 continue;
2990 }
Evan Cheng5ced1d82006-04-06 23:23:56 +00002991 assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
2992 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
2993 if (Val < NumElems)
2994 MaskVec.push_back(DAG.getConstant(Val + NumElems, EltVT));
2995 else
2996 MaskVec.push_back(DAG.getConstant(Val - NumElems, EltVT));
2997 }
2998
Evan Cheng9eca5e82006-10-25 21:49:50 +00002999 std::swap(V1, V2);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003000 Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
Evan Cheng9eca5e82006-10-25 21:49:50 +00003001 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
Evan Cheng5ced1d82006-04-06 23:23:56 +00003002}
3003
Evan Cheng533a0aa2006-04-19 20:35:22 +00003004/// ShouldXformToMOVHLPS - Return true if the node should be transformed to
3005/// match movhlps. The lower half elements should come from upper half of
3006/// V1 (and in order), and the upper half elements should come from the upper
3007/// half of V2 (and in order).
3008static bool ShouldXformToMOVHLPS(SDNode *Mask) {
3009 unsigned NumElems = Mask->getNumOperands();
3010 if (NumElems != 4)
3011 return false;
3012 for (unsigned i = 0, e = 2; i != e; ++i)
3013 if (!isUndefOrEqual(Mask->getOperand(i), i+2))
3014 return false;
3015 for (unsigned i = 2; i != 4; ++i)
3016 if (!isUndefOrEqual(Mask->getOperand(i), i+4))
3017 return false;
3018 return true;
3019}
3020
Evan Cheng5ced1d82006-04-06 23:23:56 +00003021/// isScalarLoadToVector - Returns true if the node is a scalar load that
3022/// is promoted to a vector.
Evan Cheng533a0aa2006-04-19 20:35:22 +00003023static inline bool isScalarLoadToVector(SDNode *N) {
3024 if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) {
3025 N = N->getOperand(0).Val;
Evan Cheng466685d2006-10-09 20:57:25 +00003026 return ISD::isNON_EXTLoad(N);
Evan Cheng5ced1d82006-04-06 23:23:56 +00003027 }
3028 return false;
3029}
3030
Evan Cheng533a0aa2006-04-19 20:35:22 +00003031/// ShouldXformToMOVLP{S|D} - Return true if the node should be transformed to
3032/// match movlp{s|d}. The lower half elements should come from lower half of
3033/// V1 (and in order), and the upper half elements should come from the upper
3034/// half of V2 (and in order). And since V1 will become the source of the
3035/// MOVLP, it must be either a vector load or a scalar load to vector.
Evan Cheng23425f52006-10-09 21:39:25 +00003036static bool ShouldXformToMOVLP(SDNode *V1, SDNode *V2, SDNode *Mask) {
Evan Cheng466685d2006-10-09 20:57:25 +00003037 if (!ISD::isNON_EXTLoad(V1) && !isScalarLoadToVector(V1))
Evan Cheng533a0aa2006-04-19 20:35:22 +00003038 return false;
Evan Cheng23425f52006-10-09 21:39:25 +00003039 // Is V2 is a vector load, don't do this transformation. We will try to use
3040 // load folding shufps op.
3041 if (ISD::isNON_EXTLoad(V2))
3042 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00003043
Evan Cheng533a0aa2006-04-19 20:35:22 +00003044 unsigned NumElems = Mask->getNumOperands();
3045 if (NumElems != 2 && NumElems != 4)
3046 return false;
3047 for (unsigned i = 0, e = NumElems/2; i != e; ++i)
3048 if (!isUndefOrEqual(Mask->getOperand(i), i))
3049 return false;
3050 for (unsigned i = NumElems/2; i != NumElems; ++i)
3051 if (!isUndefOrEqual(Mask->getOperand(i), i+NumElems))
3052 return false;
3053 return true;
Evan Cheng5ced1d82006-04-06 23:23:56 +00003054}
3055
Evan Cheng39623da2006-04-20 08:58:49 +00003056/// isSplatVector - Returns true if N is a BUILD_VECTOR node whose elements are
3057/// all the same.
3058static bool isSplatVector(SDNode *N) {
3059 if (N->getOpcode() != ISD::BUILD_VECTOR)
3060 return false;
Evan Cheng5ced1d82006-04-06 23:23:56 +00003061
Evan Cheng39623da2006-04-20 08:58:49 +00003062 SDOperand SplatValue = N->getOperand(0);
3063 for (unsigned i = 1, e = N->getNumOperands(); i != e; ++i)
3064 if (N->getOperand(i) != SplatValue)
Evan Cheng5ced1d82006-04-06 23:23:56 +00003065 return false;
3066 return true;
3067}
3068
Evan Cheng8cf723d2006-09-08 01:50:06 +00003069/// isUndefShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
3070/// to an undef.
3071static bool isUndefShuffle(SDNode *N) {
3072 if (N->getOpcode() != ISD::BUILD_VECTOR)
3073 return false;
3074
3075 SDOperand V1 = N->getOperand(0);
3076 SDOperand V2 = N->getOperand(1);
3077 SDOperand Mask = N->getOperand(2);
3078 unsigned NumElems = Mask.getNumOperands();
3079 for (unsigned i = 0; i != NumElems; ++i) {
3080 SDOperand Arg = Mask.getOperand(i);
3081 if (Arg.getOpcode() != ISD::UNDEF) {
3082 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
3083 if (Val < NumElems && V1.getOpcode() != ISD::UNDEF)
3084 return false;
3085 else if (Val >= NumElems && V2.getOpcode() != ISD::UNDEF)
3086 return false;
3087 }
3088 }
3089 return true;
3090}
3091
Evan Cheng39623da2006-04-20 08:58:49 +00003092/// NormalizeMask - V2 is a splat, modify the mask (if needed) so all elements
3093/// that point to V2 points to its first element.
3094static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) {
3095 assert(Mask.getOpcode() == ISD::BUILD_VECTOR);
3096
3097 bool Changed = false;
3098 std::vector<SDOperand> MaskVec;
3099 unsigned NumElems = Mask.getNumOperands();
3100 for (unsigned i = 0; i != NumElems; ++i) {
3101 SDOperand Arg = Mask.getOperand(i);
3102 if (Arg.getOpcode() != ISD::UNDEF) {
3103 unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
3104 if (Val > NumElems) {
3105 Arg = DAG.getConstant(NumElems, Arg.getValueType());
3106 Changed = true;
3107 }
3108 }
3109 MaskVec.push_back(Arg);
3110 }
3111
3112 if (Changed)
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003113 Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
3114 &MaskVec[0], MaskVec.size());
Evan Cheng39623da2006-04-20 08:58:49 +00003115 return Mask;
3116}
3117
Evan Cheng017dcc62006-04-21 01:05:10 +00003118/// getMOVLMask - Returns a vector_shuffle mask for an movs{s|d}, movd
3119/// operation of specified width.
3120static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) {
Evan Cheng39623da2006-04-20 08:58:49 +00003121 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3122 MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
3123
3124 std::vector<SDOperand> MaskVec;
3125 MaskVec.push_back(DAG.getConstant(NumElems, BaseVT));
3126 for (unsigned i = 1; i != NumElems; ++i)
3127 MaskVec.push_back(DAG.getConstant(i, BaseVT));
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003128 return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
Evan Cheng39623da2006-04-20 08:58:49 +00003129}
3130
Evan Chengc575ca22006-04-17 20:43:08 +00003131/// getUnpacklMask - Returns a vector_shuffle mask for an unpackl operation
3132/// of specified width.
3133static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) {
3134 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3135 MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
3136 std::vector<SDOperand> MaskVec;
3137 for (unsigned i = 0, e = NumElems/2; i != e; ++i) {
3138 MaskVec.push_back(DAG.getConstant(i, BaseVT));
3139 MaskVec.push_back(DAG.getConstant(i + NumElems, BaseVT));
3140 }
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003141 return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
Evan Chengc575ca22006-04-17 20:43:08 +00003142}
3143
Evan Cheng39623da2006-04-20 08:58:49 +00003144/// getUnpackhMask - Returns a vector_shuffle mask for an unpackh operation
3145/// of specified width.
3146static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) {
3147 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3148 MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
3149 unsigned Half = NumElems/2;
3150 std::vector<SDOperand> MaskVec;
3151 for (unsigned i = 0; i != Half; ++i) {
3152 MaskVec.push_back(DAG.getConstant(i + Half, BaseVT));
3153 MaskVec.push_back(DAG.getConstant(i + NumElems + Half, BaseVT));
3154 }
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003155 return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
Evan Cheng39623da2006-04-20 08:58:49 +00003156}
3157
Evan Cheng017dcc62006-04-21 01:05:10 +00003158/// getZeroVector - Returns a vector of specified type with all zero elements.
3159///
3160static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) {
3161 assert(MVT::isVector(VT) && "Expected a vector type");
3162 unsigned NumElems = getVectorNumElements(VT);
3163 MVT::ValueType EVT = MVT::getVectorBaseType(VT);
3164 bool isFP = MVT::isFloatingPoint(EVT);
3165 SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT);
3166 std::vector<SDOperand> ZeroVec(NumElems, Zero);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003167 return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size());
Evan Cheng017dcc62006-04-21 01:05:10 +00003168}
3169
Evan Chengc575ca22006-04-17 20:43:08 +00003170/// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32.
3171///
3172static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
3173 SDOperand V1 = Op.getOperand(0);
Evan Cheng017dcc62006-04-21 01:05:10 +00003174 SDOperand Mask = Op.getOperand(2);
Evan Chengc575ca22006-04-17 20:43:08 +00003175 MVT::ValueType VT = Op.getValueType();
Evan Cheng017dcc62006-04-21 01:05:10 +00003176 unsigned NumElems = Mask.getNumOperands();
3177 Mask = getUnpacklMask(NumElems, DAG);
Evan Chengc575ca22006-04-17 20:43:08 +00003178 while (NumElems != 4) {
Evan Cheng017dcc62006-04-21 01:05:10 +00003179 V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1, Mask);
Evan Chengc575ca22006-04-17 20:43:08 +00003180 NumElems >>= 1;
3181 }
3182 V1 = DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, V1);
3183
3184 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
Evan Cheng017dcc62006-04-21 01:05:10 +00003185 Mask = getZeroVector(MaskVT, DAG);
Evan Chengc575ca22006-04-17 20:43:08 +00003186 SDOperand Shuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v4i32, V1,
Evan Cheng017dcc62006-04-21 01:05:10 +00003187 DAG.getNode(ISD::UNDEF, MVT::v4i32), Mask);
Evan Chengc575ca22006-04-17 20:43:08 +00003188 return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
3189}
3190
Evan Cheng017dcc62006-04-21 01:05:10 +00003191/// isZeroNode - Returns true if Elt is a constant zero or a floating point
3192/// constant +0.0.
3193static inline bool isZeroNode(SDOperand Elt) {
3194 return ((isa<ConstantSDNode>(Elt) &&
3195 cast<ConstantSDNode>(Elt)->getValue() == 0) ||
3196 (isa<ConstantFPSDNode>(Elt) &&
3197 cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
3198}
3199
Evan Chengba05f722006-04-21 23:03:30 +00003200/// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified
3201/// vector and zero or undef vector.
3202static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
Evan Cheng017dcc62006-04-21 01:05:10 +00003203 unsigned NumElems, unsigned Idx,
Evan Chengba05f722006-04-21 23:03:30 +00003204 bool isZero, SelectionDAG &DAG) {
3205 SDOperand V1 = isZero ? getZeroVector(VT, DAG) : DAG.getNode(ISD::UNDEF, VT);
Evan Cheng017dcc62006-04-21 01:05:10 +00003206 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3207 MVT::ValueType EVT = MVT::getVectorBaseType(MaskVT);
3208 SDOperand Zero = DAG.getConstant(0, EVT);
3209 std::vector<SDOperand> MaskVec(NumElems, Zero);
3210 MaskVec[Idx] = DAG.getConstant(NumElems, EVT);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003211 SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3212 &MaskVec[0], MaskVec.size());
Evan Chengba05f722006-04-21 23:03:30 +00003213 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
Evan Cheng017dcc62006-04-21 01:05:10 +00003214}
3215
Evan Chengc78d3b42006-04-24 18:01:45 +00003216/// LowerBuildVectorv16i8 - Custom lower build_vector of v16i8.
3217///
3218static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
3219 unsigned NumNonZero, unsigned NumZero,
Evan Cheng25ab6902006-09-08 06:48:29 +00003220 SelectionDAG &DAG, TargetLowering &TLI) {
Evan Chengc78d3b42006-04-24 18:01:45 +00003221 if (NumNonZero > 8)
3222 return SDOperand();
3223
3224 SDOperand V(0, 0);
3225 bool First = true;
3226 for (unsigned i = 0; i < 16; ++i) {
3227 bool ThisIsNonZero = (NonZeros & (1 << i)) != 0;
3228 if (ThisIsNonZero && First) {
3229 if (NumZero)
3230 V = getZeroVector(MVT::v8i16, DAG);
3231 else
3232 V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
3233 First = false;
3234 }
3235
3236 if ((i & 1) != 0) {
3237 SDOperand ThisElt(0, 0), LastElt(0, 0);
3238 bool LastIsNonZero = (NonZeros & (1 << (i-1))) != 0;
3239 if (LastIsNonZero) {
3240 LastElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i-1));
3241 }
3242 if (ThisIsNonZero) {
3243 ThisElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i));
3244 ThisElt = DAG.getNode(ISD::SHL, MVT::i16,
3245 ThisElt, DAG.getConstant(8, MVT::i8));
3246 if (LastIsNonZero)
3247 ThisElt = DAG.getNode(ISD::OR, MVT::i16, ThisElt, LastElt);
3248 } else
3249 ThisElt = LastElt;
3250
3251 if (ThisElt.Val)
3252 V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, ThisElt,
Evan Cheng25ab6902006-09-08 06:48:29 +00003253 DAG.getConstant(i/2, TLI.getPointerTy()));
Evan Chengc78d3b42006-04-24 18:01:45 +00003254 }
3255 }
3256
3257 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, V);
3258}
3259
3260/// LowerBuildVectorv16i8 - Custom lower build_vector of v8i16.
3261///
3262static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
3263 unsigned NumNonZero, unsigned NumZero,
Evan Cheng25ab6902006-09-08 06:48:29 +00003264 SelectionDAG &DAG, TargetLowering &TLI) {
Evan Chengc78d3b42006-04-24 18:01:45 +00003265 if (NumNonZero > 4)
3266 return SDOperand();
3267
3268 SDOperand V(0, 0);
3269 bool First = true;
3270 for (unsigned i = 0; i < 8; ++i) {
3271 bool isNonZero = (NonZeros & (1 << i)) != 0;
3272 if (isNonZero) {
3273 if (First) {
3274 if (NumZero)
3275 V = getZeroVector(MVT::v8i16, DAG);
3276 else
3277 V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
3278 First = false;
3279 }
3280 V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, Op.getOperand(i),
Evan Cheng25ab6902006-09-08 06:48:29 +00003281 DAG.getConstant(i, TLI.getPointerTy()));
Evan Chengc78d3b42006-04-24 18:01:45 +00003282 }
3283 }
3284
3285 return V;
3286}
3287
Evan Cheng0db9fe62006-04-25 20:13:52 +00003288SDOperand
3289X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
3290 // All zero's are handled with pxor.
3291 if (ISD::isBuildVectorAllZeros(Op.Val))
3292 return Op;
3293
3294 // All one's are handled with pcmpeqd.
3295 if (ISD::isBuildVectorAllOnes(Op.Val))
3296 return Op;
3297
3298 MVT::ValueType VT = Op.getValueType();
3299 MVT::ValueType EVT = MVT::getVectorBaseType(VT);
3300 unsigned EVTBits = MVT::getSizeInBits(EVT);
3301
3302 unsigned NumElems = Op.getNumOperands();
3303 unsigned NumZero = 0;
3304 unsigned NumNonZero = 0;
3305 unsigned NonZeros = 0;
3306 std::set<SDOperand> Values;
3307 for (unsigned i = 0; i < NumElems; ++i) {
3308 SDOperand Elt = Op.getOperand(i);
3309 if (Elt.getOpcode() != ISD::UNDEF) {
3310 Values.insert(Elt);
3311 if (isZeroNode(Elt))
3312 NumZero++;
3313 else {
3314 NonZeros |= (1 << i);
3315 NumNonZero++;
3316 }
3317 }
3318 }
3319
3320 if (NumNonZero == 0)
3321 // Must be a mix of zero and undef. Return a zero vector.
3322 return getZeroVector(VT, DAG);
3323
3324 // Splat is obviously ok. Let legalizer expand it to a shuffle.
3325 if (Values.size() == 1)
3326 return SDOperand();
3327
3328 // Special case for single non-zero element.
Evan Cheng9bbbb982006-10-25 20:48:19 +00003329 if (NumNonZero == 1) {
Evan Cheng0db9fe62006-04-25 20:13:52 +00003330 unsigned Idx = CountTrailingZeros_32(NonZeros);
3331 SDOperand Item = Op.getOperand(Idx);
3332 Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);
3333 if (Idx == 0)
3334 // Turn it into a MOVL (i.e. movss, movsd, or movd) to a zero vector.
3335 return getShuffleVectorZeroOrUndef(Item, VT, NumElems, Idx,
3336 NumZero > 0, DAG);
3337
3338 if (EVTBits == 32) {
3339 // Turn it into a shuffle of zero and zero-extended scalar to vector.
3340 Item = getShuffleVectorZeroOrUndef(Item, VT, NumElems, 0, NumZero > 0,
3341 DAG);
3342 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3343 MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
3344 std::vector<SDOperand> MaskVec;
3345 for (unsigned i = 0; i < NumElems; i++)
3346 MaskVec.push_back(DAG.getConstant((i == Idx) ? 0 : 1, MaskEVT));
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003347 SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3348 &MaskVec[0], MaskVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003349 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Item,
3350 DAG.getNode(ISD::UNDEF, VT), Mask);
3351 }
3352 }
3353
Evan Chenge1113032006-10-04 18:33:38 +00003354 // Let legalizer expand 2-wide build_vector's.
Evan Cheng0db9fe62006-04-25 20:13:52 +00003355 if (EVTBits == 64)
3356 return SDOperand();
3357
3358 // If element VT is < 32 bits, convert it to inserts into a zero vector.
3359 if (EVTBits == 8) {
Evan Cheng25ab6902006-09-08 06:48:29 +00003360 SDOperand V = LowerBuildVectorv16i8(Op, NonZeros,NumNonZero,NumZero, DAG,
3361 *this);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003362 if (V.Val) return V;
3363 }
3364
3365 if (EVTBits == 16) {
Evan Cheng25ab6902006-09-08 06:48:29 +00003366 SDOperand V = LowerBuildVectorv8i16(Op, NonZeros,NumNonZero,NumZero, DAG,
3367 *this);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003368 if (V.Val) return V;
3369 }
3370
3371 // If element VT is == 32 bits, turn it into a number of shuffles.
3372 std::vector<SDOperand> V(NumElems);
3373 if (NumElems == 4 && NumZero > 0) {
3374 for (unsigned i = 0; i < 4; ++i) {
3375 bool isZero = !(NonZeros & (1 << i));
3376 if (isZero)
3377 V[i] = getZeroVector(VT, DAG);
3378 else
3379 V[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Op.getOperand(i));
3380 }
3381
3382 for (unsigned i = 0; i < 2; ++i) {
3383 switch ((NonZeros & (0x3 << i*2)) >> (i*2)) {
3384 default: break;
3385 case 0:
3386 V[i] = V[i*2]; // Must be a zero vector.
3387 break;
3388 case 1:
3389 V[i] = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V[i*2+1], V[i*2],
3390 getMOVLMask(NumElems, DAG));
3391 break;
3392 case 2:
3393 V[i] = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V[i*2], V[i*2+1],
3394 getMOVLMask(NumElems, DAG));
3395 break;
3396 case 3:
3397 V[i] = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V[i*2], V[i*2+1],
3398 getUnpacklMask(NumElems, DAG));
3399 break;
3400 }
3401 }
3402
Evan Cheng069287d2006-05-16 07:21:53 +00003403 // Take advantage of the fact GR32 to VR128 scalar_to_vector (i.e. movd)
Evan Cheng0db9fe62006-04-25 20:13:52 +00003404 // clears the upper bits.
3405 // FIXME: we can do the same for v4f32 case when we know both parts of
3406 // the lower half come from scalar_to_vector (loadf32). We should do
3407 // that in post legalizer dag combiner with target specific hooks.
Evan Cheng9bbbb982006-10-25 20:48:19 +00003408 if (MVT::isInteger(EVT) && (NonZeros & (0x3 << 2)) == 0)
Evan Cheng0db9fe62006-04-25 20:13:52 +00003409 return V[0];
3410 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3411 MVT::ValueType EVT = MVT::getVectorBaseType(MaskVT);
3412 std::vector<SDOperand> MaskVec;
3413 bool Reverse = (NonZeros & 0x3) == 2;
3414 for (unsigned i = 0; i < 2; ++i)
3415 if (Reverse)
3416 MaskVec.push_back(DAG.getConstant(1-i, EVT));
3417 else
3418 MaskVec.push_back(DAG.getConstant(i, EVT));
3419 Reverse = ((NonZeros & (0x3 << 2)) >> 2) == 2;
3420 for (unsigned i = 0; i < 2; ++i)
3421 if (Reverse)
3422 MaskVec.push_back(DAG.getConstant(1-i+NumElems, EVT));
3423 else
3424 MaskVec.push_back(DAG.getConstant(i+NumElems, EVT));
Chris Lattnere2199452006-08-11 17:38:39 +00003425 SDOperand ShufMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3426 &MaskVec[0], MaskVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003427 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V[0], V[1], ShufMask);
3428 }
3429
3430 if (Values.size() > 2) {
3431 // Expand into a number of unpckl*.
3432 // e.g. for v4f32
3433 // Step 1: unpcklps 0, 2 ==> X: <?, ?, 2, 0>
3434 // : unpcklps 1, 3 ==> Y: <?, ?, 3, 1>
3435 // Step 2: unpcklps X, Y ==> <3, 2, 1, 0>
3436 SDOperand UnpckMask = getUnpacklMask(NumElems, DAG);
3437 for (unsigned i = 0; i < NumElems; ++i)
3438 V[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Op.getOperand(i));
3439 NumElems >>= 1;
3440 while (NumElems != 0) {
3441 for (unsigned i = 0; i < NumElems; ++i)
3442 V[i] = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V[i], V[i + NumElems],
3443 UnpckMask);
3444 NumElems >>= 1;
3445 }
3446 return V[0];
3447 }
3448
3449 return SDOperand();
3450}
3451
3452SDOperand
3453X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
3454 SDOperand V1 = Op.getOperand(0);
3455 SDOperand V2 = Op.getOperand(1);
3456 SDOperand PermMask = Op.getOperand(2);
3457 MVT::ValueType VT = Op.getValueType();
3458 unsigned NumElems = PermMask.getNumOperands();
3459 bool V1IsUndef = V1.getOpcode() == ISD::UNDEF;
3460 bool V2IsUndef = V2.getOpcode() == ISD::UNDEF;
Evan Chengd9b8e402006-10-16 06:36:00 +00003461 bool V1IsSplat = false;
3462 bool V2IsSplat = false;
Evan Cheng0db9fe62006-04-25 20:13:52 +00003463
Evan Cheng8cf723d2006-09-08 01:50:06 +00003464 if (isUndefShuffle(Op.Val))
3465 return DAG.getNode(ISD::UNDEF, VT);
3466
Evan Cheng0db9fe62006-04-25 20:13:52 +00003467 if (isSplatMask(PermMask.Val)) {
3468 if (NumElems <= 4) return Op;
3469 // Promote it to a v4i32 splat.
Evan Cheng9bbbb982006-10-25 20:48:19 +00003470 return PromoteSplat(Op, DAG);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003471 }
3472
Evan Cheng9bbbb982006-10-25 20:48:19 +00003473 if (X86::isMOVLMask(PermMask.Val))
3474 return (V1IsUndef) ? V2 : Op;
Evan Cheng0db9fe62006-04-25 20:13:52 +00003475
Evan Cheng9bbbb982006-10-25 20:48:19 +00003476 if (X86::isMOVSHDUPMask(PermMask.Val) ||
3477 X86::isMOVSLDUPMask(PermMask.Val) ||
3478 X86::isMOVHLPSMask(PermMask.Val) ||
3479 X86::isMOVHPMask(PermMask.Val) ||
3480 X86::isMOVLPMask(PermMask.Val))
3481 return Op;
Evan Cheng0db9fe62006-04-25 20:13:52 +00003482
Evan Cheng9bbbb982006-10-25 20:48:19 +00003483 if (ShouldXformToMOVHLPS(PermMask.Val) ||
3484 ShouldXformToMOVLP(V1.Val, V2.Val, PermMask.Val))
Evan Cheng9eca5e82006-10-25 21:49:50 +00003485 return CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003486
Evan Cheng9eca5e82006-10-25 21:49:50 +00003487 bool Commuted = false;
Evan Cheng9bbbb982006-10-25 20:48:19 +00003488 V1IsSplat = isSplatVector(V1.Val);
3489 V2IsSplat = isSplatVector(V2.Val);
3490 if ((V1IsSplat || V1IsUndef) && !(V2IsSplat || V2IsUndef)) {
Evan Cheng9eca5e82006-10-25 21:49:50 +00003491 Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
Evan Cheng9bbbb982006-10-25 20:48:19 +00003492 std::swap(V1IsSplat, V2IsSplat);
3493 std::swap(V1IsUndef, V2IsUndef);
Evan Cheng9eca5e82006-10-25 21:49:50 +00003494 Commuted = true;
Evan Cheng9bbbb982006-10-25 20:48:19 +00003495 }
3496
3497 if (isCommutedMOVL(PermMask.Val, V2IsSplat, V2IsUndef)) {
3498 if (V2IsUndef) return V1;
Evan Cheng9eca5e82006-10-25 21:49:50 +00003499 Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
Evan Cheng9bbbb982006-10-25 20:48:19 +00003500 if (V2IsSplat) {
3501 // V2 is a splat, so the mask may be malformed. That is, it may point
3502 // to any V2 element. The instruction selectior won't like this. Get
3503 // a corrected mask and commute to form a proper MOVS{S|D}.
3504 SDOperand NewMask = getMOVLMask(NumElems, DAG);
3505 if (NewMask.Val != PermMask.Val)
3506 Op = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, NewMask);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003507 }
Evan Cheng9bbbb982006-10-25 20:48:19 +00003508 return Op;
Evan Chengd9b8e402006-10-16 06:36:00 +00003509 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00003510
Evan Chengd9b8e402006-10-16 06:36:00 +00003511 if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) ||
3512 X86::isUNPCKLMask(PermMask.Val) ||
3513 X86::isUNPCKHMask(PermMask.Val))
3514 return Op;
Evan Chenge1113032006-10-04 18:33:38 +00003515
Evan Cheng9bbbb982006-10-25 20:48:19 +00003516 if (V2IsSplat) {
3517 // Normalize mask so all entries that point to V2 points to its first
3518 // element then try to match unpck{h|l} again. If match, return a
3519 // new vector_shuffle with the corrected mask.
3520 SDOperand NewMask = NormalizeMask(PermMask, DAG);
3521 if (NewMask.Val != PermMask.Val) {
3522 if (X86::isUNPCKLMask(PermMask.Val, true)) {
3523 SDOperand NewMask = getUnpacklMask(NumElems, DAG);
3524 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, NewMask);
3525 } else if (X86::isUNPCKHMask(PermMask.Val, true)) {
3526 SDOperand NewMask = getUnpackhMask(NumElems, DAG);
3527 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, NewMask);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003528 }
3529 }
3530 }
3531
3532 // Normalize the node to match x86 shuffle ops if needed
Evan Cheng9eca5e82006-10-25 21:49:50 +00003533 if (V2.getOpcode() != ISD::UNDEF && isCommutedSHUFP(PermMask.Val))
3534 Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
3535
3536 if (Commuted) {
3537 // Commute is back and try unpck* again.
3538 Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
3539 if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) ||
3540 X86::isUNPCKLMask(PermMask.Val) ||
3541 X86::isUNPCKHMask(PermMask.Val))
3542 return Op;
3543 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00003544
3545 // If VT is integer, try PSHUF* first, then SHUFP*.
3546 if (MVT::isInteger(VT)) {
3547 if (X86::isPSHUFDMask(PermMask.Val) ||
3548 X86::isPSHUFHWMask(PermMask.Val) ||
3549 X86::isPSHUFLWMask(PermMask.Val)) {
3550 if (V2.getOpcode() != ISD::UNDEF)
3551 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1,
3552 DAG.getNode(ISD::UNDEF, V1.getValueType()),PermMask);
3553 return Op;
3554 }
3555
3556 if (X86::isSHUFPMask(PermMask.Val))
3557 return Op;
3558
3559 // Handle v8i16 shuffle high / low shuffle node pair.
3560 if (VT == MVT::v8i16 && isPSHUFHW_PSHUFLWMask(PermMask.Val)) {
3561 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
3562 MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
3563 std::vector<SDOperand> MaskVec;
3564 for (unsigned i = 0; i != 4; ++i)
3565 MaskVec.push_back(PermMask.getOperand(i));
3566 for (unsigned i = 4; i != 8; ++i)
3567 MaskVec.push_back(DAG.getConstant(i, BaseVT));
Chris Lattnere2199452006-08-11 17:38:39 +00003568 SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3569 &MaskVec[0], MaskVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003570 V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
3571 MaskVec.clear();
3572 for (unsigned i = 0; i != 4; ++i)
3573 MaskVec.push_back(DAG.getConstant(i, BaseVT));
3574 for (unsigned i = 4; i != 8; ++i)
3575 MaskVec.push_back(PermMask.getOperand(i));
Chris Lattnere2199452006-08-11 17:38:39 +00003576 Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0],MaskVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003577 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
3578 }
3579 } else {
3580 // Floating point cases in the other order.
3581 if (X86::isSHUFPMask(PermMask.Val))
3582 return Op;
3583 if (X86::isPSHUFDMask(PermMask.Val) ||
3584 X86::isPSHUFHWMask(PermMask.Val) ||
3585 X86::isPSHUFLWMask(PermMask.Val)) {
3586 if (V2.getOpcode() != ISD::UNDEF)
3587 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1,
3588 DAG.getNode(ISD::UNDEF, V1.getValueType()),PermMask);
3589 return Op;
3590 }
3591 }
3592
3593 if (NumElems == 4) {
Evan Cheng0db9fe62006-04-25 20:13:52 +00003594 MVT::ValueType MaskVT = PermMask.getValueType();
3595 MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
Evan Cheng43f3bd32006-04-28 07:03:38 +00003596 std::vector<std::pair<int, int> > Locs;
3597 Locs.reserve(NumElems);
3598 std::vector<SDOperand> Mask1(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
3599 std::vector<SDOperand> Mask2(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
3600 unsigned NumHi = 0;
3601 unsigned NumLo = 0;
3602 // If no more than two elements come from either vector. This can be
3603 // implemented with two shuffles. First shuffle gather the elements.
3604 // The second shuffle, which takes the first shuffle as both of its
3605 // vector operands, put the elements into the right order.
3606 for (unsigned i = 0; i != NumElems; ++i) {
3607 SDOperand Elt = PermMask.getOperand(i);
3608 if (Elt.getOpcode() == ISD::UNDEF) {
3609 Locs[i] = std::make_pair(-1, -1);
3610 } else {
3611 unsigned Val = cast<ConstantSDNode>(Elt)->getValue();
3612 if (Val < NumElems) {
3613 Locs[i] = std::make_pair(0, NumLo);
3614 Mask1[NumLo] = Elt;
3615 NumLo++;
3616 } else {
3617 Locs[i] = std::make_pair(1, NumHi);
3618 if (2+NumHi < NumElems)
3619 Mask1[2+NumHi] = Elt;
3620 NumHi++;
3621 }
3622 }
3623 }
3624 if (NumLo <= 2 && NumHi <= 2) {
3625 V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
Chris Lattnere2199452006-08-11 17:38:39 +00003626 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3627 &Mask1[0], Mask1.size()));
Evan Cheng43f3bd32006-04-28 07:03:38 +00003628 for (unsigned i = 0; i != NumElems; ++i) {
3629 if (Locs[i].first == -1)
3630 continue;
3631 else {
3632 unsigned Idx = (i < NumElems/2) ? 0 : NumElems;
3633 Idx += Locs[i].first * (NumElems/2) + Locs[i].second;
3634 Mask2[i] = DAG.getConstant(Idx, MaskEVT);
3635 }
3636 }
3637
3638 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1,
Chris Lattnere2199452006-08-11 17:38:39 +00003639 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3640 &Mask2[0], Mask2.size()));
Evan Cheng43f3bd32006-04-28 07:03:38 +00003641 }
3642
3643 // Break it into (shuffle shuffle_hi, shuffle_lo).
3644 Locs.clear();
Evan Cheng0db9fe62006-04-25 20:13:52 +00003645 std::vector<SDOperand> LoMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
3646 std::vector<SDOperand> HiMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
3647 std::vector<SDOperand> *MaskPtr = &LoMask;
3648 unsigned MaskIdx = 0;
3649 unsigned LoIdx = 0;
3650 unsigned HiIdx = NumElems/2;
3651 for (unsigned i = 0; i != NumElems; ++i) {
3652 if (i == NumElems/2) {
3653 MaskPtr = &HiMask;
3654 MaskIdx = 1;
3655 LoIdx = 0;
3656 HiIdx = NumElems/2;
3657 }
3658 SDOperand Elt = PermMask.getOperand(i);
3659 if (Elt.getOpcode() == ISD::UNDEF) {
3660 Locs[i] = std::make_pair(-1, -1);
3661 } else if (cast<ConstantSDNode>(Elt)->getValue() < NumElems) {
3662 Locs[i] = std::make_pair(MaskIdx, LoIdx);
3663 (*MaskPtr)[LoIdx] = Elt;
3664 LoIdx++;
3665 } else {
3666 Locs[i] = std::make_pair(MaskIdx, HiIdx);
3667 (*MaskPtr)[HiIdx] = Elt;
3668 HiIdx++;
3669 }
3670 }
3671
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003672 SDOperand LoShuffle =
3673 DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
Chris Lattnere2199452006-08-11 17:38:39 +00003674 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3675 &LoMask[0], LoMask.size()));
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003676 SDOperand HiShuffle =
3677 DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
Chris Lattnere2199452006-08-11 17:38:39 +00003678 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3679 &HiMask[0], HiMask.size()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003680 std::vector<SDOperand> MaskOps;
3681 for (unsigned i = 0; i != NumElems; ++i) {
3682 if (Locs[i].first == -1) {
3683 MaskOps.push_back(DAG.getNode(ISD::UNDEF, MaskEVT));
3684 } else {
3685 unsigned Idx = Locs[i].first * NumElems + Locs[i].second;
3686 MaskOps.push_back(DAG.getConstant(Idx, MaskEVT));
3687 }
3688 }
3689 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, LoShuffle, HiShuffle,
Chris Lattnere2199452006-08-11 17:38:39 +00003690 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3691 &MaskOps[0], MaskOps.size()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003692 }
3693
3694 return SDOperand();
3695}
3696
3697SDOperand
3698X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
3699 if (!isa<ConstantSDNode>(Op.getOperand(1)))
3700 return SDOperand();
3701
3702 MVT::ValueType VT = Op.getValueType();
3703 // TODO: handle v16i8.
3704 if (MVT::getSizeInBits(VT) == 16) {
3705 // Transform it so it match pextrw which produces a 32-bit result.
3706 MVT::ValueType EVT = (MVT::ValueType)(VT+1);
3707 SDOperand Extract = DAG.getNode(X86ISD::PEXTRW, EVT,
3708 Op.getOperand(0), Op.getOperand(1));
3709 SDOperand Assert = DAG.getNode(ISD::AssertZext, EVT, Extract,
3710 DAG.getValueType(VT));
3711 return DAG.getNode(ISD::TRUNCATE, VT, Assert);
3712 } else if (MVT::getSizeInBits(VT) == 32) {
3713 SDOperand Vec = Op.getOperand(0);
3714 unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
3715 if (Idx == 0)
3716 return Op;
Evan Cheng0db9fe62006-04-25 20:13:52 +00003717 // SHUFPS the element to the lowest double word, then movss.
3718 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003719 std::vector<SDOperand> IdxVec;
3720 IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorBaseType(MaskVT)));
3721 IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
3722 IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
3723 IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
Chris Lattnere2199452006-08-11 17:38:39 +00003724 SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3725 &IdxVec[0], IdxVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003726 Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
3727 Vec, Vec, Mask);
3728 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
Evan Cheng015188f2006-06-15 08:14:54 +00003729 DAG.getConstant(0, getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003730 } else if (MVT::getSizeInBits(VT) == 64) {
3731 SDOperand Vec = Op.getOperand(0);
3732 unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
3733 if (Idx == 0)
3734 return Op;
3735
3736 // UNPCKHPD the element to the lowest double word, then movsd.
3737 // Note if the lower 64 bits of the result of the UNPCKHPD is then stored
3738 // to a f64mem, the whole operation is folded into a single MOVHPDmr.
3739 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
3740 std::vector<SDOperand> IdxVec;
3741 IdxVec.push_back(DAG.getConstant(1, MVT::getVectorBaseType(MaskVT)));
3742 IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
Chris Lattnere2199452006-08-11 17:38:39 +00003743 SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3744 &IdxVec[0], IdxVec.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003745 Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
3746 Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
3747 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
Evan Cheng015188f2006-06-15 08:14:54 +00003748 DAG.getConstant(0, getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003749 }
3750
3751 return SDOperand();
3752}
3753
3754SDOperand
3755X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
Evan Cheng069287d2006-05-16 07:21:53 +00003756 // Transform it so it match pinsrw which expects a 16-bit value in a GR32
Evan Cheng0db9fe62006-04-25 20:13:52 +00003757 // as its second argument.
3758 MVT::ValueType VT = Op.getValueType();
3759 MVT::ValueType BaseVT = MVT::getVectorBaseType(VT);
3760 SDOperand N0 = Op.getOperand(0);
3761 SDOperand N1 = Op.getOperand(1);
3762 SDOperand N2 = Op.getOperand(2);
3763 if (MVT::getSizeInBits(BaseVT) == 16) {
3764 if (N1.getValueType() != MVT::i32)
3765 N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1);
3766 if (N2.getValueType() != MVT::i32)
3767 N2 = DAG.getConstant(cast<ConstantSDNode>(N2)->getValue(), MVT::i32);
3768 return DAG.getNode(X86ISD::PINSRW, VT, N0, N1, N2);
3769 } else if (MVT::getSizeInBits(BaseVT) == 32) {
3770 unsigned Idx = cast<ConstantSDNode>(N2)->getValue();
3771 if (Idx == 0) {
3772 // Use a movss.
3773 N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, N1);
3774 MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
3775 MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
3776 std::vector<SDOperand> MaskVec;
3777 MaskVec.push_back(DAG.getConstant(4, BaseVT));
3778 for (unsigned i = 1; i <= 3; ++i)
3779 MaskVec.push_back(DAG.getConstant(i, BaseVT));
3780 return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, N0, N1,
Chris Lattnere2199452006-08-11 17:38:39 +00003781 DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
3782 &MaskVec[0], MaskVec.size()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003783 } else {
3784 // Use two pinsrw instructions to insert a 32 bit value.
3785 Idx <<= 1;
3786 if (MVT::isFloatingPoint(N1.getValueType())) {
Evan Cheng466685d2006-10-09 20:57:25 +00003787 if (ISD::isNON_EXTLoad(N1.Val)) {
Evan Cheng069287d2006-05-16 07:21:53 +00003788 // Just load directly from f32mem to GR32.
Evan Cheng466685d2006-10-09 20:57:25 +00003789 LoadSDNode *LD = cast<LoadSDNode>(N1);
3790 N1 = DAG.getLoad(MVT::i32, LD->getChain(), LD->getBasePtr(),
3791 LD->getSrcValue(), LD->getSrcValueOffset());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003792 } else {
3793 N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, N1);
3794 N1 = DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, N1);
3795 N1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, N1,
Evan Cheng015188f2006-06-15 08:14:54 +00003796 DAG.getConstant(0, getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003797 }
3798 }
3799 N0 = DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, N0);
3800 N0 = DAG.getNode(X86ISD::PINSRW, MVT::v8i16, N0, N1,
Evan Cheng015188f2006-06-15 08:14:54 +00003801 DAG.getConstant(Idx, getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003802 N1 = DAG.getNode(ISD::SRL, MVT::i32, N1, DAG.getConstant(16, MVT::i8));
3803 N0 = DAG.getNode(X86ISD::PINSRW, MVT::v8i16, N0, N1,
Evan Cheng015188f2006-06-15 08:14:54 +00003804 DAG.getConstant(Idx+1, getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003805 return DAG.getNode(ISD::BIT_CONVERT, VT, N0);
3806 }
3807 }
3808
3809 return SDOperand();
3810}
3811
3812SDOperand
3813X86TargetLowering::LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
3814 SDOperand AnyExt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, Op.getOperand(0));
3815 return DAG.getNode(X86ISD::S2VEC, Op.getValueType(), AnyExt);
3816}
3817
3818// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3819// their target countpart wrapped in the X86ISD::Wrapper node. Suppose N is
3820// one of the above mentioned nodes. It has to be wrapped because otherwise
3821// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3822// be used to form addressing mode. These wrapped nodes will be selected
3823// into MOV32ri.
3824SDOperand
3825X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
3826 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3827 SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
Evan Chengc356a572006-09-12 21:04:05 +00003828 DAG.getTargetConstantPool(CP->getConstVal(),
3829 getPointerTy(),
3830 CP->getAlignment()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003831 if (Subtarget->isTargetDarwin()) {
3832 // With PIC, the address is actually $g + Offset.
Evan Cheng25ab6902006-09-08 06:48:29 +00003833 if (!Subtarget->is64Bit() &&
3834 getTargetMachine().getRelocationModel() == Reloc::PIC_)
Evan Cheng0db9fe62006-04-25 20:13:52 +00003835 Result = DAG.getNode(ISD::ADD, getPointerTy(),
3836 DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
3837 }
3838
3839 return Result;
3840}
3841
3842SDOperand
3843X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
3844 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3845 SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003846 DAG.getTargetGlobalAddress(GV,
3847 getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003848 if (Subtarget->isTargetDarwin()) {
3849 // With PIC, the address is actually $g + Offset.
Evan Cheng25ab6902006-09-08 06:48:29 +00003850 if (!Subtarget->is64Bit() &&
3851 getTargetMachine().getRelocationModel() == Reloc::PIC_)
Evan Cheng0db9fe62006-04-25 20:13:52 +00003852 Result = DAG.getNode(ISD::ADD, getPointerTy(),
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003853 DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
3854 Result);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003855
3856 // For Darwin, external and weak symbols are indirect, so we want to load
3857 // the value at address GV, not the value of GV itself. This means that
3858 // the GlobalAddress must be in the base or index register of the address,
3859 // not the GV offset field.
3860 if (getTargetMachine().getRelocationModel() != Reloc::Static &&
3861 DarwinGVRequiresExtraLoad(GV))
Evan Cheng466685d2006-10-09 20:57:25 +00003862 Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
Anton Korobeynikovb74ed072006-09-14 18:23:27 +00003863 } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) {
Evan Cheng466685d2006-10-09 20:57:25 +00003864 // FIXME: What about PIC?
3865 if (WindowsGVRequiresExtraLoad(GV))
3866 Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003867 }
Anton Korobeynikovb74ed072006-09-14 18:23:27 +00003868
Evan Cheng0db9fe62006-04-25 20:13:52 +00003869
3870 return Result;
3871}
3872
3873SDOperand
3874X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
3875 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
3876 SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003877 DAG.getTargetExternalSymbol(Sym,
3878 getPointerTy()));
Evan Cheng0db9fe62006-04-25 20:13:52 +00003879 if (Subtarget->isTargetDarwin()) {
3880 // With PIC, the address is actually $g + Offset.
Evan Cheng25ab6902006-09-08 06:48:29 +00003881 if (!Subtarget->is64Bit() &&
3882 getTargetMachine().getRelocationModel() == Reloc::PIC_)
Evan Cheng0db9fe62006-04-25 20:13:52 +00003883 Result = DAG.getNode(ISD::ADD, getPointerTy(),
Chris Lattner8c0c10c2006-05-16 06:45:34 +00003884 DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
3885 Result);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003886 }
3887
3888 return Result;
3889}
3890
3891SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
Evan Chenge3413162006-01-09 18:33:28 +00003892 assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
3893 "Not an i64 shift!");
3894 bool isSRA = Op.getOpcode() == ISD::SRA_PARTS;
3895 SDOperand ShOpLo = Op.getOperand(0);
3896 SDOperand ShOpHi = Op.getOperand(1);
3897 SDOperand ShAmt = Op.getOperand(2);
Evan Cheng734503b2006-09-11 02:19:56 +00003898 SDOperand Tmp1 = isSRA ?
3899 DAG.getNode(ISD::SRA, MVT::i32, ShOpHi, DAG.getConstant(31, MVT::i8)) :
3900 DAG.getConstant(0, MVT::i32);
Evan Chenge3413162006-01-09 18:33:28 +00003901
3902 SDOperand Tmp2, Tmp3;
3903 if (Op.getOpcode() == ISD::SHL_PARTS) {
3904 Tmp2 = DAG.getNode(X86ISD::SHLD, MVT::i32, ShOpHi, ShOpLo, ShAmt);
3905 Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, ShOpLo, ShAmt);
3906 } else {
3907 Tmp2 = DAG.getNode(X86ISD::SHRD, MVT::i32, ShOpLo, ShOpHi, ShAmt);
Evan Chengb7b57062006-01-19 01:46:14 +00003908 Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SRL, MVT::i32, ShOpHi, ShAmt);
Evan Chenge3413162006-01-09 18:33:28 +00003909 }
3910
Evan Cheng734503b2006-09-11 02:19:56 +00003911 const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
3912 SDOperand AndNode = DAG.getNode(ISD::AND, MVT::i8, ShAmt,
3913 DAG.getConstant(32, MVT::i8));
3914 SDOperand COps[]={DAG.getEntryNode(), AndNode, DAG.getConstant(0, MVT::i8)};
3915 SDOperand InFlag = DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1);
Evan Chenge3413162006-01-09 18:33:28 +00003916
3917 SDOperand Hi, Lo;
Chris Lattner7fbe9722006-10-20 17:42:20 +00003918 SDOperand CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Evan Chenge3413162006-01-09 18:33:28 +00003919
Evan Cheng734503b2006-09-11 02:19:56 +00003920 VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
3921 SmallVector<SDOperand, 4> Ops;
Evan Chenge3413162006-01-09 18:33:28 +00003922 if (Op.getOpcode() == ISD::SHL_PARTS) {
3923 Ops.push_back(Tmp2);
3924 Ops.push_back(Tmp3);
3925 Ops.push_back(CC);
3926 Ops.push_back(InFlag);
Evan Cheng734503b2006-09-11 02:19:56 +00003927 Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
Evan Chenge3413162006-01-09 18:33:28 +00003928 InFlag = Hi.getValue(1);
3929
3930 Ops.clear();
3931 Ops.push_back(Tmp3);
3932 Ops.push_back(Tmp1);
3933 Ops.push_back(CC);
3934 Ops.push_back(InFlag);
Evan Cheng734503b2006-09-11 02:19:56 +00003935 Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
Evan Chenge3413162006-01-09 18:33:28 +00003936 } else {
3937 Ops.push_back(Tmp2);
3938 Ops.push_back(Tmp3);
3939 Ops.push_back(CC);
Evan Cheng910cd3c2006-01-09 22:29:54 +00003940 Ops.push_back(InFlag);
Evan Cheng734503b2006-09-11 02:19:56 +00003941 Lo = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
Evan Chenge3413162006-01-09 18:33:28 +00003942 InFlag = Lo.getValue(1);
3943
3944 Ops.clear();
3945 Ops.push_back(Tmp3);
3946 Ops.push_back(Tmp1);
3947 Ops.push_back(CC);
3948 Ops.push_back(InFlag);
Evan Cheng734503b2006-09-11 02:19:56 +00003949 Hi = DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
Evan Chenge3413162006-01-09 18:33:28 +00003950 }
3951
Evan Cheng734503b2006-09-11 02:19:56 +00003952 VTs = DAG.getNodeValueTypes(MVT::i32, MVT::i32);
Evan Chenge3413162006-01-09 18:33:28 +00003953 Ops.clear();
3954 Ops.push_back(Lo);
3955 Ops.push_back(Hi);
Evan Cheng734503b2006-09-11 02:19:56 +00003956 return DAG.getNode(ISD::MERGE_VALUES, VTs, 2, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003957}
Evan Chenga3195e82006-01-12 22:54:21 +00003958
Evan Cheng0db9fe62006-04-25 20:13:52 +00003959SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
3960 assert(Op.getOperand(0).getValueType() <= MVT::i64 &&
3961 Op.getOperand(0).getValueType() >= MVT::i16 &&
3962 "Unknown SINT_TO_FP to lower!");
3963
3964 SDOperand Result;
3965 MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
3966 unsigned Size = MVT::getSizeInBits(SrcVT)/8;
3967 MachineFunction &MF = DAG.getMachineFunction();
3968 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
3969 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
Evan Cheng786225a2006-10-05 23:01:46 +00003970 SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Op.getOperand(0),
Evan Cheng8b2794a2006-10-13 21:14:26 +00003971 StackSlot, NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003972
3973 // Build the FILD
3974 std::vector<MVT::ValueType> Tys;
3975 Tys.push_back(MVT::f64);
3976 Tys.push_back(MVT::Other);
3977 if (X86ScalarSSE) Tys.push_back(MVT::Flag);
3978 std::vector<SDOperand> Ops;
3979 Ops.push_back(Chain);
3980 Ops.push_back(StackSlot);
3981 Ops.push_back(DAG.getValueType(SrcVT));
3982 Result = DAG.getNode(X86ScalarSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
Chris Lattnerbd564bf2006-08-08 02:23:42 +00003983 Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00003984
3985 if (X86ScalarSSE) {
3986 Chain = Result.getValue(1);
3987 SDOperand InFlag = Result.getValue(2);
3988
3989 // FIXME: Currently the FST is flagged to the FILD_FLAG. This
3990 // shouldn't be necessary except that RFP cannot be live across
3991 // multiple blocks. When stackifier is fixed, they can be uncoupled.
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00003992 MachineFunction &MF = DAG.getMachineFunction();
Evan Cheng0db9fe62006-04-25 20:13:52 +00003993 int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00003994 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
Evan Chenga3195e82006-01-12 22:54:21 +00003995 std::vector<MVT::ValueType> Tys;
Evan Cheng6dab0532006-01-30 08:02:57 +00003996 Tys.push_back(MVT::Other);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00003997 std::vector<SDOperand> Ops;
Evan Chenga3195e82006-01-12 22:54:21 +00003998 Ops.push_back(Chain);
Evan Cheng0db9fe62006-04-25 20:13:52 +00003999 Ops.push_back(Result);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004000 Ops.push_back(StackSlot);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004001 Ops.push_back(DAG.getValueType(Op.getValueType()));
4002 Ops.push_back(InFlag);
Chris Lattnerbd564bf2006-08-08 02:23:42 +00004003 Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
Evan Cheng466685d2006-10-09 20:57:25 +00004004 Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, NULL, 0);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004005 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004006
Evan Cheng0db9fe62006-04-25 20:13:52 +00004007 return Result;
4008}
4009
4010SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
4011 assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
4012 "Unknown FP_TO_SINT to lower!");
4013 // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
4014 // stack slot.
4015 MachineFunction &MF = DAG.getMachineFunction();
4016 unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
4017 int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
4018 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
4019
4020 unsigned Opc;
4021 switch (Op.getValueType()) {
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004022 default: assert(0 && "Invalid FP_TO_SINT to lower!");
4023 case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
4024 case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
4025 case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004026 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004027
Evan Cheng0db9fe62006-04-25 20:13:52 +00004028 SDOperand Chain = DAG.getEntryNode();
4029 SDOperand Value = Op.getOperand(0);
4030 if (X86ScalarSSE) {
4031 assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
Evan Cheng8b2794a2006-10-13 21:14:26 +00004032 Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004033 std::vector<MVT::ValueType> Tys;
4034 Tys.push_back(MVT::f64);
4035 Tys.push_back(MVT::Other);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004036 std::vector<SDOperand> Ops;
Evan Cheng6dab0532006-01-30 08:02:57 +00004037 Ops.push_back(Chain);
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004038 Ops.push_back(StackSlot);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004039 Ops.push_back(DAG.getValueType(Op.getOperand(0).getValueType()));
Chris Lattnerbd564bf2006-08-08 02:23:42 +00004040 Value = DAG.getNode(X86ISD::FLD, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004041 Chain = Value.getValue(1);
4042 SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
4043 StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
4044 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004045
Evan Cheng0db9fe62006-04-25 20:13:52 +00004046 // Build the FP_TO_INT*_IN_MEM
4047 std::vector<SDOperand> Ops;
4048 Ops.push_back(Chain);
4049 Ops.push_back(Value);
4050 Ops.push_back(StackSlot);
Evan Cheng311ace02006-08-11 07:35:45 +00004051 SDOperand FIST = DAG.getNode(Opc, MVT::Other, &Ops[0], Ops.size());
Evan Chengd9558e02006-01-06 00:43:03 +00004052
Evan Cheng0db9fe62006-04-25 20:13:52 +00004053 // Load the result.
Evan Cheng466685d2006-10-09 20:57:25 +00004054 return DAG.getLoad(Op.getValueType(), FIST, StackSlot, NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004055}
4056
4057SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
4058 MVT::ValueType VT = Op.getValueType();
4059 const Type *OpNTy = MVT::getTypeForValueType(VT);
4060 std::vector<Constant*> CV;
4061 if (VT == MVT::f64) {
4062 CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(~(1ULL << 63))));
4063 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4064 } else {
4065 CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(~(1U << 31))));
4066 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4067 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4068 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4069 }
4070 Constant *CS = ConstantStruct::get(CV);
4071 SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4);
Evan Cheng64a752f2006-08-11 09:08:15 +00004072 std::vector<MVT::ValueType> Tys;
4073 Tys.push_back(VT);
4074 Tys.push_back(MVT::Other);
4075 SmallVector<SDOperand, 3> Ops;
4076 Ops.push_back(DAG.getEntryNode());
4077 Ops.push_back(CPIdx);
4078 Ops.push_back(DAG.getSrcValue(NULL));
4079 SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004080 return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask);
4081}
4082
4083SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
4084 MVT::ValueType VT = Op.getValueType();
4085 const Type *OpNTy = MVT::getTypeForValueType(VT);
4086 std::vector<Constant*> CV;
4087 if (VT == MVT::f64) {
4088 CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(1ULL << 63)));
4089 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4090 } else {
4091 CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(1U << 31)));
4092 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4093 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4094 CV.push_back(ConstantFP::get(OpNTy, 0.0));
4095 }
4096 Constant *CS = ConstantStruct::get(CV);
4097 SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4);
Evan Cheng64a752f2006-08-11 09:08:15 +00004098 std::vector<MVT::ValueType> Tys;
4099 Tys.push_back(VT);
4100 Tys.push_back(MVT::Other);
4101 SmallVector<SDOperand, 3> Ops;
4102 Ops.push_back(DAG.getEntryNode());
4103 Ops.push_back(CPIdx);
4104 Ops.push_back(DAG.getSrcValue(NULL));
4105 SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004106 return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask);
4107}
4108
Evan Cheng734503b2006-09-11 02:19:56 +00004109SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG,
4110 SDOperand Chain) {
Evan Cheng0db9fe62006-04-25 20:13:52 +00004111 assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
4112 SDOperand Cond;
Evan Cheng734503b2006-09-11 02:19:56 +00004113 SDOperand Op0 = Op.getOperand(0);
4114 SDOperand Op1 = Op.getOperand(1);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004115 SDOperand CC = Op.getOperand(2);
4116 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
Evan Chengcf12ec42006-10-12 19:12:56 +00004117 const MVT::ValueType *VTs1 = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
4118 const MVT::ValueType *VTs2 = DAG.getNodeValueTypes(MVT::i8, MVT::Flag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004119 bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004120 unsigned X86CC;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004121
Chris Lattnerf9570512006-09-13 03:22:10 +00004122 if (translateX86CC(cast<CondCodeSDNode>(CC)->get(), isFP, X86CC,
4123 Op0, Op1, DAG)) {
Evan Cheng734503b2006-09-11 02:19:56 +00004124 SDOperand Ops1[] = { Chain, Op0, Op1 };
Evan Chengcf12ec42006-10-12 19:12:56 +00004125 Cond = DAG.getNode(X86ISD::CMP, VTs1, 2, Ops1, 3).getValue(1);
Evan Cheng734503b2006-09-11 02:19:56 +00004126 SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond };
Evan Chengcf12ec42006-10-12 19:12:56 +00004127 return DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops2, 2);
Evan Cheng734503b2006-09-11 02:19:56 +00004128 }
4129
4130 assert(isFP && "Illegal integer SetCC!");
4131
4132 SDOperand COps[] = { Chain, Op0, Op1 };
Evan Chengcf12ec42006-10-12 19:12:56 +00004133 Cond = DAG.getNode(X86ISD::CMP, VTs1, 2, COps, 3).getValue(1);
Evan Cheng734503b2006-09-11 02:19:56 +00004134
4135 switch (SetCCOpcode) {
4136 default: assert(false && "Illegal floating point SetCC!");
4137 case ISD::SETOEQ: { // !PF & ZF
Chris Lattner7fbe9722006-10-20 17:42:20 +00004138 SDOperand Ops1[] = { DAG.getConstant(X86::COND_NP, MVT::i8), Cond };
Evan Chengcf12ec42006-10-12 19:12:56 +00004139 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops1, 2);
Chris Lattner7fbe9722006-10-20 17:42:20 +00004140 SDOperand Ops2[] = { DAG.getConstant(X86::COND_E, MVT::i8),
Evan Cheng734503b2006-09-11 02:19:56 +00004141 Tmp1.getValue(1) };
Evan Chengcf12ec42006-10-12 19:12:56 +00004142 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops2, 2);
Evan Cheng734503b2006-09-11 02:19:56 +00004143 return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
4144 }
4145 case ISD::SETUNE: { // PF | !ZF
Chris Lattner7fbe9722006-10-20 17:42:20 +00004146 SDOperand Ops1[] = { DAG.getConstant(X86::COND_P, MVT::i8), Cond };
Evan Chengcf12ec42006-10-12 19:12:56 +00004147 SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops1, 2);
Chris Lattner7fbe9722006-10-20 17:42:20 +00004148 SDOperand Ops2[] = { DAG.getConstant(X86::COND_NE, MVT::i8),
Evan Cheng734503b2006-09-11 02:19:56 +00004149 Tmp1.getValue(1) };
Evan Chengcf12ec42006-10-12 19:12:56 +00004150 SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops2, 2);
Evan Cheng734503b2006-09-11 02:19:56 +00004151 return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
4152 }
Evan Chengd5781fc2005-12-21 20:21:51 +00004153 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004154}
Evan Cheng6dfa9992006-01-30 23:41:35 +00004155
Evan Cheng0db9fe62006-04-25 20:13:52 +00004156SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
Evan Cheng734503b2006-09-11 02:19:56 +00004157 bool addTest = true;
4158 SDOperand Chain = DAG.getEntryNode();
4159 SDOperand Cond = Op.getOperand(0);
4160 SDOperand CC;
4161 const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
Evan Cheng9bba8942006-01-26 02:13:10 +00004162
Evan Cheng734503b2006-09-11 02:19:56 +00004163 if (Cond.getOpcode() == ISD::SETCC)
4164 Cond = LowerSETCC(Cond, DAG, Chain);
4165
4166 if (Cond.getOpcode() == X86ISD::SETCC) {
4167 CC = Cond.getOperand(0);
4168
Evan Cheng0db9fe62006-04-25 20:13:52 +00004169 // If condition flag is set by a X86ISD::CMP, then make a copy of it
Evan Cheng734503b2006-09-11 02:19:56 +00004170 // (since flag operand cannot be shared). Use it as the condition setting
4171 // operand in place of the X86ISD::SETCC.
4172 // If the X86ISD::SETCC has more than one use, then perhaps it's better
Evan Cheng0db9fe62006-04-25 20:13:52 +00004173 // to use a test instead of duplicating the X86ISD::CMP (for register
Evan Cheng734503b2006-09-11 02:19:56 +00004174 // pressure reason)?
4175 SDOperand Cmp = Cond.getOperand(1);
4176 unsigned Opc = Cmp.getOpcode();
4177 bool IllegalFPCMov = !X86ScalarSSE &&
4178 MVT::isFloatingPoint(Op.getValueType()) &&
4179 !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
4180 if ((Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) &&
4181 !IllegalFPCMov) {
4182 SDOperand Ops[] = { Chain, Cmp.getOperand(1), Cmp.getOperand(2) };
4183 Cond = DAG.getNode(Opc, VTs, 2, Ops, 3);
4184 addTest = false;
4185 }
4186 }
Evan Chengaaca22c2006-01-10 20:26:56 +00004187
Evan Cheng0db9fe62006-04-25 20:13:52 +00004188 if (addTest) {
Chris Lattner7fbe9722006-10-20 17:42:20 +00004189 CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Evan Cheng734503b2006-09-11 02:19:56 +00004190 SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) };
4191 Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3);
Evan Cheng7df96d62005-12-17 01:21:05 +00004192 }
Evan Cheng6dfa9992006-01-30 23:41:35 +00004193
Evan Cheng734503b2006-09-11 02:19:56 +00004194 VTs = DAG.getNodeValueTypes(Op.getValueType(), MVT::Flag);
4195 SmallVector<SDOperand, 4> Ops;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004196 // X86ISD::CMOV means set the result (which is operand 1) to the RHS if
4197 // condition is true.
4198 Ops.push_back(Op.getOperand(2));
4199 Ops.push_back(Op.getOperand(1));
4200 Ops.push_back(CC);
Evan Cheng734503b2006-09-11 02:19:56 +00004201 Ops.push_back(Cond.getValue(1));
4202 return DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004203}
Evan Cheng9bba8942006-01-26 02:13:10 +00004204
Evan Cheng0db9fe62006-04-25 20:13:52 +00004205SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) {
Evan Cheng734503b2006-09-11 02:19:56 +00004206 bool addTest = true;
4207 SDOperand Chain = Op.getOperand(0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004208 SDOperand Cond = Op.getOperand(1);
4209 SDOperand Dest = Op.getOperand(2);
4210 SDOperand CC;
Evan Cheng734503b2006-09-11 02:19:56 +00004211 const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
4212
Evan Cheng0db9fe62006-04-25 20:13:52 +00004213 if (Cond.getOpcode() == ISD::SETCC)
Evan Cheng734503b2006-09-11 02:19:56 +00004214 Cond = LowerSETCC(Cond, DAG, Chain);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004215
4216 if (Cond.getOpcode() == X86ISD::SETCC) {
Evan Cheng734503b2006-09-11 02:19:56 +00004217 CC = Cond.getOperand(0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004218
Evan Cheng734503b2006-09-11 02:19:56 +00004219 // If condition flag is set by a X86ISD::CMP, then make a copy of it
4220 // (since flag operand cannot be shared). Use it as the condition setting
4221 // operand in place of the X86ISD::SETCC.
4222 // If the X86ISD::SETCC has more than one use, then perhaps it's better
4223 // to use a test instead of duplicating the X86ISD::CMP (for register
4224 // pressure reason)?
4225 SDOperand Cmp = Cond.getOperand(1);
4226 unsigned Opc = Cmp.getOpcode();
4227 if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI) {
4228 SDOperand Ops[] = { Chain, Cmp.getOperand(1), Cmp.getOperand(2) };
4229 Cond = DAG.getNode(Opc, VTs, 2, Ops, 3);
4230 addTest = false;
4231 }
4232 }
Evan Cheng1bcee362006-01-13 01:03:02 +00004233
Evan Cheng0db9fe62006-04-25 20:13:52 +00004234 if (addTest) {
Chris Lattner7fbe9722006-10-20 17:42:20 +00004235 CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Evan Cheng734503b2006-09-11 02:19:56 +00004236 SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) };
4237 Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3);
Evan Cheng898101c2005-12-19 23:12:38 +00004238 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004239 return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
Evan Cheng734503b2006-09-11 02:19:56 +00004240 Cond, Op.getOperand(2), CC, Cond.getValue(1));
Evan Cheng0db9fe62006-04-25 20:13:52 +00004241}
Evan Cheng67f92a72006-01-11 22:15:48 +00004242
Evan Cheng0db9fe62006-04-25 20:13:52 +00004243SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
4244 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
4245 SDOperand Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(),
4246 DAG.getTargetJumpTable(JT->getIndex(),
4247 getPointerTy()));
4248 if (Subtarget->isTargetDarwin()) {
4249 // With PIC, the address is actually $g + Offset.
Evan Cheng25ab6902006-09-08 06:48:29 +00004250 if (!Subtarget->is64Bit() &&
4251 getTargetMachine().getRelocationModel() == Reloc::PIC_)
Evan Cheng0db9fe62006-04-25 20:13:52 +00004252 Result = DAG.getNode(ISD::ADD, getPointerTy(),
Chris Lattner8c0c10c2006-05-16 06:45:34 +00004253 DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
4254 Result);
Evan Cheng67f92a72006-01-11 22:15:48 +00004255 }
Evan Chengbbbb2fb2006-02-25 09:55:19 +00004256
Evan Cheng0db9fe62006-04-25 20:13:52 +00004257 return Result;
4258}
Evan Cheng7ccced62006-02-18 00:15:05 +00004259
Evan Cheng32fe1032006-05-25 00:59:30 +00004260SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
4261 unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004262
Evan Cheng25ab6902006-09-08 06:48:29 +00004263 if (Subtarget->is64Bit())
4264 return LowerX86_64CCCCallTo(Op, DAG);
Evan Cheng32fe1032006-05-25 00:59:30 +00004265 else
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004266 switch (CallingConv) {
Chris Lattnerf38f5432006-09-27 18:29:38 +00004267 default:
4268 assert(0 && "Unsupported calling convention");
4269 case CallingConv::Fast:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004270 if (EnableFastCC) {
4271 return LowerFastCCCallTo(Op, DAG, false);
4272 }
4273 // Falls through
Chris Lattnerf38f5432006-09-27 18:29:38 +00004274 case CallingConv::C:
4275 case CallingConv::CSRet:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004276 return LowerCCCCallTo(Op, DAG);
Chris Lattnerf38f5432006-09-27 18:29:38 +00004277 case CallingConv::X86_StdCall:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004278 return LowerStdCallCCCallTo(Op, DAG);
Chris Lattnerf38f5432006-09-27 18:29:38 +00004279 case CallingConv::X86_FastCall:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004280 return LowerFastCCCallTo(Op, DAG, true);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004281 }
Evan Cheng32fe1032006-05-25 00:59:30 +00004282}
4283
Evan Cheng0db9fe62006-04-25 20:13:52 +00004284SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
4285 SDOperand Copy;
Nate Begemanee625572006-01-27 21:09:22 +00004286
Evan Cheng0db9fe62006-04-25 20:13:52 +00004287 switch(Op.getNumOperands()) {
Nate Begemanee625572006-01-27 21:09:22 +00004288 default:
4289 assert(0 && "Do not know how to return this many arguments!");
4290 abort();
Chris Lattnerb2be4032006-04-17 20:32:50 +00004291 case 1: // ret void.
Nate Begemanee625572006-01-27 21:09:22 +00004292 return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
Evan Cheng0db9fe62006-04-25 20:13:52 +00004293 DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
Evan Cheng6848be12006-05-26 23:10:12 +00004294 case 3: {
Nate Begemanee625572006-01-27 21:09:22 +00004295 MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
Chris Lattnerb2be4032006-04-17 20:32:50 +00004296
Evan Cheng25ab6902006-09-08 06:48:29 +00004297 if (MVT::isVector(ArgVT) ||
4298 (Subtarget->is64Bit() && MVT::isFloatingPoint(ArgVT))) {
Chris Lattnerb2be4032006-04-17 20:32:50 +00004299 // Integer or FP vector result -> XMM0.
4300 if (DAG.getMachineFunction().liveout_empty())
4301 DAG.getMachineFunction().addLiveOut(X86::XMM0);
4302 Copy = DAG.getCopyToReg(Op.getOperand(0), X86::XMM0, Op.getOperand(1),
4303 SDOperand());
4304 } else if (MVT::isInteger(ArgVT)) {
Evan Cheng25ab6902006-09-08 06:48:29 +00004305 // Integer result -> EAX / RAX.
4306 // The C calling convention guarantees the return value has been
4307 // promoted to at least MVT::i32. The X86-64 ABI doesn't require the
4308 // value to be promoted MVT::i64. So we don't have to extend it to
4309 // 64-bit. Return the value in EAX, but mark RAX as liveout.
4310 unsigned Reg = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
Chris Lattnerb2be4032006-04-17 20:32:50 +00004311 if (DAG.getMachineFunction().liveout_empty())
Evan Cheng25ab6902006-09-08 06:48:29 +00004312 DAG.getMachineFunction().addLiveOut(Reg);
Chris Lattnerb2be4032006-04-17 20:32:50 +00004313
Evan Cheng25ab6902006-09-08 06:48:29 +00004314 Reg = (ArgVT == MVT::i64) ? X86::RAX : X86::EAX;
4315 Copy = DAG.getCopyToReg(Op.getOperand(0), Reg, Op.getOperand(1),
Nate Begemanee625572006-01-27 21:09:22 +00004316 SDOperand());
Chris Lattnerb2be4032006-04-17 20:32:50 +00004317 } else if (!X86ScalarSSE) {
4318 // FP return with fp-stack value.
4319 if (DAG.getMachineFunction().liveout_empty())
4320 DAG.getMachineFunction().addLiveOut(X86::ST0);
4321
Nate Begemanee625572006-01-27 21:09:22 +00004322 std::vector<MVT::ValueType> Tys;
4323 Tys.push_back(MVT::Other);
4324 Tys.push_back(MVT::Flag);
4325 std::vector<SDOperand> Ops;
4326 Ops.push_back(Op.getOperand(0));
4327 Ops.push_back(Op.getOperand(1));
Evan Cheng311ace02006-08-11 07:35:45 +00004328 Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, &Ops[0], Ops.size());
Nate Begemanee625572006-01-27 21:09:22 +00004329 } else {
Chris Lattnerb2be4032006-04-17 20:32:50 +00004330 // FP return with ScalarSSE (return on fp-stack).
4331 if (DAG.getMachineFunction().liveout_empty())
4332 DAG.getMachineFunction().addLiveOut(X86::ST0);
4333
Evan Cheng0d084c92006-02-01 00:20:21 +00004334 SDOperand MemLoc;
4335 SDOperand Chain = Op.getOperand(0);
Evan Cheng0e8671b2006-01-31 23:19:54 +00004336 SDOperand Value = Op.getOperand(1);
4337
Evan Cheng466685d2006-10-09 20:57:25 +00004338 if (ISD::isNON_EXTLoad(Value.Val) &&
Evan Cheng760df292006-02-01 01:19:32 +00004339 (Chain == Value.getValue(1) || Chain == Value.getOperand(0))) {
Evan Cheng0e8671b2006-01-31 23:19:54 +00004340 Chain = Value.getOperand(0);
4341 MemLoc = Value.getOperand(1);
4342 } else {
4343 // Spill the value to memory and reload it into top of stack.
4344 unsigned Size = MVT::getSizeInBits(ArgVT)/8;
4345 MachineFunction &MF = DAG.getMachineFunction();
4346 int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
4347 MemLoc = DAG.getFrameIndex(SSFI, getPointerTy());
Evan Cheng8b2794a2006-10-13 21:14:26 +00004348 Chain = DAG.getStore(Op.getOperand(0), Value, MemLoc, NULL, 0);
Evan Cheng0e8671b2006-01-31 23:19:54 +00004349 }
Nate Begemanee625572006-01-27 21:09:22 +00004350 std::vector<MVT::ValueType> Tys;
4351 Tys.push_back(MVT::f64);
4352 Tys.push_back(MVT::Other);
4353 std::vector<SDOperand> Ops;
4354 Ops.push_back(Chain);
Evan Cheng0e8671b2006-01-31 23:19:54 +00004355 Ops.push_back(MemLoc);
Nate Begemanee625572006-01-27 21:09:22 +00004356 Ops.push_back(DAG.getValueType(ArgVT));
Evan Cheng311ace02006-08-11 07:35:45 +00004357 Copy = DAG.getNode(X86ISD::FLD, Tys, &Ops[0], Ops.size());
Nate Begemanee625572006-01-27 21:09:22 +00004358 Tys.clear();
4359 Tys.push_back(MVT::Other);
4360 Tys.push_back(MVT::Flag);
4361 Ops.clear();
4362 Ops.push_back(Copy.getValue(1));
4363 Ops.push_back(Copy);
Evan Cheng311ace02006-08-11 07:35:45 +00004364 Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, &Ops[0], Ops.size());
Nate Begemanee625572006-01-27 21:09:22 +00004365 }
4366 break;
4367 }
Evan Cheng25ab6902006-09-08 06:48:29 +00004368 case 5: {
4369 unsigned Reg1 = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
4370 unsigned Reg2 = Subtarget->is64Bit() ? X86::RDX : X86::EDX;
Chris Lattnerb2be4032006-04-17 20:32:50 +00004371 if (DAG.getMachineFunction().liveout_empty()) {
Evan Cheng25ab6902006-09-08 06:48:29 +00004372 DAG.getMachineFunction().addLiveOut(Reg1);
4373 DAG.getMachineFunction().addLiveOut(Reg2);
Chris Lattnerb2be4032006-04-17 20:32:50 +00004374 }
4375
Evan Cheng25ab6902006-09-08 06:48:29 +00004376 Copy = DAG.getCopyToReg(Op.getOperand(0), Reg2, Op.getOperand(3),
Nate Begemanee625572006-01-27 21:09:22 +00004377 SDOperand());
Evan Cheng25ab6902006-09-08 06:48:29 +00004378 Copy = DAG.getCopyToReg(Copy, Reg1, Op.getOperand(1), Copy.getValue(1));
Nate Begemanee625572006-01-27 21:09:22 +00004379 break;
Evan Cheng25ab6902006-09-08 06:48:29 +00004380 }
Nate Begemanee625572006-01-27 21:09:22 +00004381 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004382 return DAG.getNode(X86ISD::RET_FLAG, MVT::Other,
Evan Cheng25ab6902006-09-08 06:48:29 +00004383 Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16),
Evan Cheng0db9fe62006-04-25 20:13:52 +00004384 Copy.getValue(1));
4385}
4386
Evan Cheng1bc78042006-04-26 01:20:17 +00004387SDOperand
4388X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
Evan Chenge8bd0a32006-06-06 23:30:24 +00004389 MachineFunction &MF = DAG.getMachineFunction();
4390 const Function* Fn = MF.getFunction();
4391 if (Fn->hasExternalLinkage() &&
Anton Korobeynikovbcb97702006-09-17 20:25:45 +00004392 Subtarget->isTargetCygwin() &&
Evan Chengb12223e2006-06-09 06:24:42 +00004393 Fn->getName() == "main")
Evan Chenge8bd0a32006-06-06 23:30:24 +00004394 MF.getInfo<X86FunctionInfo>()->setForceFramePointer(true);
4395
Evan Cheng25caf632006-05-23 21:06:34 +00004396 unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
Evan Cheng25ab6902006-09-08 06:48:29 +00004397 if (Subtarget->is64Bit())
4398 return LowerX86_64CCCArguments(Op, DAG);
Evan Cheng25caf632006-05-23 21:06:34 +00004399 else
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004400 switch(CC) {
Chris Lattnerf38f5432006-09-27 18:29:38 +00004401 default:
4402 assert(0 && "Unsupported calling convention");
4403 case CallingConv::Fast:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004404 if (EnableFastCC) {
4405 return LowerFastCCArguments(Op, DAG);
4406 }
4407 // Falls through
Chris Lattnerf38f5432006-09-27 18:29:38 +00004408 case CallingConv::C:
4409 case CallingConv::CSRet:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004410 return LowerCCCArguments(Op, DAG);
Chris Lattnerf38f5432006-09-27 18:29:38 +00004411 case CallingConv::X86_StdCall:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004412 MF.getInfo<X86FunctionInfo>()->setDecorationStyle(StdCall);
4413 return LowerStdCallCCArguments(Op, DAG);
Chris Lattnerf38f5432006-09-27 18:29:38 +00004414 case CallingConv::X86_FastCall:
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004415 MF.getInfo<X86FunctionInfo>()->setDecorationStyle(FastCall);
4416 return LowerFastCallCCArguments(Op, DAG);
Anton Korobeynikovf8248682006-09-20 22:03:51 +00004417 }
Evan Cheng1bc78042006-04-26 01:20:17 +00004418}
4419
Evan Cheng0db9fe62006-04-25 20:13:52 +00004420SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
4421 SDOperand InFlag(0, 0);
4422 SDOperand Chain = Op.getOperand(0);
4423 unsigned Align =
4424 (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
4425 if (Align == 0) Align = 1;
4426
4427 ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3));
4428 // If not DWORD aligned, call memset if size is less than the threshold.
4429 // It knows how to align to the right boundary first.
4430 if ((Align & 3) != 0 ||
4431 (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
4432 MVT::ValueType IntPtr = getPointerTy();
Owen Andersona69571c2006-05-03 01:29:57 +00004433 const Type *IntPtrTy = getTargetData()->getIntPtrType();
Evan Cheng0db9fe62006-04-25 20:13:52 +00004434 std::vector<std::pair<SDOperand, const Type*> > Args;
4435 Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
4436 // Extend the ubyte argument to be an int value for the call.
4437 SDOperand Val = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Op.getOperand(2));
4438 Args.push_back(std::make_pair(Val, IntPtrTy));
4439 Args.push_back(std::make_pair(Op.getOperand(3), IntPtrTy));
4440 std::pair<SDOperand,SDOperand> CallResult =
4441 LowerCallTo(Chain, Type::VoidTy, false, CallingConv::C, false,
4442 DAG.getExternalSymbol("memset", IntPtr), Args, DAG);
4443 return CallResult.second;
Evan Cheng48090aa2006-03-21 23:01:21 +00004444 }
Evan Chengb9df0ca2006-03-22 02:53:00 +00004445
Evan Cheng0db9fe62006-04-25 20:13:52 +00004446 MVT::ValueType AVT;
4447 SDOperand Count;
4448 ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Op.getOperand(2));
4449 unsigned BytesLeft = 0;
4450 bool TwoRepStos = false;
4451 if (ValC) {
4452 unsigned ValReg;
Evan Cheng25ab6902006-09-08 06:48:29 +00004453 uint64_t Val = ValC->getValue() & 255;
Evan Cheng5ced1d82006-04-06 23:23:56 +00004454
Evan Cheng0db9fe62006-04-25 20:13:52 +00004455 // If the value is a constant, then we can potentially use larger sets.
4456 switch (Align & 3) {
4457 case 2: // WORD aligned
4458 AVT = MVT::i16;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004459 ValReg = X86::AX;
Evan Cheng25ab6902006-09-08 06:48:29 +00004460 Val = (Val << 8) | Val;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004461 break;
Evan Cheng25ab6902006-09-08 06:48:29 +00004462 case 0: // DWORD aligned
Evan Cheng0db9fe62006-04-25 20:13:52 +00004463 AVT = MVT::i32;
Evan Cheng25ab6902006-09-08 06:48:29 +00004464 ValReg = X86::EAX;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004465 Val = (Val << 8) | Val;
4466 Val = (Val << 16) | Val;
Evan Cheng25ab6902006-09-08 06:48:29 +00004467 if (Subtarget->is64Bit() && ((Align & 0xF) == 0)) { // QWORD aligned
4468 AVT = MVT::i64;
4469 ValReg = X86::RAX;
4470 Val = (Val << 32) | Val;
4471 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004472 break;
4473 default: // Byte aligned
4474 AVT = MVT::i8;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004475 ValReg = X86::AL;
Evan Cheng25ab6902006-09-08 06:48:29 +00004476 Count = Op.getOperand(3);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004477 break;
Evan Cheng80d428c2006-04-19 22:48:17 +00004478 }
4479
Evan Cheng25ab6902006-09-08 06:48:29 +00004480 if (AVT > MVT::i8) {
4481 if (I) {
4482 unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
4483 Count = DAG.getConstant(I->getValue() / UBytes, getPointerTy());
4484 BytesLeft = I->getValue() % UBytes;
4485 } else {
4486 assert(AVT >= MVT::i32 &&
4487 "Do not use rep;stos if not at least DWORD aligned");
4488 Count = DAG.getNode(ISD::SRL, Op.getOperand(3).getValueType(),
4489 Op.getOperand(3), DAG.getConstant(2, MVT::i8));
4490 TwoRepStos = true;
4491 }
4492 }
4493
Evan Cheng0db9fe62006-04-25 20:13:52 +00004494 Chain = DAG.getCopyToReg(Chain, ValReg, DAG.getConstant(Val, AVT),
4495 InFlag);
4496 InFlag = Chain.getValue(1);
4497 } else {
4498 AVT = MVT::i8;
4499 Count = Op.getOperand(3);
4500 Chain = DAG.getCopyToReg(Chain, X86::AL, Op.getOperand(2), InFlag);
4501 InFlag = Chain.getValue(1);
Evan Chengb9df0ca2006-03-22 02:53:00 +00004502 }
Evan Chengc78d3b42006-04-24 18:01:45 +00004503
Evan Cheng25ab6902006-09-08 06:48:29 +00004504 Chain = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RCX : X86::ECX,
4505 Count, InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004506 InFlag = Chain.getValue(1);
Evan Cheng25ab6902006-09-08 06:48:29 +00004507 Chain = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RDI : X86::EDI,
4508 Op.getOperand(1), InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004509 InFlag = Chain.getValue(1);
Evan Chenga0b3afb2006-03-27 07:00:16 +00004510
Evan Cheng0db9fe62006-04-25 20:13:52 +00004511 std::vector<MVT::ValueType> Tys;
4512 Tys.push_back(MVT::Other);
4513 Tys.push_back(MVT::Flag);
4514 std::vector<SDOperand> Ops;
4515 Ops.push_back(Chain);
4516 Ops.push_back(DAG.getValueType(AVT));
4517 Ops.push_back(InFlag);
Evan Cheng311ace02006-08-11 07:35:45 +00004518 Chain = DAG.getNode(X86ISD::REP_STOS, Tys, &Ops[0], Ops.size());
Evan Chengc78d3b42006-04-24 18:01:45 +00004519
Evan Cheng0db9fe62006-04-25 20:13:52 +00004520 if (TwoRepStos) {
4521 InFlag = Chain.getValue(1);
4522 Count = Op.getOperand(3);
4523 MVT::ValueType CVT = Count.getValueType();
4524 SDOperand Left = DAG.getNode(ISD::AND, CVT, Count,
Evan Cheng25ab6902006-09-08 06:48:29 +00004525 DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
4526 Chain = DAG.getCopyToReg(Chain, (CVT == MVT::i64) ? X86::RCX : X86::ECX,
4527 Left, InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004528 InFlag = Chain.getValue(1);
4529 Tys.clear();
4530 Tys.push_back(MVT::Other);
4531 Tys.push_back(MVT::Flag);
4532 Ops.clear();
4533 Ops.push_back(Chain);
4534 Ops.push_back(DAG.getValueType(MVT::i8));
4535 Ops.push_back(InFlag);
Evan Cheng311ace02006-08-11 07:35:45 +00004536 Chain = DAG.getNode(X86ISD::REP_STOS, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004537 } else if (BytesLeft) {
Evan Cheng25ab6902006-09-08 06:48:29 +00004538 // Issue stores for the last 1 - 7 bytes.
Evan Cheng0db9fe62006-04-25 20:13:52 +00004539 SDOperand Value;
4540 unsigned Val = ValC->getValue() & 255;
4541 unsigned Offset = I->getValue() - BytesLeft;
4542 SDOperand DstAddr = Op.getOperand(1);
4543 MVT::ValueType AddrVT = DstAddr.getValueType();
Evan Cheng25ab6902006-09-08 06:48:29 +00004544 if (BytesLeft >= 4) {
4545 Val = (Val << 8) | Val;
4546 Val = (Val << 16) | Val;
4547 Value = DAG.getConstant(Val, MVT::i32);
Evan Cheng786225a2006-10-05 23:01:46 +00004548 Chain = DAG.getStore(Chain, Value,
4549 DAG.getNode(ISD::ADD, AddrVT, DstAddr,
4550 DAG.getConstant(Offset, AddrVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004551 NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +00004552 BytesLeft -= 4;
4553 Offset += 4;
4554 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004555 if (BytesLeft >= 2) {
4556 Value = DAG.getConstant((Val << 8) | Val, MVT::i16);
Evan Cheng786225a2006-10-05 23:01:46 +00004557 Chain = DAG.getStore(Chain, Value,
4558 DAG.getNode(ISD::ADD, AddrVT, DstAddr,
4559 DAG.getConstant(Offset, AddrVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004560 NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004561 BytesLeft -= 2;
4562 Offset += 2;
Evan Cheng386031a2006-03-24 07:29:27 +00004563 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004564 if (BytesLeft == 1) {
4565 Value = DAG.getConstant(Val, MVT::i8);
Evan Cheng786225a2006-10-05 23:01:46 +00004566 Chain = DAG.getStore(Chain, Value,
4567 DAG.getNode(ISD::ADD, AddrVT, DstAddr,
4568 DAG.getConstant(Offset, AddrVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004569 NULL, 0);
Evan Chengba05f722006-04-21 23:03:30 +00004570 }
Evan Cheng386031a2006-03-24 07:29:27 +00004571 }
Evan Cheng11e15b32006-04-03 20:53:28 +00004572
Evan Cheng0db9fe62006-04-25 20:13:52 +00004573 return Chain;
4574}
Evan Cheng11e15b32006-04-03 20:53:28 +00004575
Evan Cheng0db9fe62006-04-25 20:13:52 +00004576SDOperand X86TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
4577 SDOperand Chain = Op.getOperand(0);
4578 unsigned Align =
4579 (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
4580 if (Align == 0) Align = 1;
Evan Cheng11e15b32006-04-03 20:53:28 +00004581
Evan Cheng0db9fe62006-04-25 20:13:52 +00004582 ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3));
4583 // If not DWORD aligned, call memcpy if size is less than the threshold.
4584 // It knows how to align to the right boundary first.
4585 if ((Align & 3) != 0 ||
4586 (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
4587 MVT::ValueType IntPtr = getPointerTy();
Owen Andersona69571c2006-05-03 01:29:57 +00004588 const Type *IntPtrTy = getTargetData()->getIntPtrType();
Evan Cheng0db9fe62006-04-25 20:13:52 +00004589 std::vector<std::pair<SDOperand, const Type*> > Args;
4590 Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
4591 Args.push_back(std::make_pair(Op.getOperand(2), IntPtrTy));
4592 Args.push_back(std::make_pair(Op.getOperand(3), IntPtrTy));
4593 std::pair<SDOperand,SDOperand> CallResult =
4594 LowerCallTo(Chain, Type::VoidTy, false, CallingConv::C, false,
4595 DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
4596 return CallResult.second;
Evan Chengb067a1e2006-03-31 19:22:53 +00004597 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004598
4599 MVT::ValueType AVT;
4600 SDOperand Count;
4601 unsigned BytesLeft = 0;
4602 bool TwoRepMovs = false;
4603 switch (Align & 3) {
4604 case 2: // WORD aligned
4605 AVT = MVT::i16;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004606 break;
Evan Cheng25ab6902006-09-08 06:48:29 +00004607 case 0: // DWORD aligned
Evan Cheng0db9fe62006-04-25 20:13:52 +00004608 AVT = MVT::i32;
Evan Cheng25ab6902006-09-08 06:48:29 +00004609 if (Subtarget->is64Bit() && ((Align & 0xF) == 0)) // QWORD aligned
4610 AVT = MVT::i64;
Evan Cheng0db9fe62006-04-25 20:13:52 +00004611 break;
4612 default: // Byte aligned
4613 AVT = MVT::i8;
4614 Count = Op.getOperand(3);
4615 break;
4616 }
4617
Evan Cheng25ab6902006-09-08 06:48:29 +00004618 if (AVT > MVT::i8) {
4619 if (I) {
4620 unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
4621 Count = DAG.getConstant(I->getValue() / UBytes, getPointerTy());
4622 BytesLeft = I->getValue() % UBytes;
4623 } else {
4624 assert(AVT >= MVT::i32 &&
4625 "Do not use rep;movs if not at least DWORD aligned");
4626 Count = DAG.getNode(ISD::SRL, Op.getOperand(3).getValueType(),
4627 Op.getOperand(3), DAG.getConstant(2, MVT::i8));
4628 TwoRepMovs = true;
4629 }
4630 }
4631
Evan Cheng0db9fe62006-04-25 20:13:52 +00004632 SDOperand InFlag(0, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +00004633 Chain = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RCX : X86::ECX,
4634 Count, InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004635 InFlag = Chain.getValue(1);
Evan Cheng25ab6902006-09-08 06:48:29 +00004636 Chain = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RDI : X86::EDI,
4637 Op.getOperand(1), InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004638 InFlag = Chain.getValue(1);
Evan Cheng25ab6902006-09-08 06:48:29 +00004639 Chain = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RSI : X86::ESI,
4640 Op.getOperand(2), InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004641 InFlag = Chain.getValue(1);
4642
4643 std::vector<MVT::ValueType> Tys;
4644 Tys.push_back(MVT::Other);
4645 Tys.push_back(MVT::Flag);
4646 std::vector<SDOperand> Ops;
4647 Ops.push_back(Chain);
4648 Ops.push_back(DAG.getValueType(AVT));
4649 Ops.push_back(InFlag);
Evan Cheng311ace02006-08-11 07:35:45 +00004650 Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004651
4652 if (TwoRepMovs) {
4653 InFlag = Chain.getValue(1);
4654 Count = Op.getOperand(3);
4655 MVT::ValueType CVT = Count.getValueType();
4656 SDOperand Left = DAG.getNode(ISD::AND, CVT, Count,
Evan Cheng25ab6902006-09-08 06:48:29 +00004657 DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
4658 Chain = DAG.getCopyToReg(Chain, (CVT == MVT::i64) ? X86::RCX : X86::ECX,
4659 Left, InFlag);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004660 InFlag = Chain.getValue(1);
4661 Tys.clear();
4662 Tys.push_back(MVT::Other);
4663 Tys.push_back(MVT::Flag);
4664 Ops.clear();
4665 Ops.push_back(Chain);
4666 Ops.push_back(DAG.getValueType(MVT::i8));
4667 Ops.push_back(InFlag);
Evan Cheng311ace02006-08-11 07:35:45 +00004668 Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004669 } else if (BytesLeft) {
Evan Cheng25ab6902006-09-08 06:48:29 +00004670 // Issue loads and stores for the last 1 - 7 bytes.
Evan Cheng0db9fe62006-04-25 20:13:52 +00004671 unsigned Offset = I->getValue() - BytesLeft;
4672 SDOperand DstAddr = Op.getOperand(1);
4673 MVT::ValueType DstVT = DstAddr.getValueType();
4674 SDOperand SrcAddr = Op.getOperand(2);
4675 MVT::ValueType SrcVT = SrcAddr.getValueType();
4676 SDOperand Value;
Evan Cheng25ab6902006-09-08 06:48:29 +00004677 if (BytesLeft >= 4) {
4678 Value = DAG.getLoad(MVT::i32, Chain,
4679 DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
4680 DAG.getConstant(Offset, SrcVT)),
Evan Cheng466685d2006-10-09 20:57:25 +00004681 NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +00004682 Chain = Value.getValue(1);
Evan Cheng786225a2006-10-05 23:01:46 +00004683 Chain = DAG.getStore(Chain, Value,
4684 DAG.getNode(ISD::ADD, DstVT, DstAddr,
4685 DAG.getConstant(Offset, DstVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004686 NULL, 0);
Evan Cheng25ab6902006-09-08 06:48:29 +00004687 BytesLeft -= 4;
4688 Offset += 4;
4689 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004690 if (BytesLeft >= 2) {
4691 Value = DAG.getLoad(MVT::i16, Chain,
4692 DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
4693 DAG.getConstant(Offset, SrcVT)),
Evan Cheng466685d2006-10-09 20:57:25 +00004694 NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004695 Chain = Value.getValue(1);
Evan Cheng786225a2006-10-05 23:01:46 +00004696 Chain = DAG.getStore(Chain, Value,
4697 DAG.getNode(ISD::ADD, DstVT, DstAddr,
4698 DAG.getConstant(Offset, DstVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004699 NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004700 BytesLeft -= 2;
4701 Offset += 2;
Evan Chengb067a1e2006-03-31 19:22:53 +00004702 }
4703
Evan Cheng0db9fe62006-04-25 20:13:52 +00004704 if (BytesLeft == 1) {
4705 Value = DAG.getLoad(MVT::i8, Chain,
4706 DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
4707 DAG.getConstant(Offset, SrcVT)),
Evan Cheng466685d2006-10-09 20:57:25 +00004708 NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004709 Chain = Value.getValue(1);
Evan Cheng786225a2006-10-05 23:01:46 +00004710 Chain = DAG.getStore(Chain, Value,
4711 DAG.getNode(ISD::ADD, DstVT, DstAddr,
4712 DAG.getConstant(Offset, DstVT)),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004713 NULL, 0);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004714 }
Evan Chengb067a1e2006-03-31 19:22:53 +00004715 }
Evan Cheng0db9fe62006-04-25 20:13:52 +00004716
4717 return Chain;
4718}
4719
4720SDOperand
4721X86TargetLowering::LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG) {
4722 std::vector<MVT::ValueType> Tys;
4723 Tys.push_back(MVT::Other);
4724 Tys.push_back(MVT::Flag);
4725 std::vector<SDOperand> Ops;
4726 Ops.push_back(Op.getOperand(0));
Evan Cheng311ace02006-08-11 07:35:45 +00004727 SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004728 Ops.clear();
4729 Ops.push_back(DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)));
4730 Ops.push_back(DAG.getCopyFromReg(Ops[0].getValue(1), X86::EDX,
4731 MVT::i32, Ops[0].getValue(2)));
4732 Ops.push_back(Ops[1].getValue(1));
4733 Tys[0] = Tys[1] = MVT::i32;
4734 Tys.push_back(MVT::Other);
Evan Cheng311ace02006-08-11 07:35:45 +00004735 return DAG.getNode(ISD::MERGE_VALUES, Tys, &Ops[0], Ops.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004736}
4737
4738SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
Evan Cheng8b2794a2006-10-13 21:14:26 +00004739 SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
4740
Evan Cheng25ab6902006-09-08 06:48:29 +00004741 if (!Subtarget->is64Bit()) {
4742 // vastart just stores the address of the VarArgsFrameIndex slot into the
4743 // memory location argument.
4744 SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
Evan Cheng8b2794a2006-10-13 21:14:26 +00004745 return DAG.getStore(Op.getOperand(0), FR,Op.getOperand(1), SV->getValue(),
4746 SV->getOffset());
Evan Cheng25ab6902006-09-08 06:48:29 +00004747 }
4748
4749 // __va_list_tag:
4750 // gp_offset (0 - 6 * 8)
4751 // fp_offset (48 - 48 + 8 * 16)
4752 // overflow_arg_area (point to parameters coming in memory).
4753 // reg_save_area
4754 std::vector<SDOperand> MemOps;
4755 SDOperand FIN = Op.getOperand(1);
4756 // Store gp_offset
Evan Cheng786225a2006-10-05 23:01:46 +00004757 SDOperand Store = DAG.getStore(Op.getOperand(0),
4758 DAG.getConstant(VarArgsGPOffset, MVT::i32),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004759 FIN, SV->getValue(), SV->getOffset());
Evan Cheng25ab6902006-09-08 06:48:29 +00004760 MemOps.push_back(Store);
4761
4762 // Store fp_offset
4763 FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
4764 DAG.getConstant(4, getPointerTy()));
Evan Cheng786225a2006-10-05 23:01:46 +00004765 Store = DAG.getStore(Op.getOperand(0),
4766 DAG.getConstant(VarArgsFPOffset, MVT::i32),
Evan Cheng8b2794a2006-10-13 21:14:26 +00004767 FIN, SV->getValue(), SV->getOffset());
Evan Cheng25ab6902006-09-08 06:48:29 +00004768 MemOps.push_back(Store);
4769
4770 // Store ptr to overflow_arg_area
4771 FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
4772 DAG.getConstant(4, getPointerTy()));
4773 SDOperand OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
Evan Cheng8b2794a2006-10-13 21:14:26 +00004774 Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV->getValue(),
4775 SV->getOffset());
Evan Cheng25ab6902006-09-08 06:48:29 +00004776 MemOps.push_back(Store);
4777
4778 // Store ptr to reg_save_area.
4779 FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
4780 DAG.getConstant(8, getPointerTy()));
4781 SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
Evan Cheng8b2794a2006-10-13 21:14:26 +00004782 Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV->getValue(),
4783 SV->getOffset());
Evan Cheng25ab6902006-09-08 06:48:29 +00004784 MemOps.push_back(Store);
4785 return DAG.getNode(ISD::TokenFactor, MVT::Other, &MemOps[0], MemOps.size());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004786}
4787
4788SDOperand
4789X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
4790 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getValue();
4791 switch (IntNo) {
4792 default: return SDOperand(); // Don't custom lower most intrinsics.
Evan Cheng6be2c582006-04-05 23:38:46 +00004793 // Comparison intrinsics.
Evan Cheng0db9fe62006-04-25 20:13:52 +00004794 case Intrinsic::x86_sse_comieq_ss:
4795 case Intrinsic::x86_sse_comilt_ss:
4796 case Intrinsic::x86_sse_comile_ss:
4797 case Intrinsic::x86_sse_comigt_ss:
4798 case Intrinsic::x86_sse_comige_ss:
4799 case Intrinsic::x86_sse_comineq_ss:
4800 case Intrinsic::x86_sse_ucomieq_ss:
4801 case Intrinsic::x86_sse_ucomilt_ss:
4802 case Intrinsic::x86_sse_ucomile_ss:
4803 case Intrinsic::x86_sse_ucomigt_ss:
4804 case Intrinsic::x86_sse_ucomige_ss:
4805 case Intrinsic::x86_sse_ucomineq_ss:
4806 case Intrinsic::x86_sse2_comieq_sd:
4807 case Intrinsic::x86_sse2_comilt_sd:
4808 case Intrinsic::x86_sse2_comile_sd:
4809 case Intrinsic::x86_sse2_comigt_sd:
4810 case Intrinsic::x86_sse2_comige_sd:
4811 case Intrinsic::x86_sse2_comineq_sd:
4812 case Intrinsic::x86_sse2_ucomieq_sd:
4813 case Intrinsic::x86_sse2_ucomilt_sd:
4814 case Intrinsic::x86_sse2_ucomile_sd:
4815 case Intrinsic::x86_sse2_ucomigt_sd:
4816 case Intrinsic::x86_sse2_ucomige_sd:
4817 case Intrinsic::x86_sse2_ucomineq_sd: {
4818 unsigned Opc = 0;
4819 ISD::CondCode CC = ISD::SETCC_INVALID;
4820 switch (IntNo) {
4821 default: break;
4822 case Intrinsic::x86_sse_comieq_ss:
4823 case Intrinsic::x86_sse2_comieq_sd:
4824 Opc = X86ISD::COMI;
4825 CC = ISD::SETEQ;
4826 break;
Evan Cheng6be2c582006-04-05 23:38:46 +00004827 case Intrinsic::x86_sse_comilt_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004828 case Intrinsic::x86_sse2_comilt_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004829 Opc = X86ISD::COMI;
4830 CC = ISD::SETLT;
4831 break;
4832 case Intrinsic::x86_sse_comile_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004833 case Intrinsic::x86_sse2_comile_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004834 Opc = X86ISD::COMI;
4835 CC = ISD::SETLE;
4836 break;
4837 case Intrinsic::x86_sse_comigt_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004838 case Intrinsic::x86_sse2_comigt_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004839 Opc = X86ISD::COMI;
4840 CC = ISD::SETGT;
4841 break;
4842 case Intrinsic::x86_sse_comige_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004843 case Intrinsic::x86_sse2_comige_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004844 Opc = X86ISD::COMI;
4845 CC = ISD::SETGE;
4846 break;
4847 case Intrinsic::x86_sse_comineq_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004848 case Intrinsic::x86_sse2_comineq_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004849 Opc = X86ISD::COMI;
4850 CC = ISD::SETNE;
4851 break;
4852 case Intrinsic::x86_sse_ucomieq_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004853 case Intrinsic::x86_sse2_ucomieq_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004854 Opc = X86ISD::UCOMI;
4855 CC = ISD::SETEQ;
4856 break;
4857 case Intrinsic::x86_sse_ucomilt_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004858 case Intrinsic::x86_sse2_ucomilt_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004859 Opc = X86ISD::UCOMI;
4860 CC = ISD::SETLT;
4861 break;
4862 case Intrinsic::x86_sse_ucomile_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004863 case Intrinsic::x86_sse2_ucomile_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004864 Opc = X86ISD::UCOMI;
4865 CC = ISD::SETLE;
4866 break;
4867 case Intrinsic::x86_sse_ucomigt_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004868 case Intrinsic::x86_sse2_ucomigt_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004869 Opc = X86ISD::UCOMI;
4870 CC = ISD::SETGT;
4871 break;
4872 case Intrinsic::x86_sse_ucomige_ss:
Evan Cheng6be2c582006-04-05 23:38:46 +00004873 case Intrinsic::x86_sse2_ucomige_sd:
Evan Cheng0db9fe62006-04-25 20:13:52 +00004874 Opc = X86ISD::UCOMI;
4875 CC = ISD::SETGE;
4876 break;
4877 case Intrinsic::x86_sse_ucomineq_ss:
4878 case Intrinsic::x86_sse2_ucomineq_sd:
4879 Opc = X86ISD::UCOMI;
4880 CC = ISD::SETNE;
4881 break;
Evan Cheng6be2c582006-04-05 23:38:46 +00004882 }
Evan Cheng734503b2006-09-11 02:19:56 +00004883
Evan Cheng0db9fe62006-04-25 20:13:52 +00004884 unsigned X86CC;
Chris Lattnerf9570512006-09-13 03:22:10 +00004885 SDOperand LHS = Op.getOperand(1);
4886 SDOperand RHS = Op.getOperand(2);
4887 translateX86CC(CC, true, X86CC, LHS, RHS, DAG);
Evan Cheng734503b2006-09-11 02:19:56 +00004888
4889 const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
Chris Lattnerf9570512006-09-13 03:22:10 +00004890 SDOperand Ops1[] = { DAG.getEntryNode(), LHS, RHS };
Evan Cheng734503b2006-09-11 02:19:56 +00004891 SDOperand Cond = DAG.getNode(Opc, VTs, 2, Ops1, 3);
4892 VTs = DAG.getNodeValueTypes(MVT::i8, MVT::Flag);
4893 SDOperand Ops2[] = { DAG.getConstant(X86CC, MVT::i8), Cond };
4894 SDOperand SetCC = DAG.getNode(X86ISD::SETCC, VTs, 2, Ops2, 2);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004895 return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC);
Evan Cheng6be2c582006-04-05 23:38:46 +00004896 }
Evan Cheng38bcbaf2005-12-23 07:31:11 +00004897 }
Chris Lattnerdbdbf0c2005-11-15 00:40:23 +00004898}
Evan Cheng72261582005-12-20 06:22:03 +00004899
Evan Cheng0db9fe62006-04-25 20:13:52 +00004900/// LowerOperation - Provide custom lowering hooks for some operations.
4901///
4902SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
4903 switch (Op.getOpcode()) {
4904 default: assert(0 && "Should not custom lower this!");
4905 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
4906 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
4907 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
4908 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
4909 case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
4910 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
4911 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
4912 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
4913 case ISD::SHL_PARTS:
4914 case ISD::SRA_PARTS:
4915 case ISD::SRL_PARTS: return LowerShift(Op, DAG);
4916 case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
4917 case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
4918 case ISD::FABS: return LowerFABS(Op, DAG);
4919 case ISD::FNEG: return LowerFNEG(Op, DAG);
Evan Cheng734503b2006-09-11 02:19:56 +00004920 case ISD::SETCC: return LowerSETCC(Op, DAG, DAG.getEntryNode());
Evan Cheng0db9fe62006-04-25 20:13:52 +00004921 case ISD::SELECT: return LowerSELECT(Op, DAG);
4922 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
4923 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
Evan Cheng32fe1032006-05-25 00:59:30 +00004924 case ISD::CALL: return LowerCALL(Op, DAG);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004925 case ISD::RET: return LowerRET(Op, DAG);
Evan Cheng1bc78042006-04-26 01:20:17 +00004926 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
Evan Cheng0db9fe62006-04-25 20:13:52 +00004927 case ISD::MEMSET: return LowerMEMSET(Op, DAG);
4928 case ISD::MEMCPY: return LowerMEMCPY(Op, DAG);
4929 case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG);
4930 case ISD::VASTART: return LowerVASTART(Op, DAG);
4931 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
4932 }
4933}
4934
Evan Cheng72261582005-12-20 06:22:03 +00004935const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
4936 switch (Opcode) {
4937 default: return NULL;
Evan Chenge3413162006-01-09 18:33:28 +00004938 case X86ISD::SHLD: return "X86ISD::SHLD";
4939 case X86ISD::SHRD: return "X86ISD::SHRD";
Evan Chengef6ffb12006-01-31 03:14:29 +00004940 case X86ISD::FAND: return "X86ISD::FAND";
Evan Cheng223547a2006-01-31 22:28:30 +00004941 case X86ISD::FXOR: return "X86ISD::FXOR";
Evan Chenga3195e82006-01-12 22:54:21 +00004942 case X86ISD::FILD: return "X86ISD::FILD";
Evan Chenge3de85b2006-02-04 02:20:30 +00004943 case X86ISD::FILD_FLAG: return "X86ISD::FILD_FLAG";
Evan Cheng72261582005-12-20 06:22:03 +00004944 case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM";
4945 case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM";
4946 case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM";
Evan Chengb077b842005-12-21 02:39:21 +00004947 case X86ISD::FLD: return "X86ISD::FLD";
Evan Chengd90eb7f2006-01-05 00:27:02 +00004948 case X86ISD::FST: return "X86ISD::FST";
4949 case X86ISD::FP_GET_RESULT: return "X86ISD::FP_GET_RESULT";
Evan Chengb077b842005-12-21 02:39:21 +00004950 case X86ISD::FP_SET_RESULT: return "X86ISD::FP_SET_RESULT";
Evan Cheng72261582005-12-20 06:22:03 +00004951 case X86ISD::CALL: return "X86ISD::CALL";
4952 case X86ISD::TAILCALL: return "X86ISD::TAILCALL";
4953 case X86ISD::RDTSC_DAG: return "X86ISD::RDTSC_DAG";
4954 case X86ISD::CMP: return "X86ISD::CMP";
Evan Cheng6be2c582006-04-05 23:38:46 +00004955 case X86ISD::COMI: return "X86ISD::COMI";
4956 case X86ISD::UCOMI: return "X86ISD::UCOMI";
Evan Chengd5781fc2005-12-21 20:21:51 +00004957 case X86ISD::SETCC: return "X86ISD::SETCC";
Evan Cheng72261582005-12-20 06:22:03 +00004958 case X86ISD::CMOV: return "X86ISD::CMOV";
4959 case X86ISD::BRCOND: return "X86ISD::BRCOND";
Evan Chengb077b842005-12-21 02:39:21 +00004960 case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG";
Evan Cheng8df346b2006-03-04 01:12:00 +00004961 case X86ISD::REP_STOS: return "X86ISD::REP_STOS";
4962 case X86ISD::REP_MOVS: return "X86ISD::REP_MOVS";
Evan Cheng223547a2006-01-31 22:28:30 +00004963 case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK";
Evan Cheng206ee9d2006-07-07 08:33:52 +00004964 case X86ISD::LOAD_UA: return "X86ISD::LOAD_UA";
Evan Cheng7ccced62006-02-18 00:15:05 +00004965 case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
Evan Cheng020d2e82006-02-23 20:41:18 +00004966 case X86ISD::Wrapper: return "X86ISD::Wrapper";
Evan Chengbc4832b2006-03-24 23:15:12 +00004967 case X86ISD::S2VEC: return "X86ISD::S2VEC";
Evan Chengb067a1e2006-03-31 19:22:53 +00004968 case X86ISD::PEXTRW: return "X86ISD::PEXTRW";
Evan Cheng653159f2006-03-31 21:55:24 +00004969 case X86ISD::PINSRW: return "X86ISD::PINSRW";
Evan Cheng72261582005-12-20 06:22:03 +00004970 }
4971}
Evan Cheng3a03ebb2005-12-21 23:05:39 +00004972
Evan Cheng60c07e12006-07-05 22:17:51 +00004973/// isLegalAddressImmediate - Return true if the integer value or
4974/// GlobalValue can be used as the offset of the target addressing mode.
4975bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const {
4976 // X86 allows a sign-extended 32-bit immediate field.
4977 return (V > -(1LL << 32) && V < (1LL << 32)-1);
4978}
4979
4980bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const {
4981 // GV is 64-bit but displacement field is 32-bit unless we are in small code
4982 // model. Mac OS X happens to support only small PIC code model.
4983 // FIXME: better support for other OS's.
4984 if (Subtarget->is64Bit() && !Subtarget->isTargetDarwin())
4985 return false;
4986 if (Subtarget->isTargetDarwin()) {
4987 Reloc::Model RModel = getTargetMachine().getRelocationModel();
4988 if (RModel == Reloc::Static)
4989 return true;
4990 else if (RModel == Reloc::DynamicNoPIC)
4991 return !DarwinGVRequiresExtraLoad(GV);
4992 else
4993 return false;
4994 } else
4995 return true;
4996}
4997
4998/// isShuffleMaskLegal - Targets can use this to indicate that they only
4999/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
5000/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
5001/// are assumed to be legal.
5002bool
5003X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
5004 // Only do shuffles on 128-bit vector types for now.
5005 if (MVT::getSizeInBits(VT) == 64) return false;
5006 return (Mask.Val->getNumOperands() <= 4 ||
5007 isSplatMask(Mask.Val) ||
5008 isPSHUFHW_PSHUFLWMask(Mask.Val) ||
5009 X86::isUNPCKLMask(Mask.Val) ||
5010 X86::isUNPCKL_v_undef_Mask(Mask.Val) ||
5011 X86::isUNPCKHMask(Mask.Val));
5012}
5013
5014bool X86TargetLowering::isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
5015 MVT::ValueType EVT,
5016 SelectionDAG &DAG) const {
5017 unsigned NumElts = BVOps.size();
5018 // Only do shuffles on 128-bit vector types for now.
5019 if (MVT::getSizeInBits(EVT) * NumElts == 64) return false;
5020 if (NumElts == 2) return true;
5021 if (NumElts == 4) {
5022 return (isMOVLMask(BVOps) || isCommutedMOVL(BVOps, true) ||
5023 isSHUFPMask(BVOps) || isCommutedSHUFP(BVOps));
5024 }
5025 return false;
5026}
5027
5028//===----------------------------------------------------------------------===//
5029// X86 Scheduler Hooks
5030//===----------------------------------------------------------------------===//
5031
5032MachineBasicBlock *
5033X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
5034 MachineBasicBlock *BB) {
5035 switch (MI->getOpcode()) {
5036 default: assert(false && "Unexpected instr type to insert");
5037 case X86::CMOV_FR32:
5038 case X86::CMOV_FR64:
5039 case X86::CMOV_V4F32:
5040 case X86::CMOV_V2F64:
5041 case X86::CMOV_V2I64: {
5042 // To "insert" a SELECT_CC instruction, we actually have to insert the
5043 // diamond control-flow pattern. The incoming instruction knows the
5044 // destination vreg to set, the condition code register to branch on, the
5045 // true/false values to select between, and a branch opcode to use.
5046 const BasicBlock *LLVM_BB = BB->getBasicBlock();
5047 ilist<MachineBasicBlock>::iterator It = BB;
5048 ++It;
5049
5050 // thisMBB:
5051 // ...
5052 // TrueVal = ...
5053 // cmpTY ccX, r1, r2
5054 // bCC copy1MBB
5055 // fallthrough --> copy0MBB
5056 MachineBasicBlock *thisMBB = BB;
5057 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
5058 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
Chris Lattner7fbe9722006-10-20 17:42:20 +00005059 unsigned Opc =
5060 X86::GetCondBranchFromCond((X86::CondCode)MI->getOperand(3).getImm());
Evan Cheng60c07e12006-07-05 22:17:51 +00005061 BuildMI(BB, Opc, 1).addMBB(sinkMBB);
5062 MachineFunction *F = BB->getParent();
5063 F->getBasicBlockList().insert(It, copy0MBB);
5064 F->getBasicBlockList().insert(It, sinkMBB);
5065 // Update machine-CFG edges by first adding all successors of the current
5066 // block to the new block which will contain the Phi node for the select.
5067 for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
5068 e = BB->succ_end(); i != e; ++i)
5069 sinkMBB->addSuccessor(*i);
5070 // Next, remove all successors of the current block, and add the true
5071 // and fallthrough blocks as its successors.
5072 while(!BB->succ_empty())
5073 BB->removeSuccessor(BB->succ_begin());
5074 BB->addSuccessor(copy0MBB);
5075 BB->addSuccessor(sinkMBB);
5076
5077 // copy0MBB:
5078 // %FalseValue = ...
5079 // # fallthrough to sinkMBB
5080 BB = copy0MBB;
5081
5082 // Update machine-CFG edges
5083 BB->addSuccessor(sinkMBB);
5084
5085 // sinkMBB:
5086 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
5087 // ...
5088 BB = sinkMBB;
5089 BuildMI(BB, X86::PHI, 4, MI->getOperand(0).getReg())
5090 .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB)
5091 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
5092
5093 delete MI; // The pseudo instruction is gone now.
5094 return BB;
5095 }
5096
5097 case X86::FP_TO_INT16_IN_MEM:
5098 case X86::FP_TO_INT32_IN_MEM:
5099 case X86::FP_TO_INT64_IN_MEM: {
5100 // Change the floating point control register to use "round towards zero"
5101 // mode when truncating to an integer value.
5102 MachineFunction *F = BB->getParent();
5103 int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2);
5104 addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
5105
5106 // Load the old value of the high byte of the control word...
5107 unsigned OldCW =
5108 F->getSSARegMap()->createVirtualRegister(X86::GR16RegisterClass);
5109 addFrameReference(BuildMI(BB, X86::MOV16rm, 4, OldCW), CWFrameIdx);
5110
5111 // Set the high part to be round to zero...
5112 addFrameReference(BuildMI(BB, X86::MOV16mi, 5), CWFrameIdx).addImm(0xC7F);
5113
5114 // Reload the modified control word now...
5115 addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
5116
5117 // Restore the memory image of control word to original value
5118 addFrameReference(BuildMI(BB, X86::MOV16mr, 5), CWFrameIdx).addReg(OldCW);
5119
5120 // Get the X86 opcode to use.
5121 unsigned Opc;
5122 switch (MI->getOpcode()) {
5123 default: assert(0 && "illegal opcode!");
5124 case X86::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break;
5125 case X86::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break;
5126 case X86::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break;
5127 }
5128
5129 X86AddressMode AM;
5130 MachineOperand &Op = MI->getOperand(0);
5131 if (Op.isRegister()) {
5132 AM.BaseType = X86AddressMode::RegBase;
5133 AM.Base.Reg = Op.getReg();
5134 } else {
5135 AM.BaseType = X86AddressMode::FrameIndexBase;
5136 AM.Base.FrameIndex = Op.getFrameIndex();
5137 }
5138 Op = MI->getOperand(1);
5139 if (Op.isImmediate())
Chris Lattner7fbe9722006-10-20 17:42:20 +00005140 AM.Scale = Op.getImm();
Evan Cheng60c07e12006-07-05 22:17:51 +00005141 Op = MI->getOperand(2);
5142 if (Op.isImmediate())
Chris Lattner7fbe9722006-10-20 17:42:20 +00005143 AM.IndexReg = Op.getImm();
Evan Cheng60c07e12006-07-05 22:17:51 +00005144 Op = MI->getOperand(3);
5145 if (Op.isGlobalAddress()) {
5146 AM.GV = Op.getGlobal();
5147 } else {
Chris Lattner7fbe9722006-10-20 17:42:20 +00005148 AM.Disp = Op.getImm();
Evan Cheng60c07e12006-07-05 22:17:51 +00005149 }
5150 addFullAddress(BuildMI(BB, Opc, 5), AM).addReg(MI->getOperand(4).getReg());
5151
5152 // Reload the original control word now.
5153 addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
5154
5155 delete MI; // The pseudo instruction is gone now.
5156 return BB;
5157 }
5158 }
5159}
5160
5161//===----------------------------------------------------------------------===//
5162// X86 Optimization Hooks
5163//===----------------------------------------------------------------------===//
5164
Nate Begeman368e18d2006-02-16 21:11:51 +00005165void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
5166 uint64_t Mask,
5167 uint64_t &KnownZero,
5168 uint64_t &KnownOne,
5169 unsigned Depth) const {
Evan Cheng3a03ebb2005-12-21 23:05:39 +00005170 unsigned Opc = Op.getOpcode();
Evan Cheng865f0602006-04-05 06:11:20 +00005171 assert((Opc >= ISD::BUILTIN_OP_END ||
5172 Opc == ISD::INTRINSIC_WO_CHAIN ||
5173 Opc == ISD::INTRINSIC_W_CHAIN ||
5174 Opc == ISD::INTRINSIC_VOID) &&
5175 "Should use MaskedValueIsZero if you don't know whether Op"
5176 " is a target node!");
Evan Cheng3a03ebb2005-12-21 23:05:39 +00005177
Evan Cheng865f0602006-04-05 06:11:20 +00005178 KnownZero = KnownOne = 0; // Don't know anything.
Evan Cheng3a03ebb2005-12-21 23:05:39 +00005179 switch (Opc) {
Evan Cheng865f0602006-04-05 06:11:20 +00005180 default: break;
Nate Begeman368e18d2006-02-16 21:11:51 +00005181 case X86ISD::SETCC:
5182 KnownZero |= (MVT::getIntVTBitMask(Op.getValueType()) ^ 1ULL);
5183 break;
Evan Cheng3a03ebb2005-12-21 23:05:39 +00005184 }
Evan Cheng3a03ebb2005-12-21 23:05:39 +00005185}
Chris Lattner259e97c2006-01-31 19:43:35 +00005186
Evan Cheng206ee9d2006-07-07 08:33:52 +00005187/// getShuffleScalarElt - Returns the scalar element that will make up the ith
5188/// element of the result of the vector shuffle.
5189static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
5190 MVT::ValueType VT = N->getValueType(0);
5191 SDOperand PermMask = N->getOperand(2);
5192 unsigned NumElems = PermMask.getNumOperands();
5193 SDOperand V = (i < NumElems) ? N->getOperand(0) : N->getOperand(1);
5194 i %= NumElems;
5195 if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) {
5196 return (i == 0)
5197 ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(VT));
5198 } else if (V.getOpcode() == ISD::VECTOR_SHUFFLE) {
5199 SDOperand Idx = PermMask.getOperand(i);
5200 if (Idx.getOpcode() == ISD::UNDEF)
5201 return DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(VT));
5202 return getShuffleScalarElt(V.Val,cast<ConstantSDNode>(Idx)->getValue(),DAG);
5203 }
5204 return SDOperand();
5205}
5206
5207/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
5208/// node is a GlobalAddress + an offset.
5209static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
5210 if (N->getOpcode() == X86ISD::Wrapper) {
5211 if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
5212 GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
5213 return true;
5214 }
5215 } else if (N->getOpcode() == ISD::ADD) {
5216 SDOperand N1 = N->getOperand(0);
5217 SDOperand N2 = N->getOperand(1);
5218 if (isGAPlusOffset(N1.Val, GA, Offset)) {
5219 ConstantSDNode *V = dyn_cast<ConstantSDNode>(N2);
5220 if (V) {
5221 Offset += V->getSignExtended();
5222 return true;
5223 }
5224 } else if (isGAPlusOffset(N2.Val, GA, Offset)) {
5225 ConstantSDNode *V = dyn_cast<ConstantSDNode>(N1);
5226 if (V) {
5227 Offset += V->getSignExtended();
5228 return true;
5229 }
5230 }
5231 }
5232 return false;
5233}
5234
5235/// isConsecutiveLoad - Returns true if N is loading from an address of Base
5236/// + Dist * Size.
5237static bool isConsecutiveLoad(SDNode *N, SDNode *Base, int Dist, int Size,
5238 MachineFrameInfo *MFI) {
5239 if (N->getOperand(0).Val != Base->getOperand(0).Val)
5240 return false;
5241
5242 SDOperand Loc = N->getOperand(1);
5243 SDOperand BaseLoc = Base->getOperand(1);
5244 if (Loc.getOpcode() == ISD::FrameIndex) {
5245 if (BaseLoc.getOpcode() != ISD::FrameIndex)
5246 return false;
5247 int FI = dyn_cast<FrameIndexSDNode>(Loc)->getIndex();
5248 int BFI = dyn_cast<FrameIndexSDNode>(BaseLoc)->getIndex();
5249 int FS = MFI->getObjectSize(FI);
5250 int BFS = MFI->getObjectSize(BFI);
5251 if (FS != BFS || FS != Size) return false;
5252 return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Size);
5253 } else {
5254 GlobalValue *GV1 = NULL;
5255 GlobalValue *GV2 = NULL;
5256 int64_t Offset1 = 0;
5257 int64_t Offset2 = 0;
5258 bool isGA1 = isGAPlusOffset(Loc.Val, GV1, Offset1);
5259 bool isGA2 = isGAPlusOffset(BaseLoc.Val, GV2, Offset2);
5260 if (isGA1 && isGA2 && GV1 == GV2)
5261 return Offset1 == (Offset2 + Dist*Size);
5262 }
5263
5264 return false;
5265}
5266
Evan Cheng1e60c092006-07-10 21:37:44 +00005267static bool isBaseAlignment16(SDNode *Base, MachineFrameInfo *MFI,
5268 const X86Subtarget *Subtarget) {
Evan Cheng206ee9d2006-07-07 08:33:52 +00005269 GlobalValue *GV;
5270 int64_t Offset;
5271 if (isGAPlusOffset(Base, GV, Offset))
5272 return (GV->getAlignment() >= 16 && (Offset % 16) == 0);
5273 else {
5274 assert(Base->getOpcode() == ISD::FrameIndex && "Unexpected base node!");
5275 int BFI = dyn_cast<FrameIndexSDNode>(Base)->getIndex();
Evan Cheng1e60c092006-07-10 21:37:44 +00005276 if (BFI < 0)
5277 // Fixed objects do not specify alignment, however the offsets are known.
5278 return ((Subtarget->getStackAlignment() % 16) == 0 &&
5279 (MFI->getObjectOffset(BFI) % 16) == 0);
5280 else
5281 return MFI->getObjectAlignment(BFI) >= 16;
Evan Cheng206ee9d2006-07-07 08:33:52 +00005282 }
5283 return false;
5284}
5285
5286
5287/// PerformShuffleCombine - Combine a vector_shuffle that is equal to
5288/// build_vector load1, load2, load3, load4, <0, 1, 2, 3> into a 128-bit load
5289/// if the load addresses are consecutive, non-overlapping, and in the right
5290/// order.
Evan Cheng1e60c092006-07-10 21:37:44 +00005291static SDOperand PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
5292 const X86Subtarget *Subtarget) {
Evan Cheng206ee9d2006-07-07 08:33:52 +00005293 MachineFunction &MF = DAG.getMachineFunction();
5294 MachineFrameInfo *MFI = MF.getFrameInfo();
5295 MVT::ValueType VT = N->getValueType(0);
5296 MVT::ValueType EVT = MVT::getVectorBaseType(VT);
5297 SDOperand PermMask = N->getOperand(2);
5298 int NumElems = (int)PermMask.getNumOperands();
5299 SDNode *Base = NULL;
5300 for (int i = 0; i < NumElems; ++i) {
5301 SDOperand Idx = PermMask.getOperand(i);
5302 if (Idx.getOpcode() == ISD::UNDEF) {
5303 if (!Base) return SDOperand();
5304 } else {
5305 SDOperand Arg =
5306 getShuffleScalarElt(N, cast<ConstantSDNode>(Idx)->getValue(), DAG);
Evan Cheng466685d2006-10-09 20:57:25 +00005307 if (!Arg.Val || !ISD::isNON_EXTLoad(Arg.Val))
Evan Cheng206ee9d2006-07-07 08:33:52 +00005308 return SDOperand();
5309 if (!Base)
5310 Base = Arg.Val;
5311 else if (!isConsecutiveLoad(Arg.Val, Base,
5312 i, MVT::getSizeInBits(EVT)/8,MFI))
5313 return SDOperand();
5314 }
5315 }
5316
Evan Cheng1e60c092006-07-10 21:37:44 +00005317 bool isAlign16 = isBaseAlignment16(Base->getOperand(1).Val, MFI, Subtarget);
Evan Cheng466685d2006-10-09 20:57:25 +00005318 if (isAlign16) {
5319 LoadSDNode *LD = cast<LoadSDNode>(Base);
5320 return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(),
5321 LD->getSrcValueOffset());
5322 } else {
Evan Cheng206ee9d2006-07-07 08:33:52 +00005323 // Just use movups, it's shorter.
Evan Cheng64a752f2006-08-11 09:08:15 +00005324 std::vector<MVT::ValueType> Tys;
5325 Tys.push_back(MVT::v4f32);
5326 Tys.push_back(MVT::Other);
5327 SmallVector<SDOperand, 3> Ops;
5328 Ops.push_back(Base->getOperand(0));
5329 Ops.push_back(Base->getOperand(1));
5330 Ops.push_back(Base->getOperand(2));
Evan Cheng206ee9d2006-07-07 08:33:52 +00005331 return DAG.getNode(ISD::BIT_CONVERT, VT,
Evan Cheng64a752f2006-08-11 09:08:15 +00005332 DAG.getNode(X86ISD::LOAD_UA, Tys, &Ops[0], Ops.size()));
Evan Cheng311ace02006-08-11 07:35:45 +00005333 }
Evan Cheng206ee9d2006-07-07 08:33:52 +00005334}
5335
Chris Lattner83e6c992006-10-04 06:57:07 +00005336/// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes.
5337static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
5338 const X86Subtarget *Subtarget) {
5339 SDOperand Cond = N->getOperand(0);
5340
5341 // If we have SSE[12] support, try to form min/max nodes.
5342 if (Subtarget->hasSSE2() &&
5343 (N->getValueType(0) == MVT::f32 || N->getValueType(0) == MVT::f64)) {
5344 if (Cond.getOpcode() == ISD::SETCC) {
5345 // Get the LHS/RHS of the select.
5346 SDOperand LHS = N->getOperand(1);
5347 SDOperand RHS = N->getOperand(2);
5348 ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
5349
5350 unsigned IntNo = 0;
5351 if (LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
Chris Lattner1907a7b2006-10-05 04:11:26 +00005352 switch (CC) {
5353 default: break;
5354 case ISD::SETOLE: // (X <= Y) ? X : Y -> min
5355 case ISD::SETULE:
5356 case ISD::SETLE:
5357 if (!UnsafeFPMath) break;
5358 // FALL THROUGH.
5359 case ISD::SETOLT: // (X olt/lt Y) ? X : Y -> min
5360 case ISD::SETLT:
Chris Lattner83e6c992006-10-04 06:57:07 +00005361 IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
5362 Intrinsic::x86_sse2_min_sd;
Chris Lattner1907a7b2006-10-05 04:11:26 +00005363 break;
5364
5365 case ISD::SETOGT: // (X > Y) ? X : Y -> max
5366 case ISD::SETUGT:
5367 case ISD::SETGT:
5368 if (!UnsafeFPMath) break;
5369 // FALL THROUGH.
5370 case ISD::SETUGE: // (X uge/ge Y) ? X : Y -> max
5371 case ISD::SETGE:
Chris Lattner83e6c992006-10-04 06:57:07 +00005372 IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
Chris Lattner1907a7b2006-10-05 04:11:26 +00005373 Intrinsic::x86_sse2_max_sd;
5374 break;
5375 }
Chris Lattner83e6c992006-10-04 06:57:07 +00005376 } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) {
Chris Lattner1907a7b2006-10-05 04:11:26 +00005377 switch (CC) {
5378 default: break;
5379 case ISD::SETOGT: // (X > Y) ? Y : X -> min
5380 case ISD::SETUGT:
5381 case ISD::SETGT:
5382 if (!UnsafeFPMath) break;
5383 // FALL THROUGH.
5384 case ISD::SETUGE: // (X uge/ge Y) ? Y : X -> min
5385 case ISD::SETGE:
Chris Lattner83e6c992006-10-04 06:57:07 +00005386 IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
Chris Lattner1907a7b2006-10-05 04:11:26 +00005387 Intrinsic::x86_sse2_min_sd;
5388 break;
5389
5390 case ISD::SETOLE: // (X <= Y) ? Y : X -> max
5391 case ISD::SETULE:
5392 case ISD::SETLE:
5393 if (!UnsafeFPMath) break;
5394 // FALL THROUGH.
5395 case ISD::SETOLT: // (X olt/lt Y) ? Y : X -> max
5396 case ISD::SETLT:
Chris Lattner83e6c992006-10-04 06:57:07 +00005397 IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
Chris Lattner1907a7b2006-10-05 04:11:26 +00005398 Intrinsic::x86_sse2_max_sd;
5399 break;
5400 }
Chris Lattner83e6c992006-10-04 06:57:07 +00005401 }
5402
5403 // minss/maxss take a v4f32 operand.
5404 if (IntNo) {
5405 if (LHS.getValueType() == MVT::f32) {
5406 LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, LHS);
5407 RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, RHS);
5408 } else {
5409 LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, LHS);
5410 RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, RHS);
5411 }
5412
5413 MVT::ValueType PtrTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
5414 SDOperand IntNoN = DAG.getConstant(IntNo, PtrTy);
5415
5416 SDOperand Val = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, LHS.getValueType(),
5417 IntNoN, LHS, RHS);
5418 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getValueType(0), Val,
5419 DAG.getConstant(0, PtrTy));
5420 }
5421 }
5422
5423 }
5424
5425 return SDOperand();
5426}
5427
5428
Evan Cheng206ee9d2006-07-07 08:33:52 +00005429SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N,
5430 DAGCombinerInfo &DCI) const {
5431 TargetMachine &TM = getTargetMachine();
5432 SelectionDAG &DAG = DCI.DAG;
5433 switch (N->getOpcode()) {
5434 default: break;
5435 case ISD::VECTOR_SHUFFLE:
Evan Cheng1e60c092006-07-10 21:37:44 +00005436 return PerformShuffleCombine(N, DAG, Subtarget);
Chris Lattner83e6c992006-10-04 06:57:07 +00005437 case ISD::SELECT:
5438 return PerformSELECTCombine(N, DAG, Subtarget);
Evan Cheng206ee9d2006-07-07 08:33:52 +00005439 }
5440
5441 return SDOperand();
5442}
5443
Evan Cheng60c07e12006-07-05 22:17:51 +00005444//===----------------------------------------------------------------------===//
5445// X86 Inline Assembly Support
5446//===----------------------------------------------------------------------===//
5447
Chris Lattnerf4dff842006-07-11 02:54:03 +00005448/// getConstraintType - Given a constraint letter, return the type of
5449/// constraint it is for this target.
5450X86TargetLowering::ConstraintType
5451X86TargetLowering::getConstraintType(char ConstraintLetter) const {
5452 switch (ConstraintLetter) {
Chris Lattner6d346572006-07-12 16:59:49 +00005453 case 'A':
5454 case 'r':
5455 case 'R':
5456 case 'l':
5457 case 'q':
5458 case 'Q':
5459 case 'x':
5460 case 'Y':
5461 return C_RegisterClass;
Chris Lattnerf4dff842006-07-11 02:54:03 +00005462 default: return TargetLowering::getConstraintType(ConstraintLetter);
5463 }
5464}
5465
Chris Lattner259e97c2006-01-31 19:43:35 +00005466std::vector<unsigned> X86TargetLowering::
Chris Lattner1efa40f2006-02-22 00:56:39 +00005467getRegClassForInlineAsmConstraint(const std::string &Constraint,
5468 MVT::ValueType VT) const {
Chris Lattner259e97c2006-01-31 19:43:35 +00005469 if (Constraint.size() == 1) {
5470 // FIXME: not handling fp-stack yet!
5471 // FIXME: not handling MMX registers yet ('y' constraint).
5472 switch (Constraint[0]) { // GCC X86 Constraint Letters
Chris Lattnerf4dff842006-07-11 02:54:03 +00005473 default: break; // Unknown constraint letter
5474 case 'A': // EAX/EDX
5475 if (VT == MVT::i32 || VT == MVT::i64)
5476 return make_vector<unsigned>(X86::EAX, X86::EDX, 0);
5477 break;
Chris Lattner259e97c2006-01-31 19:43:35 +00005478 case 'r': // GENERAL_REGS
5479 case 'R': // LEGACY_REGS
Chris Lattner80a7ecc2006-05-06 00:29:37 +00005480 if (VT == MVT::i32)
5481 return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX,
5482 X86::ESI, X86::EDI, X86::EBP, X86::ESP, 0);
5483 else if (VT == MVT::i16)
5484 return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX,
5485 X86::SI, X86::DI, X86::BP, X86::SP, 0);
5486 else if (VT == MVT::i8)
5487 return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
5488 break;
Chris Lattner259e97c2006-01-31 19:43:35 +00005489 case 'l': // INDEX_REGS
Chris Lattner80a7ecc2006-05-06 00:29:37 +00005490 if (VT == MVT::i32)
5491 return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX,
5492 X86::ESI, X86::EDI, X86::EBP, 0);
5493 else if (VT == MVT::i16)
5494 return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX,
5495 X86::SI, X86::DI, X86::BP, 0);
5496 else if (VT == MVT::i8)
5497 return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
5498 break;
Chris Lattner259e97c2006-01-31 19:43:35 +00005499 case 'q': // Q_REGS (GENERAL_REGS in 64-bit mode)
5500 case 'Q': // Q_REGS
Chris Lattner80a7ecc2006-05-06 00:29:37 +00005501 if (VT == MVT::i32)
5502 return make_vector<unsigned>(X86::EAX, X86::EDX, X86::ECX, X86::EBX, 0);
5503 else if (VT == MVT::i16)
5504 return make_vector<unsigned>(X86::AX, X86::DX, X86::CX, X86::BX, 0);
5505 else if (VT == MVT::i8)
5506 return make_vector<unsigned>(X86::AL, X86::DL, X86::CL, X86::DL, 0);
5507 break;
Chris Lattner259e97c2006-01-31 19:43:35 +00005508 case 'x': // SSE_REGS if SSE1 allowed
5509 if (Subtarget->hasSSE1())
5510 return make_vector<unsigned>(X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
5511 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7,
5512 0);
5513 return std::vector<unsigned>();
5514 case 'Y': // SSE_REGS if SSE2 allowed
5515 if (Subtarget->hasSSE2())
5516 return make_vector<unsigned>(X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
5517 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7,
5518 0);
5519 return std::vector<unsigned>();
5520 }
5521 }
5522
Chris Lattner1efa40f2006-02-22 00:56:39 +00005523 return std::vector<unsigned>();
Chris Lattner259e97c2006-01-31 19:43:35 +00005524}
Chris Lattnerf76d1802006-07-31 23:26:50 +00005525
5526std::pair<unsigned, const TargetRegisterClass*>
5527X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
5528 MVT::ValueType VT) const {
5529 // Use the default implementation in TargetLowering to convert the register
5530 // constraint into a member of a register class.
5531 std::pair<unsigned, const TargetRegisterClass*> Res;
5532 Res = TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
5533
5534 // Not found? Bail out.
5535 if (Res.second == 0) return Res;
5536
5537 // Otherwise, check to see if this is a register class of the wrong value
5538 // type. For example, we want to map "{ax},i32" -> {eax}, we don't want it to
5539 // turn into {ax},{dx}.
5540 if (Res.second->hasType(VT))
5541 return Res; // Correct type already, nothing to do.
5542
5543 // All of the single-register GCC register classes map their values onto
5544 // 16-bit register pieces "ax","dx","cx","bx","si","di","bp","sp". If we
5545 // really want an 8-bit or 32-bit register, map to the appropriate register
5546 // class and return the appropriate register.
5547 if (Res.second != X86::GR16RegisterClass)
5548 return Res;
5549
5550 if (VT == MVT::i8) {
5551 unsigned DestReg = 0;
5552 switch (Res.first) {
5553 default: break;
5554 case X86::AX: DestReg = X86::AL; break;
5555 case X86::DX: DestReg = X86::DL; break;
5556 case X86::CX: DestReg = X86::CL; break;
5557 case X86::BX: DestReg = X86::BL; break;
5558 }
5559 if (DestReg) {
5560 Res.first = DestReg;
5561 Res.second = Res.second = X86::GR8RegisterClass;
5562 }
5563 } else if (VT == MVT::i32) {
5564 unsigned DestReg = 0;
5565 switch (Res.first) {
5566 default: break;
5567 case X86::AX: DestReg = X86::EAX; break;
5568 case X86::DX: DestReg = X86::EDX; break;
5569 case X86::CX: DestReg = X86::ECX; break;
5570 case X86::BX: DestReg = X86::EBX; break;
5571 case X86::SI: DestReg = X86::ESI; break;
5572 case X86::DI: DestReg = X86::EDI; break;
5573 case X86::BP: DestReg = X86::EBP; break;
5574 case X86::SP: DestReg = X86::ESP; break;
5575 }
5576 if (DestReg) {
5577 Res.first = DestReg;
5578 Res.second = Res.second = X86::GR32RegisterClass;
5579 }
Evan Cheng25ab6902006-09-08 06:48:29 +00005580 } else if (VT == MVT::i64) {
5581 unsigned DestReg = 0;
5582 switch (Res.first) {
5583 default: break;
5584 case X86::AX: DestReg = X86::RAX; break;
5585 case X86::DX: DestReg = X86::RDX; break;
5586 case X86::CX: DestReg = X86::RCX; break;
5587 case X86::BX: DestReg = X86::RBX; break;
5588 case X86::SI: DestReg = X86::RSI; break;
5589 case X86::DI: DestReg = X86::RDI; break;
5590 case X86::BP: DestReg = X86::RBP; break;
5591 case X86::SP: DestReg = X86::RSP; break;
5592 }
5593 if (DestReg) {
5594 Res.first = DestReg;
5595 Res.second = Res.second = X86::GR64RegisterClass;
5596 }
Chris Lattnerf76d1802006-07-31 23:26:50 +00005597 }
5598
5599 return Res;
5600}
5601