blob: 407b8e6856f968b43ee514d3d59f554bf78d5f80 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
17#include "llvm/ADT/VectorExtras.h"
18#include "llvm/Analysis/ScalarEvolutionExpressions.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000024#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/Constants.h"
26#include "llvm/Function.h"
27#include "llvm/Intrinsics.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Target/TargetOptions.h"
31
32#include <map>
33
34using namespace llvm;
35
36// Used in getTargetNodeName() below
37namespace {
38 std::map<unsigned, const char *> node_names;
39
40 //! MVT::ValueType mapping to useful data for Cell SPU
41 struct valtype_map_s {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000042 const MVT::ValueType valtype;
43 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000044 };
45
46 const valtype_map_s valtype_map[] = {
47 { MVT::i1, 3 },
48 { MVT::i8, 3 },
49 { MVT::i16, 2 },
50 { MVT::i32, 0 },
51 { MVT::f32, 0 },
52 { MVT::i64, 0 },
53 { MVT::f64, 0 },
54 { MVT::i128, 0 }
55 };
56
57 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
58
59 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) {
60 const valtype_map_s *retval = 0;
61
62 for (size_t i = 0; i < n_valtype_map; ++i) {
63 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000064 retval = valtype_map + i;
65 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000066 }
67 }
68
69#ifndef NDEBUG
70 if (retval == 0) {
71 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel7f9ba9b2008-01-30 02:55:46 +000072 << MVT::getValueTypeString(VT)
73 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000074 abort();
75 }
76#endif
77
78 return retval;
79 }
80
81 //! Predicate that returns true if operand is a memory target
82 /*!
83 \arg Op Operand to test
84 \return true if the operand is a memory target (i.e., global
Scott Michel9de5d0d2008-01-11 02:53:15 +000085 address, external symbol, constant pool) or an A-form
Scott Michel266bc8f2007-12-04 22:23:35 +000086 address.
87 */
88 bool isMemoryOperand(const SDOperand &Op)
89 {
90 const unsigned Opc = Op.getOpcode();
91 return (Opc == ISD::GlobalAddress
92 || Opc == ISD::GlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000093 || Opc == ISD::JumpTable
94 || Opc == ISD::ConstantPool
95 || Opc == ISD::ExternalSymbol
96 || Opc == ISD::TargetGlobalAddress
97 || Opc == ISD::TargetGlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000098 || Opc == ISD::TargetJumpTable
99 || Opc == ISD::TargetConstantPool
100 || Opc == ISD::TargetExternalSymbol
Scott Michel9de5d0d2008-01-11 02:53:15 +0000101 || Opc == SPUISD::AFormAddr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000102 }
Scott Michel58c58182008-01-17 20:38:41 +0000103
104 //! Predicate that returns true if the operand is an indirect target
105 bool isIndirectOperand(const SDOperand &Op)
106 {
107 const unsigned Opc = Op.getOpcode();
108 return (Opc == ISD::Register
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000109 || Opc == SPUISD::LDRESULT);
Scott Michel58c58182008-01-17 20:38:41 +0000110 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000111}
112
113SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
114 : TargetLowering(TM),
115 SPUTM(TM)
116{
117 // Fold away setcc operations if possible.
118 setPow2DivIsCheap();
119
120 // Use _setjmp/_longjmp instead of setjmp/longjmp.
121 setUseUnderscoreSetJmp(true);
122 setUseUnderscoreLongJmp(true);
123
124 // Set up the SPU's register classes:
125 // NOTE: i8 register class is not registered because we cannot determine when
126 // we need to zero or sign extend for custom-lowered loads and stores.
Scott Michel504c3692007-12-17 22:32:34 +0000127 // NOTE: Ignore the previous note. For now. :-)
128 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
129 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
130 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
131 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
132 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
133 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000134 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
135
136 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000137 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000138 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
139 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000140 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
142 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
143 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
144 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000145
146 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
147 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
148 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000149 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
151 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
152 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
153 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
154
Scott Michel266bc8f2007-12-04 22:23:35 +0000155 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
156 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
157 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
158
159 // SPU constant load actions are custom lowered:
160 setOperationAction(ISD::Constant, MVT::i64, Custom);
161 setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
162 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
163
164 // SPU's loads and stores have to be custom lowered:
165 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
166 ++sctype) {
167 setOperationAction(ISD::LOAD, sctype, Custom);
168 setOperationAction(ISD::STORE, sctype, Custom);
169 }
170
Scott Michel58c58182008-01-17 20:38:41 +0000171 // Custom lower BRCOND for i1, i8 to "promote" the result to
172 // i32 and i16, respectively.
173 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000174
175 // Expand the jumptable branches
176 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
177 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
178 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
179
180 // SPU has no intrinsics for these particular operations:
181 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
182 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
183 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
184
185 // PowerPC has no SREM/UREM instructions
186 setOperationAction(ISD::SREM, MVT::i32, Expand);
187 setOperationAction(ISD::UREM, MVT::i32, Expand);
188 setOperationAction(ISD::SREM, MVT::i64, Expand);
189 setOperationAction(ISD::UREM, MVT::i64, Expand);
190
191 // We don't support sin/cos/sqrt/fmod
192 setOperationAction(ISD::FSIN , MVT::f64, Expand);
193 setOperationAction(ISD::FCOS , MVT::f64, Expand);
194 setOperationAction(ISD::FREM , MVT::f64, Expand);
195 setOperationAction(ISD::FSIN , MVT::f32, Expand);
196 setOperationAction(ISD::FCOS , MVT::f32, Expand);
197 setOperationAction(ISD::FREM , MVT::f32, Expand);
198
199 // If we're enabling GP optimizations, use hardware square root
200 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
201 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
202
203 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
204 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
205
206 // SPU can do rotate right and left, so legalize it... but customize for i8
207 // because instructions don't exist.
208 setOperationAction(ISD::ROTR, MVT::i32, Legal);
209 setOperationAction(ISD::ROTR, MVT::i16, Legal);
210 setOperationAction(ISD::ROTR, MVT::i8, Custom);
211 setOperationAction(ISD::ROTL, MVT::i32, Legal);
212 setOperationAction(ISD::ROTL, MVT::i16, Legal);
213 setOperationAction(ISD::ROTL, MVT::i8, Custom);
214 // SPU has no native version of shift left/right for i8
215 setOperationAction(ISD::SHL, MVT::i8, Custom);
216 setOperationAction(ISD::SRL, MVT::i8, Custom);
217 setOperationAction(ISD::SRA, MVT::i8, Custom);
218
219 // Custom lower i32 multiplications
220 setOperationAction(ISD::MUL, MVT::i32, Custom);
221
222 // Need to custom handle (some) common i8 math ops
223 setOperationAction(ISD::SUB, MVT::i8, Custom);
224 setOperationAction(ISD::MUL, MVT::i8, Custom);
225
226 // SPU does not have BSWAP. It does have i32 support CTLZ.
227 // CTPOP has to be custom lowered.
228 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
229 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
230
231 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
232 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
233 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
234 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
235
236 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
237 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
238
239 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
240
241 // SPU does not have select or setcc
242 setOperationAction(ISD::SELECT, MVT::i1, Expand);
243 setOperationAction(ISD::SELECT, MVT::i8, Expand);
244 setOperationAction(ISD::SELECT, MVT::i16, Expand);
245 setOperationAction(ISD::SELECT, MVT::i32, Expand);
246 setOperationAction(ISD::SELECT, MVT::i64, Expand);
247 setOperationAction(ISD::SELECT, MVT::f32, Expand);
248 setOperationAction(ISD::SELECT, MVT::f64, Expand);
249
250 setOperationAction(ISD::SETCC, MVT::i1, Expand);
251 setOperationAction(ISD::SETCC, MVT::i8, Expand);
252 setOperationAction(ISD::SETCC, MVT::i16, Expand);
253 setOperationAction(ISD::SETCC, MVT::i32, Expand);
254 setOperationAction(ISD::SETCC, MVT::i64, Expand);
255 setOperationAction(ISD::SETCC, MVT::f32, Expand);
256 setOperationAction(ISD::SETCC, MVT::f64, Expand);
257
258 // SPU has a legal FP -> signed INT instruction
259 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
260 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
261 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
262 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
263
264 // FDIV on SPU requires custom lowering
265 setOperationAction(ISD::FDIV, MVT::f32, Custom);
266 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
267
268 // SPU has [U|S]INT_TO_FP
269 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
270 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
271 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
272 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
273 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
274 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
275 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
276 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
277
Scott Michel86c041f2007-12-20 00:44:13 +0000278 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
279 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
280 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
281 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000282
283 // We cannot sextinreg(i1). Expand to shifts.
284 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
285
286 // Support label based line numbers.
287 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
288 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
289
290 // We want to legalize GlobalAddress and ConstantPool nodes into the
291 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000292 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
293 ++sctype) {
294 setOperationAction(ISD::GlobalAddress, sctype, Custom);
295 setOperationAction(ISD::ConstantPool, sctype, Custom);
296 setOperationAction(ISD::JumpTable, sctype, Custom);
297 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000298
299 // RET must be custom lowered, to meet ABI requirements
300 setOperationAction(ISD::RET, MVT::Other, Custom);
301
302 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
303 setOperationAction(ISD::VASTART , MVT::Other, Custom);
304
305 // Use the default implementation.
306 setOperationAction(ISD::VAARG , MVT::Other, Expand);
307 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
308 setOperationAction(ISD::VAEND , MVT::Other, Expand);
309 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
310 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
311 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
312 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
313
314 // Cell SPU has instructions for converting between i64 and fp.
315 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
316 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
317
318 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
319 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
320
321 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
322 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
323
324 // First set operation action for all vector types to expand. Then we
325 // will selectively turn on ones that can be effectively codegen'd.
326 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
327 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
328 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
329 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
330 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
331 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
332
333 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
334 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
335 // add/sub are legal for all supported vector VT's.
336 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
337 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
338 // mul has to be custom lowered.
339 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
340
341 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
342 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
343 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
344 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
345 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
346 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
347
348 // These operations need to be expanded:
349 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
350 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
351 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
352 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
353 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
354
355 // Custom lower build_vector, constant pool spills, insert and
356 // extract vector elements:
357 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
358 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
359 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
360 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
361 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
362 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
363 }
364
365 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
366 setOperationAction(ISD::AND, MVT::v16i8, Custom);
367 setOperationAction(ISD::OR, MVT::v16i8, Custom);
368 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
369 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000370
Scott Michel266bc8f2007-12-04 22:23:35 +0000371 setSetCCResultType(MVT::i32);
372 setShiftAmountType(MVT::i32);
373 setSetCCResultContents(ZeroOrOneSetCCResult);
374
375 setStackPointerRegisterToSaveRestore(SPU::R1);
376
377 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000378 setTargetDAGCombine(ISD::ADD);
Scott Michel266bc8f2007-12-04 22:23:35 +0000379
380 computeRegisterProperties();
381}
382
383const char *
384SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
385{
386 if (node_names.empty()) {
387 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
388 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
389 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
390 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000391 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000392 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000393 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
394 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
395 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
396 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
397 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
398 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
399 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
400 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
401 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
402 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
403 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
404 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
405 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
406 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
407 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
408 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
409 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
410 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
411 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
412 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
413 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
414 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_Z] =
415 "SPUISD::ROTBYTES_RIGHT_Z";
416 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
417 "SPUISD::ROTBYTES_RIGHT_S";
418 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
419 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
420 "SPUISD::ROTBYTES_LEFT_CHAINED";
421 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
422 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
423 node_names[(unsigned) SPUISD::SFPConstant] = "SPUISD::SFPConstant";
424 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
425 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
426 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
427 }
428
429 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
430
431 return ((i != node_names.end()) ? i->second : 0);
432}
433
434//===----------------------------------------------------------------------===//
435// Calling convention code:
436//===----------------------------------------------------------------------===//
437
438#include "SPUGenCallingConv.inc"
439
440//===----------------------------------------------------------------------===//
441// LowerOperation implementation
442//===----------------------------------------------------------------------===//
443
Scott Michel9de5d0d2008-01-11 02:53:15 +0000444/// Aligned load common code for CellSPU
445/*!
446 \param[in] Op The SelectionDAG load or store operand
447 \param[in] DAG The selection DAG
448 \param[in] ST CellSPU subtarget information structure
449 \param[in,out] alignment Caller initializes this to the load or store node's
450 value from getAlignment(), may be updated while generating the aligned load
451 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
452 offset (divisible by 16, modulo 16 == 0)
453 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
454 offset of the preferred slot (modulo 16 != 0)
455 \param[in,out] VT Caller initializes this value type to the the load or store
456 node's loaded or stored value type; may be updated if an i1-extended load or
457 store.
458 \param[out] was16aligned true if the base pointer had 16-byte alignment,
459 otherwise false. Can help to determine if the chunk needs to be rotated.
460
461 Both load and store lowering load a block of data aligned on a 16-byte
462 boundary. This is the common aligned load code shared between both.
463 */
464static SDOperand
465AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
466 LSBaseSDNode *LSN,
467 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000468 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000469{
470 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
471 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
472 SDOperand basePtr = LSN->getBasePtr();
473 SDOperand chain = LSN->getChain();
474
475 if (basePtr.getOpcode() == ISD::ADD) {
476 SDOperand Op1 = basePtr.Val->getOperand(1);
477
478 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000479 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000480
481 alignOffs = (int) CN->getValue();
482 prefSlotOffs = (int) (alignOffs & 0xf);
483
484 // Adjust the rotation amount to ensure that the final result ends up in
485 // the preferred slot:
486 prefSlotOffs -= vtm->prefslot_byte;
487 basePtr = basePtr.getOperand(0);
488
Scott Michel58c58182008-01-17 20:38:41 +0000489 // Loading from memory, can we adjust alignment?
490 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
491 SDOperand APtr = basePtr.getOperand(0);
492 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
493 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
494 alignment = GSDN->getGlobal()->getAlignment();
495 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000496 }
497 } else {
498 alignOffs = 0;
499 prefSlotOffs = -vtm->prefslot_byte;
500 }
501 } else {
502 alignOffs = 0;
503 prefSlotOffs = -vtm->prefslot_byte;
504 }
505
506 if (alignment == 16) {
507 // Realign the base pointer as a D-Form address:
508 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000509 basePtr = DAG.getNode(ISD::ADD, PtrVT,
510 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000511 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000512 }
513
514 // Emit the vector load:
515 was16aligned = true;
516 return DAG.getLoad(MVT::v16i8, chain, basePtr,
517 LSN->getSrcValue(), LSN->getSrcValueOffset(),
518 LSN->isVolatile(), 16);
519 }
520
521 // Unaligned load or we're using the "large memory" model, which means that
522 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000523 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000524 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000525 }
526
527 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000528 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000529 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000530 was16aligned = false;
531 return DAG.getLoad(MVT::v16i8, chain, basePtr,
532 LSN->getSrcValue(), LSN->getSrcValueOffset(),
533 LSN->isVolatile(), 16);
534}
535
Scott Michel266bc8f2007-12-04 22:23:35 +0000536/// Custom lower loads for CellSPU
537/*!
538 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
539 within a 16-byte block, we have to rotate to extract the requested element.
540 */
541static SDOperand
542LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
543 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000544 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000545 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000546 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000547 ISD::LoadExtType ExtType = LN->getExtensionType();
548 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000549 SDOperand Ops[8];
550
Scott Michel266bc8f2007-12-04 22:23:35 +0000551 switch (LN->getAddressingMode()) {
552 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000553 int offset, rotamt;
554 bool was16aligned;
555 SDOperand result =
556 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000557
Scott Michel9de5d0d2008-01-11 02:53:15 +0000558 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000559 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000560
561 the_chain = result.getValue(1);
562 // Rotate the chunk if necessary
563 if (rotamt < 0)
564 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000565 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000566 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
567
Scott Michel58c58182008-01-17 20:38:41 +0000568 Ops[0] = the_chain;
569 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000570 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000571 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
572 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000573 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000574 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000575 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000576 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000577 }
578
579 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
580 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000581 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000582
583 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
584 SDVTList scalarvts;
585 MVT::ValueType vecVT = MVT::v16i8;
586
587 // Convert the loaded v16i8 vector to the appropriate vector type
588 // specified by the operand:
589 if (OpVT == VT) {
590 if (VT != MVT::i1)
591 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
592 } else
593 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
594
595 Ops[0] = the_chain;
596 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
597 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
598 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
599 the_chain = result.getValue(1);
600 } else {
601 // Handle the sign and zero-extending loads for i1 and i8:
602 unsigned NewOpC;
603
604 if (ExtType == ISD::SEXTLOAD) {
605 NewOpC = (OpVT == MVT::i1
606 ? SPUISD::EXTRACT_I1_SEXT
607 : SPUISD::EXTRACT_I8_SEXT);
608 } else {
609 assert(ExtType == ISD::ZEXTLOAD);
610 NewOpC = (OpVT == MVT::i1
611 ? SPUISD::EXTRACT_I1_ZEXT
612 : SPUISD::EXTRACT_I8_ZEXT);
613 }
614
615 result = DAG.getNode(NewOpC, OpVT, result);
616 }
617
618 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000619 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000620 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000621 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000622 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000623
Scott Michel58c58182008-01-17 20:38:41 +0000624 result = DAG.getNode(SPUISD::LDRESULT, retvts,
625 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000626 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000627 }
628 case ISD::PRE_INC:
629 case ISD::PRE_DEC:
630 case ISD::POST_INC:
631 case ISD::POST_DEC:
632 case ISD::LAST_INDEXED_MODE:
633 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
634 "UNINDEXED\n";
635 cerr << (unsigned) LN->getAddressingMode() << "\n";
636 abort();
637 /*NOTREACHED*/
638 }
639
640 return SDOperand();
641}
642
643/// Custom lower stores for CellSPU
644/*!
645 All CellSPU stores are aligned to 16-byte boundaries, so for elements
646 within a 16-byte block, we have to generate a shuffle to insert the
647 requested element into its place, then store the resulting block.
648 */
649static SDOperand
650LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
651 StoreSDNode *SN = cast<StoreSDNode>(Op);
652 SDOperand Value = SN->getValue();
653 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000654 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000655 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000656 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000657
658 switch (SN->getAddressingMode()) {
659 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000660 int chunk_offset, slot_offset;
661 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000662
663 // The vector type we really want to load from the 16-byte chunk, except
664 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000665 unsigned vecVT, stVecVT = MVT::v16i8;
666
Scott Michel266bc8f2007-12-04 22:23:35 +0000667 if (StVT != MVT::i1)
668 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000669 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
670
Scott Michel9de5d0d2008-01-11 02:53:15 +0000671 SDOperand alignLoadVec =
672 AlignedLoad(Op, DAG, ST, SN, alignment,
673 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000674
Scott Michel9de5d0d2008-01-11 02:53:15 +0000675 if (alignLoadVec.Val == 0)
676 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000677
Scott Michel9de5d0d2008-01-11 02:53:15 +0000678 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
679 SDOperand basePtr = LN->getBasePtr();
680 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000681 SDOperand theValue = SN->getValue();
682 SDOperand result;
683
684 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000685 && (theValue.getOpcode() == ISD::AssertZext
686 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000687 // Drill down and get the value for zero- and sign-extended
688 // quantities
689 theValue = theValue.getOperand(0);
690 }
691
Scott Michel9de5d0d2008-01-11 02:53:15 +0000692 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000693
Scott Michel9de5d0d2008-01-11 02:53:15 +0000694 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
695 SDOperand insertEltPtr;
696 SDOperand insertEltOp;
697
698 // If the base pointer is already a D-form address, then just create
699 // a new D-form address with a slot offset and the orignal base pointer.
700 // Otherwise generate a D-form address with the slot offset relative
701 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000702 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
703 DEBUG(basePtr.Val->dump(&DAG));
704 DEBUG(cerr << "\n");
705
Scott Michel053c1da2008-01-29 02:16:57 +0000706 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
707 (basePtr.getOpcode() == ISD::ADD
708 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000709 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000710 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000711#if 0
712 // $sp is always aligned, so use it when necessary to avoid loading
713 // an address
714 SDOperand ptrP =
715 basePtr.Val->hasOneUse() ? DAG.getRegister(SPU::R1, PtrVT) : basePtr;
716 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, ptrP, insertEltOffs);
717#else
718 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
719#endif
Scott Michel9de5d0d2008-01-11 02:53:15 +0000720 }
721
722 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000723 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000724 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
725 alignLoadVec,
726 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000727
Scott Michel9de5d0d2008-01-11 02:53:15 +0000728 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000729 LN->getSrcValue(), LN->getSrcValueOffset(),
730 LN->isVolatile(), LN->getAlignment());
731
732 return result;
733 /*UNREACHED*/
734 }
735 case ISD::PRE_INC:
736 case ISD::PRE_DEC:
737 case ISD::POST_INC:
738 case ISD::POST_DEC:
739 case ISD::LAST_INDEXED_MODE:
740 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
741 "UNINDEXED\n";
742 cerr << (unsigned) SN->getAddressingMode() << "\n";
743 abort();
744 /*NOTREACHED*/
745 }
746
747 return SDOperand();
748}
749
750/// Generate the address of a constant pool entry.
751static SDOperand
752LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
753 MVT::ValueType PtrVT = Op.getValueType();
754 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
755 Constant *C = CP->getConstVal();
756 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000757 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000758 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000759
760 if (TM.getRelocationModel() == Reloc::Static) {
761 if (!ST->usingLargeMem()) {
762 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000763 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000764 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000765#if 1
Scott Michel266bc8f2007-12-04 22:23:35 +0000766 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
767 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
768
769 return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000770#else
Scott Michel053c1da2008-01-29 02:16:57 +0000771 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, CPI, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000772#endif
Scott Michel266bc8f2007-12-04 22:23:35 +0000773 }
774 }
775
776 assert(0 &&
777 "LowerConstantPool: Relocation model other than static not supported.");
778 return SDOperand();
779}
780
781static SDOperand
782LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
783 MVT::ValueType PtrVT = Op.getValueType();
784 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
785 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
786 SDOperand Zero = DAG.getConstant(0, PtrVT);
787 const TargetMachine &TM = DAG.getTarget();
788
789 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000790 SDOperand JmpAForm = DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000791 return (!ST->usingLargeMem()
Scott Michel053c1da2008-01-29 02:16:57 +0000792 ? JmpAForm
793 : DAG.getNode(SPUISD::IndirectAddr, PtrVT, JmpAForm, Zero));
Scott Michel266bc8f2007-12-04 22:23:35 +0000794 }
795
796 assert(0 &&
797 "LowerJumpTable: Relocation model other than static not supported.");
798 return SDOperand();
799}
800
801static SDOperand
802LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
803 MVT::ValueType PtrVT = Op.getValueType();
804 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
805 GlobalValue *GV = GSDN->getGlobal();
806 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000807 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000808 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000809
810 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000811 if (!ST->usingLargeMem()) {
812 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
813 } else {
814 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
815 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
816 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
817 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000818 } else {
819 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000820 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000821 abort();
822 /*NOTREACHED*/
823 }
824
825 return SDOperand();
826}
827
828//! Custom lower i64 integer constants
829/*!
830 This code inserts all of the necessary juggling that needs to occur to load
831 a 64-bit constant into a register.
832 */
833static SDOperand
834LowerConstant(SDOperand Op, SelectionDAG &DAG) {
835 unsigned VT = Op.getValueType();
836 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
837
838 if (VT == MVT::i64) {
839 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
840 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000841 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000842
843 } else {
844 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000845 << MVT::getValueTypeString(VT)
846 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000847 abort();
848 /*NOTREACHED*/
849 }
850
851 return SDOperand();
852}
853
854//! Custom lower single precision floating point constants
855/*!
856 "float" immediates can be lowered as if they were unsigned 32-bit integers.
857 The SPUISD::SFPConstant pseudo-instruction handles this in the instruction
858 target description.
859 */
860static SDOperand
861LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
862 unsigned VT = Op.getValueType();
863 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
864
865 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000866 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000867
Scott Michel266bc8f2007-12-04 22:23:35 +0000868 if (VT == MVT::f32) {
Scott Michel170783a2007-12-19 20:15:47 +0000869 float targetConst = FP->getValueAPF().convertToFloat();
Scott Michel266bc8f2007-12-04 22:23:35 +0000870 return DAG.getNode(SPUISD::SFPConstant, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000871 DAG.getTargetConstantFP(targetConst, VT));
Scott Michel266bc8f2007-12-04 22:23:35 +0000872 } else if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000873 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000874 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000875 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000876 }
877
878 return SDOperand();
879}
880
Scott Michel58c58182008-01-17 20:38:41 +0000881//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
882static SDOperand
883LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
884{
885 SDOperand Cond = Op.getOperand(1);
886 MVT::ValueType CondVT = Cond.getValueType();
887 MVT::ValueType CondNVT;
888
889 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
890 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
891 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
892 Op.getOperand(0),
893 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
894 Op.getOperand(2));
895 } else
896 return SDOperand(); // Unchanged
897}
898
Scott Michel266bc8f2007-12-04 22:23:35 +0000899static SDOperand
900LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
901{
902 MachineFunction &MF = DAG.getMachineFunction();
903 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000904 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000905 SmallVector<SDOperand, 8> ArgValues;
906 SDOperand Root = Op.getOperand(0);
907 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
908
909 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
910 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
911
912 unsigned ArgOffset = SPUFrameInfo::minStackSize();
913 unsigned ArgRegIdx = 0;
914 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
915
916 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
917
918 // Add DAG nodes to load the arguments or copy them out of registers.
919 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
920 SDOperand ArgVal;
921 bool needsLoad = false;
922 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
923 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
924
925 switch (ObjectVT) {
926 default: {
927 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000928 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000929 << "\n";
930 abort();
931 }
932 case MVT::i8:
933 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000934 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
935 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000936 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
937 ++ArgRegIdx;
938 } else {
939 needsLoad = true;
940 }
941 break;
942 case MVT::i16:
943 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000944 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
945 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000946 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
947 ++ArgRegIdx;
948 } else {
949 needsLoad = true;
950 }
951 break;
952 case MVT::i32:
953 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000954 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
955 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000956 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
957 ++ArgRegIdx;
958 } else {
959 needsLoad = true;
960 }
961 break;
962 case MVT::i64:
963 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000964 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
965 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000966 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
967 ++ArgRegIdx;
968 } else {
969 needsLoad = true;
970 }
971 break;
972 case MVT::f32:
973 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000974 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
975 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000976 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
977 ++ArgRegIdx;
978 } else {
979 needsLoad = true;
980 }
981 break;
982 case MVT::f64:
983 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000984 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
985 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000986 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
987 ++ArgRegIdx;
988 } else {
989 needsLoad = true;
990 }
991 break;
992 case MVT::v2f64:
993 case MVT::v4f32:
994 case MVT::v4i32:
995 case MVT::v8i16:
996 case MVT::v16i8:
997 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000998 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
999 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001000 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
1001 ++ArgRegIdx;
1002 } else {
1003 needsLoad = true;
1004 }
1005 break;
1006 }
1007
1008 // We need to load the argument to a virtual register if we determined above
1009 // that we ran out of physical registers of the appropriate type
1010 if (needsLoad) {
1011 // If the argument is actually used, emit a load from the right stack
1012 // slot.
1013 if (!Op.Val->hasNUsesOfValue(0, ArgNo)) {
1014 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1015 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1016 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
1017 } else {
1018 // Don't emit a dead load.
1019 ArgVal = DAG.getNode(ISD::UNDEF, ObjectVT);
1020 }
1021
1022 ArgOffset += StackSlotSize;
1023 }
1024
1025 ArgValues.push_back(ArgVal);
1026 }
1027
1028 // If the function takes variable number of arguments, make a frame index for
1029 // the start of the first vararg value... for expansion of llvm.va_start.
1030 if (isVarArg) {
1031 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1032 ArgOffset);
1033 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1034 // If this function is vararg, store any remaining integer argument regs to
1035 // their spots on the stack so that they may be loaded by deferencing the
1036 // result of va_next.
1037 SmallVector<SDOperand, 8> MemOps;
1038 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001039 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1040 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001041 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1042 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1043 MemOps.push_back(Store);
1044 // Increment the address by four for the next argument to store
1045 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1046 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1047 }
1048 if (!MemOps.empty())
1049 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1050 }
1051
1052 ArgValues.push_back(Root);
1053
1054 // Return the new list of results.
1055 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1056 Op.Val->value_end());
1057 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1058}
1059
1060/// isLSAAddress - Return the immediate to use if the specified
1061/// value is representable as a LSA address.
1062static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1063 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1064 if (!C) return 0;
1065
1066 int Addr = C->getValue();
1067 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1068 (Addr << 14 >> 14) != Addr)
1069 return 0; // Top 14 bits have to be sext of immediate.
1070
1071 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1072}
1073
1074static
1075SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001076LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001077 SDOperand Chain = Op.getOperand(0);
1078#if 0
1079 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1080 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1081#endif
1082 SDOperand Callee = Op.getOperand(4);
1083 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1084 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1085 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1086 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1087
1088 // Handy pointer type
1089 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1090
1091 // Accumulate how many bytes are to be pushed on the stack, including the
1092 // linkage area, and parameter passing area. According to the SPU ABI,
1093 // we minimally need space for [LR] and [SP]
1094 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1095
1096 // Set up a copy of the stack pointer for use loading and storing any
1097 // arguments that may not fit in the registers available for argument
1098 // passing.
1099 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1100
1101 // Figure out which arguments are going to go in registers, and which in
1102 // memory.
1103 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1104 unsigned ArgRegIdx = 0;
1105
1106 // Keep track of registers passing arguments
1107 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1108 // And the arguments passed on the stack
1109 SmallVector<SDOperand, 8> MemOpChains;
1110
1111 for (unsigned i = 0; i != NumOps; ++i) {
1112 SDOperand Arg = Op.getOperand(5+2*i);
1113
1114 // PtrOff will be used to store the current argument to the stack if a
1115 // register cannot be found for it.
1116 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1117 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1118
1119 switch (Arg.getValueType()) {
1120 default: assert(0 && "Unexpected ValueType for argument!");
1121 case MVT::i32:
1122 case MVT::i64:
1123 case MVT::i128:
1124 if (ArgRegIdx != NumArgRegs) {
1125 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1126 } else {
1127 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001128 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001129 }
1130 break;
1131 case MVT::f32:
1132 case MVT::f64:
1133 if (ArgRegIdx != NumArgRegs) {
1134 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1135 } else {
1136 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001137 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001138 }
1139 break;
1140 case MVT::v4f32:
1141 case MVT::v4i32:
1142 case MVT::v8i16:
1143 case MVT::v16i8:
1144 if (ArgRegIdx != NumArgRegs) {
1145 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1146 } else {
1147 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001148 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001149 }
1150 break;
1151 }
1152 }
1153
1154 // Update number of stack bytes actually used, insert a call sequence start
1155 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1156 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1157
1158 if (!MemOpChains.empty()) {
1159 // Adjust the stack pointer for the stack arguments.
1160 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1161 &MemOpChains[0], MemOpChains.size());
1162 }
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 the appropriate regs.
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 std::vector<MVT::ValueType> NodeTys;
1174 NodeTys.push_back(MVT::Other); // Returns a chain
1175 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1176
1177 SmallVector<SDOperand, 8> Ops;
1178 unsigned CallOpc = SPUISD::CALL;
1179
1180 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1181 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1182 // node so that legalize doesn't hack it.
1183 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1184 GlobalValue *GV = G->getGlobal();
1185 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001186 SDOperand Zero = DAG.getConstant(0, PtrVT);
1187 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001188
Scott Michel9de5d0d2008-01-11 02:53:15 +00001189 if (!ST->usingLargeMem()) {
1190 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1191 // style calls, otherwise, external symbols are BRASL calls. This assumes
1192 // that declared/defined symbols are in the same compilation unit and can
1193 // be reached through PC-relative jumps.
1194 //
1195 // NOTE:
1196 // This may be an unsafe assumption for JIT and really large compilation
1197 // units.
1198 if (GV->isDeclaration()) {
1199 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1200 } else {
1201 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1202 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001203 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001204 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1205 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001206 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001207 }
1208 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1209 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001210 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001211 // If this is an absolute destination address that appears to be a legal
1212 // local store address, use the munged value.
1213 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001214 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001215
1216 Ops.push_back(Chain);
1217 Ops.push_back(Callee);
1218
1219 // Add argument registers to the end of the list so that they are known live
1220 // into the call.
1221 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1222 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1223 RegsToPass[i].second.getValueType()));
1224
1225 if (InFlag.Val)
1226 Ops.push_back(InFlag);
1227 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1228 InFlag = Chain.getValue(1);
1229
1230 SDOperand ResultVals[3];
1231 unsigned NumResults = 0;
1232 NodeTys.clear();
1233
1234 // If the call has results, copy the values out of the ret val registers.
1235 switch (Op.Val->getValueType(0)) {
1236 default: assert(0 && "Unexpected ret value!");
1237 case MVT::Other: break;
1238 case MVT::i32:
1239 if (Op.Val->getValueType(1) == MVT::i32) {
1240 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1241 ResultVals[0] = Chain.getValue(0);
1242 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1243 Chain.getValue(2)).getValue(1);
1244 ResultVals[1] = Chain.getValue(0);
1245 NumResults = 2;
1246 NodeTys.push_back(MVT::i32);
1247 } else {
1248 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1249 ResultVals[0] = Chain.getValue(0);
1250 NumResults = 1;
1251 }
1252 NodeTys.push_back(MVT::i32);
1253 break;
1254 case MVT::i64:
1255 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1256 ResultVals[0] = Chain.getValue(0);
1257 NumResults = 1;
1258 NodeTys.push_back(MVT::i64);
1259 break;
1260 case MVT::f32:
1261 case MVT::f64:
1262 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1263 InFlag).getValue(1);
1264 ResultVals[0] = Chain.getValue(0);
1265 NumResults = 1;
1266 NodeTys.push_back(Op.Val->getValueType(0));
1267 break;
1268 case MVT::v2f64:
1269 case MVT::v4f32:
1270 case MVT::v4i32:
1271 case MVT::v8i16:
1272 case MVT::v16i8:
1273 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1274 InFlag).getValue(1);
1275 ResultVals[0] = Chain.getValue(0);
1276 NumResults = 1;
1277 NodeTys.push_back(Op.Val->getValueType(0));
1278 break;
1279 }
1280
1281 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
1282 DAG.getConstant(NumStackBytes, PtrVT));
1283 NodeTys.push_back(MVT::Other);
1284
1285 // If the function returns void, just return the chain.
1286 if (NumResults == 0)
1287 return Chain;
1288
1289 // Otherwise, merge everything together with a MERGE_VALUES node.
1290 ResultVals[NumResults++] = Chain;
1291 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1292 ResultVals, NumResults);
1293 return Res.getValue(Op.ResNo);
1294}
1295
1296static SDOperand
1297LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1298 SmallVector<CCValAssign, 16> RVLocs;
1299 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1300 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1301 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1302 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1303
1304 // If this is the first return lowered for this function, add the regs to the
1305 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001306 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001307 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001308 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001309 }
1310
1311 SDOperand Chain = Op.getOperand(0);
1312 SDOperand Flag;
1313
1314 // Copy the result values into the output registers.
1315 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1316 CCValAssign &VA = RVLocs[i];
1317 assert(VA.isRegLoc() && "Can only return in registers!");
1318 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1319 Flag = Chain.getValue(1);
1320 }
1321
1322 if (Flag.Val)
1323 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1324 else
1325 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1326}
1327
1328
1329//===----------------------------------------------------------------------===//
1330// Vector related lowering:
1331//===----------------------------------------------------------------------===//
1332
1333static ConstantSDNode *
1334getVecImm(SDNode *N) {
1335 SDOperand OpVal(0, 0);
1336
1337 // Check to see if this buildvec has a single non-undef value in its elements.
1338 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1339 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1340 if (OpVal.Val == 0)
1341 OpVal = N->getOperand(i);
1342 else if (OpVal != N->getOperand(i))
1343 return 0;
1344 }
1345
1346 if (OpVal.Val != 0) {
1347 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1348 return CN;
1349 }
1350 }
1351
1352 return 0; // All UNDEF: use implicit def.; not Constant node
1353}
1354
1355/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1356/// and the value fits into an unsigned 18-bit constant, and if so, return the
1357/// constant
1358SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1359 MVT::ValueType ValueType) {
1360 if (ConstantSDNode *CN = getVecImm(N)) {
1361 uint64_t Value = CN->getValue();
1362 if (Value <= 0x3ffff)
1363 return DAG.getConstant(Value, ValueType);
1364 }
1365
1366 return SDOperand();
1367}
1368
1369/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1370/// and the value fits into a signed 16-bit constant, and if so, return the
1371/// constant
1372SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1373 MVT::ValueType ValueType) {
1374 if (ConstantSDNode *CN = getVecImm(N)) {
1375 if (ValueType == MVT::i32) {
1376 int Value = (int) CN->getValue();
1377 int SExtValue = ((Value & 0xffff) << 16) >> 16;
1378
1379 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001380 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001381 } else if (ValueType == MVT::i16) {
1382 short Value = (short) CN->getValue();
1383 int SExtValue = ((int) Value << 16) >> 16;
1384
1385 if (Value == (short) SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001386 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001387 } else if (ValueType == MVT::i64) {
1388 int64_t Value = CN->getValue();
1389 int64_t SExtValue = ((Value & 0xffff) << (64 - 16)) >> (64 - 16);
1390
1391 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001392 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001393 }
1394 }
1395
1396 return SDOperand();
1397}
1398
1399/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1400/// and the value fits into a signed 10-bit constant, and if so, return the
1401/// constant
1402SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1403 MVT::ValueType ValueType) {
1404 if (ConstantSDNode *CN = getVecImm(N)) {
1405 int Value = (int) CN->getValue();
1406 if ((ValueType == MVT::i32 && isS10Constant(Value))
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001407 || (ValueType == MVT::i16 && isS10Constant((short) Value)))
Scott Michel266bc8f2007-12-04 22:23:35 +00001408 return DAG.getConstant(Value, ValueType);
1409 }
1410
1411 return SDOperand();
1412}
1413
1414/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1415/// and the value fits into a signed 8-bit constant, and if so, return the
1416/// constant.
1417///
1418/// @note: The incoming vector is v16i8 because that's the only way we can load
1419/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1420/// same value.
1421SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1422 MVT::ValueType ValueType) {
1423 if (ConstantSDNode *CN = getVecImm(N)) {
1424 int Value = (int) CN->getValue();
1425 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001426 && Value <= 0xffff /* truncated from uint64_t */
1427 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001428 return DAG.getConstant(Value & 0xff, ValueType);
1429 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001430 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001431 return DAG.getConstant(Value, ValueType);
1432 }
1433
1434 return SDOperand();
1435}
1436
1437/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1438/// and the value fits into a signed 16-bit constant, and if so, return the
1439/// constant
1440SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1441 MVT::ValueType ValueType) {
1442 if (ConstantSDNode *CN = getVecImm(N)) {
1443 uint64_t Value = CN->getValue();
1444 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001445 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1446 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001447 return DAG.getConstant(Value >> 16, ValueType);
1448 }
1449
1450 return SDOperand();
1451}
1452
1453/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1454SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1455 if (ConstantSDNode *CN = getVecImm(N)) {
1456 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1457 }
1458
1459 return SDOperand();
1460}
1461
1462/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1463SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1464 if (ConstantSDNode *CN = getVecImm(N)) {
1465 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1466 }
1467
1468 return SDOperand();
1469}
1470
1471// If this is a vector of constants or undefs, get the bits. A bit in
1472// UndefBits is set if the corresponding element of the vector is an
1473// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1474// zero. Return true if this is not an array of constants, false if it is.
1475//
1476static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1477 uint64_t UndefBits[2]) {
1478 // Start with zero'd results.
1479 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1480
1481 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1482 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1483 SDOperand OpVal = BV->getOperand(i);
1484
1485 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1486 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1487
1488 uint64_t EltBits = 0;
1489 if (OpVal.getOpcode() == ISD::UNDEF) {
1490 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1491 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1492 continue;
1493 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1494 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1495 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1496 const APFloat &apf = CN->getValueAPF();
1497 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001498 ? FloatToBits(apf.convertToFloat())
1499 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001500 } else {
1501 // Nonconstant element.
1502 return true;
1503 }
1504
1505 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1506 }
1507
1508 //printf("%llx %llx %llx %llx\n",
1509 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1510 return false;
1511}
1512
1513/// If this is a splat (repetition) of a value across the whole vector, return
1514/// the smallest size that splats it. For example, "0x01010101010101..." is a
1515/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1516/// SplatSize = 1 byte.
1517static bool isConstantSplat(const uint64_t Bits128[2],
1518 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001519 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001520 uint64_t &SplatBits, uint64_t &SplatUndef,
1521 int &SplatSize) {
1522 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1523 // the same as the lower 64-bits, ignoring undefs.
1524 uint64_t Bits64 = Bits128[0] | Bits128[1];
1525 uint64_t Undef64 = Undef128[0] & Undef128[1];
1526 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1527 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1528 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1529 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1530
1531 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1532 if (MinSplatBits < 64) {
1533
1534 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1535 // undefs.
1536 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001537 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001538
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001539 // If the top 16-bits are different than the lower 16-bits, ignoring
1540 // undefs, we have an i32 splat.
1541 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1542 if (MinSplatBits < 16) {
1543 // If the top 8-bits are different than the lower 8-bits, ignoring
1544 // undefs, we have an i16 splat.
1545 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1546 // Otherwise, we have an 8-bit splat.
1547 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1548 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1549 SplatSize = 1;
1550 return true;
1551 }
1552 } else {
1553 SplatBits = Bits16;
1554 SplatUndef = Undef16;
1555 SplatSize = 2;
1556 return true;
1557 }
1558 }
1559 } else {
1560 SplatBits = Bits32;
1561 SplatUndef = Undef32;
1562 SplatSize = 4;
1563 return true;
1564 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001565 }
1566 } else {
1567 SplatBits = Bits128[0];
1568 SplatUndef = Undef128[0];
1569 SplatSize = 8;
1570 return true;
1571 }
1572 }
1573
1574 return false; // Can't be a splat if two pieces don't match.
1575}
1576
1577// If this is a case we can't handle, return null and let the default
1578// expansion code take care of it. If we CAN select this case, and if it
1579// selects to a single instruction, return Op. Otherwise, if we can codegen
1580// this case more efficiently than a constant pool load, lower it to the
1581// sequence of ops that should be used.
1582static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1583 MVT::ValueType VT = Op.getValueType();
1584 // If this is a vector of constants or undefs, get the bits. A bit in
1585 // UndefBits is set if the corresponding element of the vector is an
1586 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1587 // zero.
1588 uint64_t VectorBits[2];
1589 uint64_t UndefBits[2];
1590 uint64_t SplatBits, SplatUndef;
1591 int SplatSize;
1592 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1593 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001594 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001595 SplatBits, SplatUndef, SplatSize))
1596 return SDOperand(); // Not a constant vector, not a splat.
1597
1598 switch (VT) {
1599 default:
1600 case MVT::v4f32: {
1601 uint32_t Value32 = SplatBits;
1602 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001603 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001604 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1605 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1606 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001607 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001608 break;
1609 }
1610 case MVT::v2f64: {
1611 uint64_t f64val = SplatBits;
1612 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001613 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001614 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1615 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1616 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001617 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001618 break;
1619 }
1620 case MVT::v16i8: {
1621 // 8-bit constants have to be expanded to 16-bits
1622 unsigned short Value16 = SplatBits | (SplatBits << 8);
1623 SDOperand Ops[8];
1624 for (int i = 0; i < 8; ++i)
1625 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1626 return DAG.getNode(ISD::BIT_CONVERT, VT,
1627 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1628 }
1629 case MVT::v8i16: {
1630 unsigned short Value16;
1631 if (SplatSize == 2)
1632 Value16 = (unsigned short) (SplatBits & 0xffff);
1633 else
1634 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1635 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1636 SDOperand Ops[8];
1637 for (int i = 0; i < 8; ++i) Ops[i] = T;
1638 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1639 }
1640 case MVT::v4i32: {
1641 unsigned int Value = SplatBits;
1642 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1643 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1644 }
1645 case MVT::v2i64: {
1646 uint64_t val = SplatBits;
1647 uint32_t upper = uint32_t(val >> 32);
1648 uint32_t lower = uint32_t(val);
1649
1650 if (val != 0) {
1651 SDOperand LO32;
1652 SDOperand HI32;
1653 SmallVector<SDOperand, 16> ShufBytes;
1654 SDOperand Result;
1655 bool upper_special, lower_special;
1656
1657 // NOTE: This code creates common-case shuffle masks that can be easily
1658 // detected as common expressions. It is not attempting to create highly
1659 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1660
1661 // Detect if the upper or lower half is a special shuffle mask pattern:
1662 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1663 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1664
1665 // Create lower vector if not a special pattern
1666 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001667 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1668 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1669 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1670 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001671 }
1672
1673 // Create upper vector if not a special pattern
1674 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001675 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1676 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1677 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1678 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001679 }
1680
1681 // If either upper or lower are special, then the two input operands are
1682 // the same (basically, one of them is a "don't care")
1683 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001684 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001685 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001686 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001687 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001688 // Unhappy situation... both upper and lower are special, so punt with
1689 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001690 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001691 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001692 Zero, Zero);
1693 }
1694
1695 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001696 for (int j = 0; j < 4; ++j) {
1697 SDOperand V;
1698 bool process_upper, process_lower;
1699 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001700
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001701 process_upper = (upper_special && (i & 1) == 0);
1702 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001703
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001704 if (process_upper || process_lower) {
1705 if ((process_upper && upper == 0)
1706 || (process_lower && lower == 0))
1707 val = 0x80;
1708 else if ((process_upper && upper == 0xffffffff)
1709 || (process_lower && lower == 0xffffffff))
1710 val = 0xc0;
1711 else if ((process_upper && upper == 0x80000000)
1712 || (process_lower && lower == 0x80000000))
1713 val = (j == 0 ? 0xe0 : 0x80);
1714 } else
1715 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001716
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001717 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1718 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001719 }
1720
1721 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001722 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1723 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001724 } else {
1725 // For zero, this can be lowered efficiently via v4i32 BUILD_VECTOR
1726 SDOperand Zero = DAG.getConstant(0, MVT::i32);
1727 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001728 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1729 Zero, Zero, Zero, Zero));
Scott Michel266bc8f2007-12-04 22:23:35 +00001730 }
1731 }
1732 }
1733
1734 return SDOperand();
1735}
1736
1737/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1738/// which the Cell can operate. The code inspects V3 to ascertain whether the
1739/// permutation vector, V3, is monotonically increasing with one "exception"
1740/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1741/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1742/// In either case, the net result is going to eventually invoke SHUFB to
1743/// permute/shuffle the bytes from V1 and V2.
1744/// \note
1745/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1746/// control word for byte/halfword/word insertion. This takes care of a single
1747/// element move from V2 into V1.
1748/// \note
1749/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1750static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1751 SDOperand V1 = Op.getOperand(0);
1752 SDOperand V2 = Op.getOperand(1);
1753 SDOperand PermMask = Op.getOperand(2);
1754
1755 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1756
1757 // If we have a single element being moved from V1 to V2, this can be handled
1758 // using the C*[DX] compute mask instructions, but the vector elements have
1759 // to be monotonically increasing with one exception element.
1760 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1761 unsigned EltsFromV2 = 0;
1762 unsigned V2Elt = 0;
1763 unsigned V2EltIdx0 = 0;
1764 unsigned CurrElt = 0;
1765 bool monotonic = true;
1766 if (EltVT == MVT::i8)
1767 V2EltIdx0 = 16;
1768 else if (EltVT == MVT::i16)
1769 V2EltIdx0 = 8;
1770 else if (EltVT == MVT::i32)
1771 V2EltIdx0 = 4;
1772 else
1773 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1774
1775 for (unsigned i = 0, e = PermMask.getNumOperands();
1776 EltsFromV2 <= 1 && monotonic && i != e;
1777 ++i) {
1778 unsigned SrcElt;
1779 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1780 SrcElt = 0;
1781 else
1782 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1783
1784 if (SrcElt >= V2EltIdx0) {
1785 ++EltsFromV2;
1786 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1787 } else if (CurrElt != SrcElt) {
1788 monotonic = false;
1789 }
1790
1791 ++CurrElt;
1792 }
1793
1794 if (EltsFromV2 == 1 && monotonic) {
1795 // Compute mask and shuffle
1796 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001797 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1798 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001799 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1800 // Initialize temporary register to 0
1801 SDOperand InitTempReg =
1802 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1803 // Copy register's contents as index in INSERT_MASK:
1804 SDOperand ShufMaskOp =
1805 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001806 DAG.getTargetConstant(V2Elt, MVT::i32),
1807 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001808 // Use shuffle mask in SHUFB synthetic instruction:
1809 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1810 } else {
1811 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1812 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1813
1814 SmallVector<SDOperand, 16> ResultMask;
1815 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1816 unsigned SrcElt;
1817 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001818 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001819 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001820 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001821
1822 for (unsigned j = 0; j != BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001823 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1824 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001825 }
1826 }
1827
1828 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001829 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001830 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1831 }
1832}
1833
1834static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001835 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001836
1837 if (Op0.Val->getOpcode() == ISD::Constant) {
1838 // For a constant, build the appropriate constant vector, which will
1839 // eventually simplify to a vector register load.
1840
1841 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1842 SmallVector<SDOperand, 16> ConstVecValues;
1843 MVT::ValueType VT;
1844 size_t n_copies;
1845
1846 // Create a constant vector:
1847 switch (Op.getValueType()) {
1848 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001849 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001850 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1851 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1852 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1853 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1854 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1855 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1856 }
1857
1858 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1859 for (size_t j = 0; j < n_copies; ++j)
1860 ConstVecValues.push_back(CValue);
1861
1862 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001863 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001864 } else {
1865 // Otherwise, copy the value from one register to another:
1866 switch (Op0.getValueType()) {
1867 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1868 case MVT::i8:
1869 case MVT::i16:
1870 case MVT::i32:
1871 case MVT::i64:
1872 case MVT::f32:
1873 case MVT::f64:
1874 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1875 }
1876 }
1877
1878 return SDOperand();
1879}
1880
1881static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1882 switch (Op.getValueType()) {
1883 case MVT::v4i32: {
1884 SDOperand rA = Op.getOperand(0);
1885 SDOperand rB = Op.getOperand(1);
1886 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1887 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1888 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1889 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1890
1891 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1892 break;
1893 }
1894
1895 // Multiply two v8i16 vectors (pipeline friendly version):
1896 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1897 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1898 // c) Use SELB to select upper and lower halves from the intermediate results
1899 //
1900 // NOTE: We really want to move the FSMBI to earlier to actually get the
1901 // dual-issue. This code does manage to do this, even if it's a little on
1902 // the wacky side
1903 case MVT::v8i16: {
1904 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001905 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001906 SDOperand Chain = Op.getOperand(0);
1907 SDOperand rA = Op.getOperand(0);
1908 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001909 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1910 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001911
1912 SDOperand FSMBOp =
1913 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001914 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1915 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001916
1917 SDOperand HHProd =
1918 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001919 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001920
1921 SDOperand HHProd_v4i32 =
1922 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001923 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001924
1925 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001926 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1927 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1928 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1929 HHProd_v4i32,
1930 DAG.getConstant(16, MVT::i16))),
1931 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001932 }
1933
1934 // This M00sE is N@stI! (apologies to Monty Python)
1935 //
1936 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1937 // is to break it all apart, sign extend, and reassemble the various
1938 // intermediate products.
1939 case MVT::v16i8: {
1940 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001941 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001942 SDOperand Chain = Op.getOperand(0);
1943 SDOperand rA = Op.getOperand(0);
1944 SDOperand rB = Op.getOperand(1);
1945 SDOperand c8 = DAG.getConstant(8, MVT::i8);
1946 SDOperand c16 = DAG.getConstant(16, MVT::i8);
1947
Chris Lattner84bc5422007-12-31 04:13:23 +00001948 unsigned FSMBreg_2222 = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1949 unsigned LoProd_reg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1950 unsigned HiProd_reg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001951
1952 SDOperand LLProd =
1953 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001954 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1955 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001956
1957 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1958
1959 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1960
1961 SDOperand LHProd =
1962 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001963 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001964
1965 SDOperand FSMBdef_2222 =
1966 DAG.getCopyToReg(Chain, FSMBreg_2222,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001967 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1968 DAG.getConstant(0x2222, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001969
1970 SDOperand FSMBuse_2222 =
1971 DAG.getCopyFromReg(FSMBdef_2222, FSMBreg_2222, MVT::v4i32);
1972
1973 SDOperand LoProd_1 =
1974 DAG.getCopyToReg(Chain, LoProd_reg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001975 DAG.getNode(SPUISD::SELB, MVT::v8i16, LLProd, LHProd,
1976 FSMBuse_2222));
Scott Michel266bc8f2007-12-04 22:23:35 +00001977
1978 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1979
1980 SDOperand LoProd =
1981 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001982 DAG.getCopyFromReg(LoProd_1, LoProd_reg, MVT::v4i32),
1983 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1984 LoProdMask, LoProdMask,
1985 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001986
1987 SDOperand rAH =
1988 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001989 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001990
1991 SDOperand rBH =
1992 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001993 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001994
1995 SDOperand HLProd =
1996 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001997 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1998 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001999
2000 SDOperand HHProd_1 =
2001 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002002 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2003 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
2004 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2005 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002006
2007 SDOperand HHProd =
2008 DAG.getCopyToReg(Chain, HiProd_reg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002009 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2010 HLProd,
2011 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2012 FSMBuse_2222));
Scott Michel266bc8f2007-12-04 22:23:35 +00002013
2014 SDOperand HiProd =
2015 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002016 DAG.getCopyFromReg(HHProd, HiProd_reg, MVT::v4i32), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002017
2018 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002019 DAG.getNode(ISD::OR, MVT::v4i32,
2020 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002021 }
2022
2023 default:
2024 cerr << "CellSPU: Unknown vector multiplication, got "
2025 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002026 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002027 abort();
2028 /*NOTREACHED*/
2029 }
2030
2031 return SDOperand();
2032}
2033
2034static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2035 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002036 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002037
2038 SDOperand A = Op.getOperand(0);
2039 SDOperand B = Op.getOperand(1);
2040 unsigned VT = Op.getValueType();
2041
2042 unsigned VRegBR, VRegC;
2043
2044 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002045 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2046 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002047 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002048 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2049 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002050 }
2051 // TODO: make sure we're feeding FPInterp the right arguments
2052 // Right now: fi B, frest(B)
2053
2054 // Computes BRcpl =
2055 // (Floating Interpolate (FP Reciprocal Estimate B))
2056 SDOperand BRcpl =
2057 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002058 DAG.getNode(SPUISD::FPInterp, VT, B,
2059 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002060
2061 // Computes A * BRcpl and stores in a temporary register
2062 SDOperand AxBRcpl =
2063 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002064 DAG.getNode(ISD::FMUL, VT, A,
2065 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002066 // What's the Chain variable do? It's magic!
2067 // TODO: set Chain = Op(0).getEntryNode()
2068
2069 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002070 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2071 DAG.getNode(ISD::FMUL, VT,
2072 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2073 DAG.getNode(ISD::FSUB, VT, A,
2074 DAG.getNode(ISD::FMUL, VT, B,
2075 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002076}
2077
Scott Michel266bc8f2007-12-04 22:23:35 +00002078static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2079 unsigned VT = Op.getValueType();
2080 SDOperand N = Op.getOperand(0);
2081 SDOperand Elt = Op.getOperand(1);
2082 SDOperand ShufMask[16];
2083 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2084
2085 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2086
2087 int EltNo = (int) C->getValue();
2088
2089 // sanity checks:
2090 if (VT == MVT::i8 && EltNo >= 16)
2091 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2092 else if (VT == MVT::i16 && EltNo >= 8)
2093 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2094 else if (VT == MVT::i32 && EltNo >= 4)
2095 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2096 else if (VT == MVT::i64 && EltNo >= 2)
2097 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2098
2099 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2100 // i32 and i64: Element 0 is the preferred slot
2101 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2102 }
2103
2104 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002105 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002106 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2107
2108 switch (VT) {
2109 case MVT::i8: {
2110 prefslot_begin = prefslot_end = 3;
2111 break;
2112 }
2113 case MVT::i16: {
2114 prefslot_begin = 2; prefslot_end = 3;
2115 break;
2116 }
2117 case MVT::i32: {
2118 prefslot_begin = 0; prefslot_end = 3;
2119 break;
2120 }
2121 case MVT::i64: {
2122 prefslot_begin = 0; prefslot_end = 7;
2123 break;
2124 }
2125 }
2126
Scott Michel0e5665b2007-12-19 21:17:42 +00002127 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002128 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002129
Scott Michel266bc8f2007-12-04 22:23:35 +00002130 for (int i = 0; i < 16; ++i) {
2131 // zero fill uppper part of preferred slot, don't care about the
2132 // other slots:
2133 unsigned int mask_val;
2134
2135 if (i <= prefslot_end) {
2136 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002137 ((i < prefslot_begin)
2138 ? 0x80
2139 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002140
Scott Michel0e5665b2007-12-19 21:17:42 +00002141 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002142 } else
2143 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2144 }
2145
2146 SDOperand ShufMaskVec =
2147 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002148 &ShufMask[0],
2149 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002150
2151 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002152 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2153 N, N, ShufMaskVec));
2154
Scott Michel266bc8f2007-12-04 22:23:35 +00002155}
2156
2157static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2158 SDOperand VecOp = Op.getOperand(0);
2159 SDOperand ValOp = Op.getOperand(1);
2160 SDOperand IdxOp = Op.getOperand(2);
2161 MVT::ValueType VT = Op.getValueType();
2162
2163 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2164 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2165
2166 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2167 // Use $2 because it's always 16-byte aligned and it's available:
2168 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2169
2170 SDOperand result =
2171 DAG.getNode(SPUISD::SHUFB, VT,
2172 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2173 VecOp,
2174 DAG.getNode(SPUISD::INSERT_MASK, VT,
2175 DAG.getNode(ISD::ADD, PtrVT,
2176 PtrBase,
2177 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002178 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002179
2180 return result;
2181}
2182
2183static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc) {
2184 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2185
2186 assert(Op.getValueType() == MVT::i8);
2187 switch (Opc) {
2188 default:
2189 assert(0 && "Unhandled i8 math operator");
2190 /*NOTREACHED*/
2191 break;
2192 case ISD::SUB: {
2193 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2194 // the result:
2195 SDOperand N1 = Op.getOperand(1);
2196 N0 = (N0.getOpcode() != ISD::Constant
2197 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2198 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2199 N1 = (N1.getOpcode() != ISD::Constant
2200 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2201 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2202 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2203 DAG.getNode(Opc, MVT::i16, N0, N1));
2204 }
2205 case ISD::ROTR:
2206 case ISD::ROTL: {
2207 SDOperand N1 = Op.getOperand(1);
2208 unsigned N1Opc;
2209 N0 = (N0.getOpcode() != ISD::Constant
2210 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2211 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2212 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2213 N1 = (N1.getOpcode() != ISD::Constant
2214 ? DAG.getNode(N1Opc, MVT::i16, N1)
2215 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2216 SDOperand ExpandArg =
2217 DAG.getNode(ISD::OR, MVT::i16, N0,
2218 DAG.getNode(ISD::SHL, MVT::i16,
2219 N0, DAG.getConstant(8, MVT::i16)));
2220 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2221 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2222 }
2223 case ISD::SRL:
2224 case ISD::SHL: {
2225 SDOperand N1 = Op.getOperand(1);
2226 unsigned N1Opc;
2227 N0 = (N0.getOpcode() != ISD::Constant
2228 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2229 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2230 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2231 N1 = (N1.getOpcode() != ISD::Constant
2232 ? DAG.getNode(N1Opc, MVT::i16, N1)
2233 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2234 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2235 DAG.getNode(Opc, MVT::i16, N0, N1));
2236 }
2237 case ISD::SRA: {
2238 SDOperand N1 = Op.getOperand(1);
2239 unsigned N1Opc;
2240 N0 = (N0.getOpcode() != ISD::Constant
2241 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2242 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2243 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2244 N1 = (N1.getOpcode() != ISD::Constant
2245 ? DAG.getNode(N1Opc, MVT::i16, N1)
2246 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2247 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2248 DAG.getNode(Opc, MVT::i16, N0, N1));
2249 }
2250 case ISD::MUL: {
2251 SDOperand N1 = Op.getOperand(1);
2252 unsigned N1Opc;
2253 N0 = (N0.getOpcode() != ISD::Constant
2254 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2255 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2256 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2257 N1 = (N1.getOpcode() != ISD::Constant
2258 ? DAG.getNode(N1Opc, MVT::i16, N1)
2259 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2260 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2261 DAG.getNode(Opc, MVT::i16, N0, N1));
2262 break;
2263 }
2264 }
2265
2266 return SDOperand();
2267}
2268
2269//! Lower byte immediate operations for v16i8 vectors:
2270static SDOperand
2271LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2272 SDOperand ConstVec;
2273 SDOperand Arg;
2274 MVT::ValueType VT = Op.getValueType();
2275
2276 ConstVec = Op.getOperand(0);
2277 Arg = Op.getOperand(1);
2278 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2279 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2280 ConstVec = ConstVec.getOperand(0);
2281 } else {
2282 ConstVec = Op.getOperand(1);
2283 Arg = Op.getOperand(0);
2284 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002285 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002286 }
2287 }
2288 }
2289
2290 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2291 uint64_t VectorBits[2];
2292 uint64_t UndefBits[2];
2293 uint64_t SplatBits, SplatUndef;
2294 int SplatSize;
2295
2296 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002297 && isConstantSplat(VectorBits, UndefBits,
2298 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2299 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002300 SDOperand tcVec[16];
2301 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2302 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2303
2304 // Turn the BUILD_VECTOR into a set of target constants:
2305 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002306 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002307
2308 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002309 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002310 }
2311 }
2312
2313 return SDOperand();
2314}
2315
2316//! Lower i32 multiplication
2317static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2318 unsigned Opc) {
2319 switch (VT) {
2320 default:
2321 cerr << "CellSPU: Unknown LowerMUL value type, got "
2322 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002323 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002324 abort();
2325 /*NOTREACHED*/
2326
2327 case MVT::i32: {
2328 SDOperand rA = Op.getOperand(0);
2329 SDOperand rB = Op.getOperand(1);
2330
2331 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002332 DAG.getNode(ISD::ADD, MVT::i32,
2333 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2334 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2335 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002336 }
2337 }
2338
2339 return SDOperand();
2340}
2341
2342//! Custom lowering for CTPOP (count population)
2343/*!
2344 Custom lowering code that counts the number ones in the input
2345 operand. SPU has such an instruction, but it counts the number of
2346 ones per byte, which then have to be accumulated.
2347*/
2348static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2349 unsigned VT = Op.getValueType();
2350 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2351
2352 switch (VT) {
2353 case MVT::i8: {
2354 SDOperand N = Op.getOperand(0);
2355 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2356
2357 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2358 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2359
2360 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2361 }
2362
2363 case MVT::i16: {
2364 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002365 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002366
Chris Lattner84bc5422007-12-31 04:13:23 +00002367 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002368
2369 SDOperand N = Op.getOperand(0);
2370 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2371 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2372 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2373
2374 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2375 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2376
2377 // CNTB_result becomes the chain to which all of the virtual registers
2378 // CNTB_reg, SUM1_reg become associated:
2379 SDOperand CNTB_result =
2380 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002381
Scott Michel266bc8f2007-12-04 22:23:35 +00002382 SDOperand CNTB_rescopy =
2383 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2384
2385 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2386
2387 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002388 DAG.getNode(ISD::ADD, MVT::i16,
2389 DAG.getNode(ISD::SRL, MVT::i16,
2390 Tmp1, Shift1),
2391 Tmp1),
2392 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002393 }
2394
2395 case MVT::i32: {
2396 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002397 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002398
Chris Lattner84bc5422007-12-31 04:13:23 +00002399 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2400 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002401
2402 SDOperand N = Op.getOperand(0);
2403 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2404 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2405 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2406 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2407
2408 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2409 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2410
2411 // CNTB_result becomes the chain to which all of the virtual registers
2412 // CNTB_reg, SUM1_reg become associated:
2413 SDOperand CNTB_result =
2414 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002415
Scott Michel266bc8f2007-12-04 22:23:35 +00002416 SDOperand CNTB_rescopy =
2417 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2418
2419 SDOperand Comp1 =
2420 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002421 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002422
2423 SDOperand Sum1 =
2424 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002425 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002426
2427 SDOperand Sum1_rescopy =
2428 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2429
2430 SDOperand Comp2 =
2431 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002432 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2433 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002434 SDOperand Sum2 =
2435 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002436 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002437
2438 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2439 }
2440
2441 case MVT::i64:
2442 break;
2443 }
2444
2445 return SDOperand();
2446}
2447
2448/// LowerOperation - Provide custom lowering hooks for some operations.
2449///
2450SDOperand
2451SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2452{
2453 switch (Op.getOpcode()) {
2454 default: {
2455 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
2456 cerr << "Op.getOpcode() = " << Op.getOpcode() << "\n";
2457 cerr << "*Op.Val:\n";
2458 Op.Val->dump();
2459 abort();
2460 }
2461 case ISD::LOAD:
2462 case ISD::SEXTLOAD:
2463 case ISD::ZEXTLOAD:
2464 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2465 case ISD::STORE:
2466 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2467 case ISD::ConstantPool:
2468 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2469 case ISD::GlobalAddress:
2470 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2471 case ISD::JumpTable:
2472 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2473 case ISD::Constant:
2474 return LowerConstant(Op, DAG);
2475 case ISD::ConstantFP:
2476 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002477 case ISD::BRCOND:
2478 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002479 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002480 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002481 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002482 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002483 case ISD::RET:
2484 return LowerRET(Op, DAG, getTargetMachine());
2485
2486 // i8 math ops:
2487 case ISD::SUB:
2488 case ISD::ROTR:
2489 case ISD::ROTL:
2490 case ISD::SRL:
2491 case ISD::SHL:
2492 case ISD::SRA:
2493 return LowerI8Math(Op, DAG, Op.getOpcode());
2494
2495 // Vector-related lowering.
2496 case ISD::BUILD_VECTOR:
2497 return LowerBUILD_VECTOR(Op, DAG);
2498 case ISD::SCALAR_TO_VECTOR:
2499 return LowerSCALAR_TO_VECTOR(Op, DAG);
2500 case ISD::VECTOR_SHUFFLE:
2501 return LowerVECTOR_SHUFFLE(Op, DAG);
2502 case ISD::EXTRACT_VECTOR_ELT:
2503 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2504 case ISD::INSERT_VECTOR_ELT:
2505 return LowerINSERT_VECTOR_ELT(Op, DAG);
2506
2507 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2508 case ISD::AND:
2509 case ISD::OR:
2510 case ISD::XOR:
2511 return LowerByteImmed(Op, DAG);
2512
2513 // Vector and i8 multiply:
2514 case ISD::MUL:
2515 if (MVT::isVector(Op.getValueType()))
2516 return LowerVectorMUL(Op, DAG);
2517 else if (Op.getValueType() == MVT::i8)
2518 return LowerI8Math(Op, DAG, Op.getOpcode());
2519 else
2520 return LowerMUL(Op, DAG, Op.getValueType(), Op.getOpcode());
2521
2522 case ISD::FDIV:
2523 if (Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::v4f32)
2524 return LowerFDIVf32(Op, DAG);
2525// else if (Op.getValueType() == MVT::f64)
2526// return LowerFDIVf64(Op, DAG);
2527 else
2528 assert(0 && "Calling FDIV on unsupported MVT");
2529
2530 case ISD::CTPOP:
2531 return LowerCTPOP(Op, DAG);
2532 }
2533
2534 return SDOperand();
2535}
2536
2537//===----------------------------------------------------------------------===//
2538// Other Lowering Code
2539//===----------------------------------------------------------------------===//
2540
2541MachineBasicBlock *
2542SPUTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
2543 MachineBasicBlock *BB)
2544{
2545 return BB;
2546}
2547
2548//===----------------------------------------------------------------------===//
2549// Target Optimization Hooks
2550//===----------------------------------------------------------------------===//
2551
2552SDOperand
2553SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2554{
2555#if 0
2556 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002557#endif
2558 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002559 SelectionDAG &DAG = DCI.DAG;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002560 SDOperand N0 = N->getOperand(0); // everything has at least one operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002561
2562 switch (N->getOpcode()) {
2563 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002564 case SPUISD::IndirectAddr: {
2565 if (!ST->usingLargeMem() && N0.getOpcode() == SPUISD::AFormAddr) {
2566 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2567 if (CN->getValue() == 0) {
2568 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2569 // (SPUaform <addr>, 0)
2570
2571 DEBUG(cerr << "Replace: ");
2572 DEBUG(N->dump(&DAG));
2573 DEBUG(cerr << "\nWith: ");
2574 DEBUG(N0.Val->dump(&DAG));
2575 DEBUG(cerr << "\n");
2576
2577 return N0;
2578 }
2579 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002580 }
Scott Michel053c1da2008-01-29 02:16:57 +00002581 case ISD::ADD: {
2582 SDOperand Op0 = N->getOperand(0);
2583 SDOperand Op1 = N->getOperand(1);
2584
2585 if ((Op1.getOpcode() == ISD::Constant
2586 || Op1.getOpcode() == ISD::TargetConstant)
2587 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2588 SDOperand Op01 = Op0.getOperand(1);
2589 if (Op01.getOpcode() == ISD::Constant
2590 || Op01.getOpcode() == ISD::TargetConstant) {
2591 // (add <const>, (SPUindirect <arg>, <const>)) ->
2592 // (SPUindirect <arg>, <const + const>)
2593 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2594 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2595 SDOperand combinedConst =
2596 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2597 Op0.getValueType());
2598
2599 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2600 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2601 DEBUG(cerr << "With: (SPUindirect <arg>, "
2602 << CN0->getValue() + CN1->getValue() << ")\n");
2603 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2604 Op0.getOperand(0), combinedConst);
2605 }
2606 } else if ((Op0.getOpcode() == ISD::Constant
2607 || Op0.getOpcode() == ISD::TargetConstant)
2608 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2609 SDOperand Op11 = Op1.getOperand(1);
2610 if (Op11.getOpcode() == ISD::Constant
2611 || Op11.getOpcode() == ISD::TargetConstant) {
2612 // (add (SPUindirect <arg>, <const>), <const>) ->
2613 // (SPUindirect <arg>, <const + const>)
2614 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2615 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2616 SDOperand combinedConst =
2617 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2618 Op0.getValueType());
2619
2620 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2621 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2622 DEBUG(cerr << "With: (SPUindirect <arg>, "
2623 << CN0->getValue() + CN1->getValue() << ")\n");
2624
2625 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2626 Op1.getOperand(0), combinedConst);
2627 }
2628 }
2629 }
2630 }
Scott Michel58c58182008-01-17 20:38:41 +00002631 // Otherwise, return unchanged.
Scott Michel266bc8f2007-12-04 22:23:35 +00002632 return SDOperand();
2633}
2634
2635//===----------------------------------------------------------------------===//
2636// Inline Assembly Support
2637//===----------------------------------------------------------------------===//
2638
2639/// getConstraintType - Given a constraint letter, return the type of
2640/// constraint it is for this target.
2641SPUTargetLowering::ConstraintType
2642SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2643 if (ConstraintLetter.size() == 1) {
2644 switch (ConstraintLetter[0]) {
2645 default: break;
2646 case 'b':
2647 case 'r':
2648 case 'f':
2649 case 'v':
2650 case 'y':
2651 return C_RegisterClass;
2652 }
2653 }
2654 return TargetLowering::getConstraintType(ConstraintLetter);
2655}
2656
2657std::pair<unsigned, const TargetRegisterClass*>
2658SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2659 MVT::ValueType VT) const
2660{
2661 if (Constraint.size() == 1) {
2662 // GCC RS6000 Constraint Letters
2663 switch (Constraint[0]) {
2664 case 'b': // R1-R31
2665 case 'r': // R0-R31
2666 if (VT == MVT::i64)
2667 return std::make_pair(0U, SPU::R64CRegisterClass);
2668 return std::make_pair(0U, SPU::R32CRegisterClass);
2669 case 'f':
2670 if (VT == MVT::f32)
2671 return std::make_pair(0U, SPU::R32FPRegisterClass);
2672 else if (VT == MVT::f64)
2673 return std::make_pair(0U, SPU::R64FPRegisterClass);
2674 break;
2675 case 'v':
2676 return std::make_pair(0U, SPU::GPRCRegisterClass);
2677 }
2678 }
2679
2680 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2681}
2682
2683void
2684SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002685 uint64_t Mask,
2686 uint64_t &KnownZero,
2687 uint64_t &KnownOne,
2688 const SelectionDAG &DAG,
2689 unsigned Depth ) const {
Scott Michel266bc8f2007-12-04 22:23:35 +00002690 KnownZero = 0;
2691 KnownOne = 0;
2692}
2693
2694// LowerAsmOperandForConstraint
2695void
2696SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2697 char ConstraintLetter,
2698 std::vector<SDOperand> &Ops,
2699 SelectionDAG &DAG) {
2700 // Default, for the time being, to the base class handler
2701 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2702}
2703
2704/// isLegalAddressImmediate - Return true if the integer value can be used
2705/// as the offset of the target addressing mode.
2706bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2707 // SPU's addresses are 256K:
2708 return (V > -(1 << 18) && V < (1 << 18) - 1);
2709}
2710
2711bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2712 return false;
2713}