blob: 6fe6e48bc84f283d4306bdc496f54b7d8fb4f463 [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) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001011 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1012 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1013 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001014 ArgOffset += StackSlotSize;
1015 }
1016
1017 ArgValues.push_back(ArgVal);
1018 }
1019
1020 // If the function takes variable number of arguments, make a frame index for
1021 // the start of the first vararg value... for expansion of llvm.va_start.
1022 if (isVarArg) {
1023 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1024 ArgOffset);
1025 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1026 // If this function is vararg, store any remaining integer argument regs to
1027 // their spots on the stack so that they may be loaded by deferencing the
1028 // result of va_next.
1029 SmallVector<SDOperand, 8> MemOps;
1030 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001031 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1032 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001033 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1034 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1035 MemOps.push_back(Store);
1036 // Increment the address by four for the next argument to store
1037 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1038 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1039 }
1040 if (!MemOps.empty())
1041 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1042 }
1043
1044 ArgValues.push_back(Root);
1045
1046 // Return the new list of results.
1047 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1048 Op.Val->value_end());
1049 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1050}
1051
1052/// isLSAAddress - Return the immediate to use if the specified
1053/// value is representable as a LSA address.
1054static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1055 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1056 if (!C) return 0;
1057
1058 int Addr = C->getValue();
1059 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1060 (Addr << 14 >> 14) != Addr)
1061 return 0; // Top 14 bits have to be sext of immediate.
1062
1063 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1064}
1065
1066static
1067SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001068LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001069 SDOperand Chain = Op.getOperand(0);
1070#if 0
1071 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1072 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1073#endif
1074 SDOperand Callee = Op.getOperand(4);
1075 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1076 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1077 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1078 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1079
1080 // Handy pointer type
1081 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1082
1083 // Accumulate how many bytes are to be pushed on the stack, including the
1084 // linkage area, and parameter passing area. According to the SPU ABI,
1085 // we minimally need space for [LR] and [SP]
1086 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1087
1088 // Set up a copy of the stack pointer for use loading and storing any
1089 // arguments that may not fit in the registers available for argument
1090 // passing.
1091 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1092
1093 // Figure out which arguments are going to go in registers, and which in
1094 // memory.
1095 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1096 unsigned ArgRegIdx = 0;
1097
1098 // Keep track of registers passing arguments
1099 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1100 // And the arguments passed on the stack
1101 SmallVector<SDOperand, 8> MemOpChains;
1102
1103 for (unsigned i = 0; i != NumOps; ++i) {
1104 SDOperand Arg = Op.getOperand(5+2*i);
1105
1106 // PtrOff will be used to store the current argument to the stack if a
1107 // register cannot be found for it.
1108 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1109 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1110
1111 switch (Arg.getValueType()) {
1112 default: assert(0 && "Unexpected ValueType for argument!");
1113 case MVT::i32:
1114 case MVT::i64:
1115 case MVT::i128:
1116 if (ArgRegIdx != NumArgRegs) {
1117 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1118 } else {
1119 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001120 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001121 }
1122 break;
1123 case MVT::f32:
1124 case MVT::f64:
1125 if (ArgRegIdx != NumArgRegs) {
1126 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1127 } else {
1128 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001129 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001130 }
1131 break;
1132 case MVT::v4f32:
1133 case MVT::v4i32:
1134 case MVT::v8i16:
1135 case MVT::v16i8:
1136 if (ArgRegIdx != NumArgRegs) {
1137 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1138 } else {
1139 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001140 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001141 }
1142 break;
1143 }
1144 }
1145
1146 // Update number of stack bytes actually used, insert a call sequence start
1147 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1148 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1149
1150 if (!MemOpChains.empty()) {
1151 // Adjust the stack pointer for the stack arguments.
1152 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1153 &MemOpChains[0], MemOpChains.size());
1154 }
1155
1156 // Build a sequence of copy-to-reg nodes chained together with token chain
1157 // and flag operands which copy the outgoing args into the appropriate regs.
1158 SDOperand InFlag;
1159 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1160 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1161 InFlag);
1162 InFlag = Chain.getValue(1);
1163 }
1164
1165 std::vector<MVT::ValueType> NodeTys;
1166 NodeTys.push_back(MVT::Other); // Returns a chain
1167 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1168
1169 SmallVector<SDOperand, 8> Ops;
1170 unsigned CallOpc = SPUISD::CALL;
1171
1172 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1173 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1174 // node so that legalize doesn't hack it.
1175 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1176 GlobalValue *GV = G->getGlobal();
1177 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001178 SDOperand Zero = DAG.getConstant(0, PtrVT);
1179 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001180
Scott Michel9de5d0d2008-01-11 02:53:15 +00001181 if (!ST->usingLargeMem()) {
1182 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1183 // style calls, otherwise, external symbols are BRASL calls. This assumes
1184 // that declared/defined symbols are in the same compilation unit and can
1185 // be reached through PC-relative jumps.
1186 //
1187 // NOTE:
1188 // This may be an unsafe assumption for JIT and really large compilation
1189 // units.
1190 if (GV->isDeclaration()) {
1191 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1192 } else {
1193 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1194 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001195 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001196 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1197 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001198 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001199 }
1200 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1201 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001202 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001203 // If this is an absolute destination address that appears to be a legal
1204 // local store address, use the munged value.
1205 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001206 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001207
1208 Ops.push_back(Chain);
1209 Ops.push_back(Callee);
1210
1211 // Add argument registers to the end of the list so that they are known live
1212 // into the call.
1213 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1214 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1215 RegsToPass[i].second.getValueType()));
1216
1217 if (InFlag.Val)
1218 Ops.push_back(InFlag);
1219 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1220 InFlag = Chain.getValue(1);
1221
Evan Chengebaaa912008-02-05 22:44:06 +00001222 Chain = DAG.getCALLSEQ_END(Chain,
1223 DAG.getConstant(NumStackBytes, PtrVT),
1224 DAG.getConstant(0, PtrVT),
1225 InFlag);
1226 if (Op.Val->getValueType(0) != MVT::Other)
1227 InFlag = Chain.getValue(1);
1228
Scott Michel266bc8f2007-12-04 22:23:35 +00001229 SDOperand ResultVals[3];
1230 unsigned NumResults = 0;
1231 NodeTys.clear();
1232
1233 // If the call has results, copy the values out of the ret val registers.
1234 switch (Op.Val->getValueType(0)) {
1235 default: assert(0 && "Unexpected ret value!");
1236 case MVT::Other: break;
1237 case MVT::i32:
1238 if (Op.Val->getValueType(1) == MVT::i32) {
1239 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1240 ResultVals[0] = Chain.getValue(0);
1241 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1242 Chain.getValue(2)).getValue(1);
1243 ResultVals[1] = Chain.getValue(0);
1244 NumResults = 2;
1245 NodeTys.push_back(MVT::i32);
1246 } else {
1247 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1248 ResultVals[0] = Chain.getValue(0);
1249 NumResults = 1;
1250 }
1251 NodeTys.push_back(MVT::i32);
1252 break;
1253 case MVT::i64:
1254 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1255 ResultVals[0] = Chain.getValue(0);
1256 NumResults = 1;
1257 NodeTys.push_back(MVT::i64);
1258 break;
1259 case MVT::f32:
1260 case MVT::f64:
1261 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1262 InFlag).getValue(1);
1263 ResultVals[0] = Chain.getValue(0);
1264 NumResults = 1;
1265 NodeTys.push_back(Op.Val->getValueType(0));
1266 break;
1267 case MVT::v2f64:
1268 case MVT::v4f32:
1269 case MVT::v4i32:
1270 case MVT::v8i16:
1271 case MVT::v16i8:
1272 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1273 InFlag).getValue(1);
1274 ResultVals[0] = Chain.getValue(0);
1275 NumResults = 1;
1276 NodeTys.push_back(Op.Val->getValueType(0));
1277 break;
1278 }
1279
Scott Michel266bc8f2007-12-04 22:23:35 +00001280 NodeTys.push_back(MVT::Other);
1281
1282 // If the function returns void, just return the chain.
1283 if (NumResults == 0)
1284 return Chain;
1285
1286 // Otherwise, merge everything together with a MERGE_VALUES node.
1287 ResultVals[NumResults++] = Chain;
1288 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1289 ResultVals, NumResults);
1290 return Res.getValue(Op.ResNo);
1291}
1292
1293static SDOperand
1294LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1295 SmallVector<CCValAssign, 16> RVLocs;
1296 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1297 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1298 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1299 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1300
1301 // If this is the first return lowered for this function, add the regs to the
1302 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001303 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001304 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001305 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001306 }
1307
1308 SDOperand Chain = Op.getOperand(0);
1309 SDOperand Flag;
1310
1311 // Copy the result values into the output registers.
1312 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1313 CCValAssign &VA = RVLocs[i];
1314 assert(VA.isRegLoc() && "Can only return in registers!");
1315 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1316 Flag = Chain.getValue(1);
1317 }
1318
1319 if (Flag.Val)
1320 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1321 else
1322 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1323}
1324
1325
1326//===----------------------------------------------------------------------===//
1327// Vector related lowering:
1328//===----------------------------------------------------------------------===//
1329
1330static ConstantSDNode *
1331getVecImm(SDNode *N) {
1332 SDOperand OpVal(0, 0);
1333
1334 // Check to see if this buildvec has a single non-undef value in its elements.
1335 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1336 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1337 if (OpVal.Val == 0)
1338 OpVal = N->getOperand(i);
1339 else if (OpVal != N->getOperand(i))
1340 return 0;
1341 }
1342
1343 if (OpVal.Val != 0) {
1344 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1345 return CN;
1346 }
1347 }
1348
1349 return 0; // All UNDEF: use implicit def.; not Constant node
1350}
1351
1352/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1353/// and the value fits into an unsigned 18-bit constant, and if so, return the
1354/// constant
1355SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1356 MVT::ValueType ValueType) {
1357 if (ConstantSDNode *CN = getVecImm(N)) {
1358 uint64_t Value = CN->getValue();
1359 if (Value <= 0x3ffff)
1360 return DAG.getConstant(Value, ValueType);
1361 }
1362
1363 return SDOperand();
1364}
1365
1366/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1367/// and the value fits into a signed 16-bit constant, and if so, return the
1368/// constant
1369SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1370 MVT::ValueType ValueType) {
1371 if (ConstantSDNode *CN = getVecImm(N)) {
1372 if (ValueType == MVT::i32) {
1373 int Value = (int) CN->getValue();
1374 int SExtValue = ((Value & 0xffff) << 16) >> 16;
1375
1376 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001377 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001378 } else if (ValueType == MVT::i16) {
1379 short Value = (short) CN->getValue();
1380 int SExtValue = ((int) Value << 16) >> 16;
1381
1382 if (Value == (short) SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001383 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001384 } else if (ValueType == MVT::i64) {
1385 int64_t Value = CN->getValue();
1386 int64_t SExtValue = ((Value & 0xffff) << (64 - 16)) >> (64 - 16);
1387
1388 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001389 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001390 }
1391 }
1392
1393 return SDOperand();
1394}
1395
1396/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1397/// and the value fits into a signed 10-bit constant, and if so, return the
1398/// constant
1399SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1400 MVT::ValueType ValueType) {
1401 if (ConstantSDNode *CN = getVecImm(N)) {
1402 int Value = (int) CN->getValue();
1403 if ((ValueType == MVT::i32 && isS10Constant(Value))
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001404 || (ValueType == MVT::i16 && isS10Constant((short) Value)))
Scott Michel266bc8f2007-12-04 22:23:35 +00001405 return DAG.getConstant(Value, ValueType);
1406 }
1407
1408 return SDOperand();
1409}
1410
1411/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1412/// and the value fits into a signed 8-bit constant, and if so, return the
1413/// constant.
1414///
1415/// @note: The incoming vector is v16i8 because that's the only way we can load
1416/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1417/// same value.
1418SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1419 MVT::ValueType ValueType) {
1420 if (ConstantSDNode *CN = getVecImm(N)) {
1421 int Value = (int) CN->getValue();
1422 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001423 && Value <= 0xffff /* truncated from uint64_t */
1424 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001425 return DAG.getConstant(Value & 0xff, ValueType);
1426 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001427 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001428 return DAG.getConstant(Value, ValueType);
1429 }
1430
1431 return SDOperand();
1432}
1433
1434/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1435/// and the value fits into a signed 16-bit constant, and if so, return the
1436/// constant
1437SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1438 MVT::ValueType ValueType) {
1439 if (ConstantSDNode *CN = getVecImm(N)) {
1440 uint64_t Value = CN->getValue();
1441 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001442 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1443 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001444 return DAG.getConstant(Value >> 16, ValueType);
1445 }
1446
1447 return SDOperand();
1448}
1449
1450/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1451SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1452 if (ConstantSDNode *CN = getVecImm(N)) {
1453 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1454 }
1455
1456 return SDOperand();
1457}
1458
1459/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1460SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1461 if (ConstantSDNode *CN = getVecImm(N)) {
1462 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1463 }
1464
1465 return SDOperand();
1466}
1467
1468// If this is a vector of constants or undefs, get the bits. A bit in
1469// UndefBits is set if the corresponding element of the vector is an
1470// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1471// zero. Return true if this is not an array of constants, false if it is.
1472//
1473static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1474 uint64_t UndefBits[2]) {
1475 // Start with zero'd results.
1476 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1477
1478 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1479 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1480 SDOperand OpVal = BV->getOperand(i);
1481
1482 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1483 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1484
1485 uint64_t EltBits = 0;
1486 if (OpVal.getOpcode() == ISD::UNDEF) {
1487 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1488 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1489 continue;
1490 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1491 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1492 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1493 const APFloat &apf = CN->getValueAPF();
1494 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001495 ? FloatToBits(apf.convertToFloat())
1496 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001497 } else {
1498 // Nonconstant element.
1499 return true;
1500 }
1501
1502 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1503 }
1504
1505 //printf("%llx %llx %llx %llx\n",
1506 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1507 return false;
1508}
1509
1510/// If this is a splat (repetition) of a value across the whole vector, return
1511/// the smallest size that splats it. For example, "0x01010101010101..." is a
1512/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1513/// SplatSize = 1 byte.
1514static bool isConstantSplat(const uint64_t Bits128[2],
1515 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001516 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001517 uint64_t &SplatBits, uint64_t &SplatUndef,
1518 int &SplatSize) {
1519 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1520 // the same as the lower 64-bits, ignoring undefs.
1521 uint64_t Bits64 = Bits128[0] | Bits128[1];
1522 uint64_t Undef64 = Undef128[0] & Undef128[1];
1523 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1524 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1525 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1526 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1527
1528 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1529 if (MinSplatBits < 64) {
1530
1531 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1532 // undefs.
1533 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001534 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001535
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001536 // If the top 16-bits are different than the lower 16-bits, ignoring
1537 // undefs, we have an i32 splat.
1538 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1539 if (MinSplatBits < 16) {
1540 // If the top 8-bits are different than the lower 8-bits, ignoring
1541 // undefs, we have an i16 splat.
1542 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1543 // Otherwise, we have an 8-bit splat.
1544 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1545 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1546 SplatSize = 1;
1547 return true;
1548 }
1549 } else {
1550 SplatBits = Bits16;
1551 SplatUndef = Undef16;
1552 SplatSize = 2;
1553 return true;
1554 }
1555 }
1556 } else {
1557 SplatBits = Bits32;
1558 SplatUndef = Undef32;
1559 SplatSize = 4;
1560 return true;
1561 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001562 }
1563 } else {
1564 SplatBits = Bits128[0];
1565 SplatUndef = Undef128[0];
1566 SplatSize = 8;
1567 return true;
1568 }
1569 }
1570
1571 return false; // Can't be a splat if two pieces don't match.
1572}
1573
1574// If this is a case we can't handle, return null and let the default
1575// expansion code take care of it. If we CAN select this case, and if it
1576// selects to a single instruction, return Op. Otherwise, if we can codegen
1577// this case more efficiently than a constant pool load, lower it to the
1578// sequence of ops that should be used.
1579static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1580 MVT::ValueType VT = Op.getValueType();
1581 // If this is a vector of constants or undefs, get the bits. A bit in
1582 // UndefBits is set if the corresponding element of the vector is an
1583 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1584 // zero.
1585 uint64_t VectorBits[2];
1586 uint64_t UndefBits[2];
1587 uint64_t SplatBits, SplatUndef;
1588 int SplatSize;
1589 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1590 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001591 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001592 SplatBits, SplatUndef, SplatSize))
1593 return SDOperand(); // Not a constant vector, not a splat.
1594
1595 switch (VT) {
1596 default:
1597 case MVT::v4f32: {
1598 uint32_t Value32 = SplatBits;
1599 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001600 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001601 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1602 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1603 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001604 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001605 break;
1606 }
1607 case MVT::v2f64: {
1608 uint64_t f64val = SplatBits;
1609 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001610 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001611 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1612 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1613 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001614 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001615 break;
1616 }
1617 case MVT::v16i8: {
1618 // 8-bit constants have to be expanded to 16-bits
1619 unsigned short Value16 = SplatBits | (SplatBits << 8);
1620 SDOperand Ops[8];
1621 for (int i = 0; i < 8; ++i)
1622 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1623 return DAG.getNode(ISD::BIT_CONVERT, VT,
1624 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1625 }
1626 case MVT::v8i16: {
1627 unsigned short Value16;
1628 if (SplatSize == 2)
1629 Value16 = (unsigned short) (SplatBits & 0xffff);
1630 else
1631 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1632 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1633 SDOperand Ops[8];
1634 for (int i = 0; i < 8; ++i) Ops[i] = T;
1635 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1636 }
1637 case MVT::v4i32: {
1638 unsigned int Value = SplatBits;
1639 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1640 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1641 }
1642 case MVT::v2i64: {
1643 uint64_t val = SplatBits;
1644 uint32_t upper = uint32_t(val >> 32);
1645 uint32_t lower = uint32_t(val);
1646
1647 if (val != 0) {
1648 SDOperand LO32;
1649 SDOperand HI32;
1650 SmallVector<SDOperand, 16> ShufBytes;
1651 SDOperand Result;
1652 bool upper_special, lower_special;
1653
1654 // NOTE: This code creates common-case shuffle masks that can be easily
1655 // detected as common expressions. It is not attempting to create highly
1656 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1657
1658 // Detect if the upper or lower half is a special shuffle mask pattern:
1659 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1660 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1661
1662 // Create lower vector if not a special pattern
1663 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001664 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1665 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1666 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1667 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001668 }
1669
1670 // Create upper vector if not a special pattern
1671 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001672 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1673 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1674 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1675 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001676 }
1677
1678 // If either upper or lower are special, then the two input operands are
1679 // the same (basically, one of them is a "don't care")
1680 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001681 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001682 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001683 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001684 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001685 // Unhappy situation... both upper and lower are special, so punt with
1686 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001687 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001688 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001689 Zero, Zero);
1690 }
1691
1692 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001693 for (int j = 0; j < 4; ++j) {
1694 SDOperand V;
1695 bool process_upper, process_lower;
1696 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001697
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001698 process_upper = (upper_special && (i & 1) == 0);
1699 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001700
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001701 if (process_upper || process_lower) {
1702 if ((process_upper && upper == 0)
1703 || (process_lower && lower == 0))
1704 val = 0x80;
1705 else if ((process_upper && upper == 0xffffffff)
1706 || (process_lower && lower == 0xffffffff))
1707 val = 0xc0;
1708 else if ((process_upper && upper == 0x80000000)
1709 || (process_lower && lower == 0x80000000))
1710 val = (j == 0 ? 0xe0 : 0x80);
1711 } else
1712 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001713
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001714 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1715 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001716 }
1717
1718 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001719 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1720 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001721 } else {
1722 // For zero, this can be lowered efficiently via v4i32 BUILD_VECTOR
1723 SDOperand Zero = DAG.getConstant(0, MVT::i32);
1724 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001725 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1726 Zero, Zero, Zero, Zero));
Scott Michel266bc8f2007-12-04 22:23:35 +00001727 }
1728 }
1729 }
1730
1731 return SDOperand();
1732}
1733
1734/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1735/// which the Cell can operate. The code inspects V3 to ascertain whether the
1736/// permutation vector, V3, is monotonically increasing with one "exception"
1737/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1738/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1739/// In either case, the net result is going to eventually invoke SHUFB to
1740/// permute/shuffle the bytes from V1 and V2.
1741/// \note
1742/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1743/// control word for byte/halfword/word insertion. This takes care of a single
1744/// element move from V2 into V1.
1745/// \note
1746/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1747static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1748 SDOperand V1 = Op.getOperand(0);
1749 SDOperand V2 = Op.getOperand(1);
1750 SDOperand PermMask = Op.getOperand(2);
1751
1752 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1753
1754 // If we have a single element being moved from V1 to V2, this can be handled
1755 // using the C*[DX] compute mask instructions, but the vector elements have
1756 // to be monotonically increasing with one exception element.
1757 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1758 unsigned EltsFromV2 = 0;
1759 unsigned V2Elt = 0;
1760 unsigned V2EltIdx0 = 0;
1761 unsigned CurrElt = 0;
1762 bool monotonic = true;
1763 if (EltVT == MVT::i8)
1764 V2EltIdx0 = 16;
1765 else if (EltVT == MVT::i16)
1766 V2EltIdx0 = 8;
1767 else if (EltVT == MVT::i32)
1768 V2EltIdx0 = 4;
1769 else
1770 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1771
1772 for (unsigned i = 0, e = PermMask.getNumOperands();
1773 EltsFromV2 <= 1 && monotonic && i != e;
1774 ++i) {
1775 unsigned SrcElt;
1776 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1777 SrcElt = 0;
1778 else
1779 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1780
1781 if (SrcElt >= V2EltIdx0) {
1782 ++EltsFromV2;
1783 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1784 } else if (CurrElt != SrcElt) {
1785 monotonic = false;
1786 }
1787
1788 ++CurrElt;
1789 }
1790
1791 if (EltsFromV2 == 1 && monotonic) {
1792 // Compute mask and shuffle
1793 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001794 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1795 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001796 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1797 // Initialize temporary register to 0
1798 SDOperand InitTempReg =
1799 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1800 // Copy register's contents as index in INSERT_MASK:
1801 SDOperand ShufMaskOp =
1802 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001803 DAG.getTargetConstant(V2Elt, MVT::i32),
1804 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001805 // Use shuffle mask in SHUFB synthetic instruction:
1806 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1807 } else {
1808 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1809 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1810
1811 SmallVector<SDOperand, 16> ResultMask;
1812 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1813 unsigned SrcElt;
1814 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001815 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001816 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001817 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001818
1819 for (unsigned j = 0; j != BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001820 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1821 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001822 }
1823 }
1824
1825 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001826 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001827 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1828 }
1829}
1830
1831static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001832 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001833
1834 if (Op0.Val->getOpcode() == ISD::Constant) {
1835 // For a constant, build the appropriate constant vector, which will
1836 // eventually simplify to a vector register load.
1837
1838 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1839 SmallVector<SDOperand, 16> ConstVecValues;
1840 MVT::ValueType VT;
1841 size_t n_copies;
1842
1843 // Create a constant vector:
1844 switch (Op.getValueType()) {
1845 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001846 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001847 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1848 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1849 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1850 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1851 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1852 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1853 }
1854
1855 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1856 for (size_t j = 0; j < n_copies; ++j)
1857 ConstVecValues.push_back(CValue);
1858
1859 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001860 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001861 } else {
1862 // Otherwise, copy the value from one register to another:
1863 switch (Op0.getValueType()) {
1864 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1865 case MVT::i8:
1866 case MVT::i16:
1867 case MVT::i32:
1868 case MVT::i64:
1869 case MVT::f32:
1870 case MVT::f64:
1871 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1872 }
1873 }
1874
1875 return SDOperand();
1876}
1877
1878static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1879 switch (Op.getValueType()) {
1880 case MVT::v4i32: {
1881 SDOperand rA = Op.getOperand(0);
1882 SDOperand rB = Op.getOperand(1);
1883 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1884 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1885 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1886 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1887
1888 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1889 break;
1890 }
1891
1892 // Multiply two v8i16 vectors (pipeline friendly version):
1893 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1894 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1895 // c) Use SELB to select upper and lower halves from the intermediate results
1896 //
1897 // NOTE: We really want to move the FSMBI to earlier to actually get the
1898 // dual-issue. This code does manage to do this, even if it's a little on
1899 // the wacky side
1900 case MVT::v8i16: {
1901 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001902 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001903 SDOperand Chain = Op.getOperand(0);
1904 SDOperand rA = Op.getOperand(0);
1905 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001906 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1907 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001908
1909 SDOperand FSMBOp =
1910 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001911 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1912 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001913
1914 SDOperand HHProd =
1915 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001916 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001917
1918 SDOperand HHProd_v4i32 =
1919 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001920 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001921
1922 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001923 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1924 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1925 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1926 HHProd_v4i32,
1927 DAG.getConstant(16, MVT::i16))),
1928 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001929 }
1930
1931 // This M00sE is N@stI! (apologies to Monty Python)
1932 //
1933 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1934 // is to break it all apart, sign extend, and reassemble the various
1935 // intermediate products.
1936 case MVT::v16i8: {
1937 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001938 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001939 SDOperand Chain = Op.getOperand(0);
1940 SDOperand rA = Op.getOperand(0);
1941 SDOperand rB = Op.getOperand(1);
1942 SDOperand c8 = DAG.getConstant(8, MVT::i8);
1943 SDOperand c16 = DAG.getConstant(16, MVT::i8);
1944
Chris Lattner84bc5422007-12-31 04:13:23 +00001945 unsigned FSMBreg_2222 = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1946 unsigned LoProd_reg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1947 unsigned HiProd_reg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001948
1949 SDOperand LLProd =
1950 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001951 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1952 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001953
1954 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1955
1956 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1957
1958 SDOperand LHProd =
1959 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001960 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001961
1962 SDOperand FSMBdef_2222 =
1963 DAG.getCopyToReg(Chain, FSMBreg_2222,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001964 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1965 DAG.getConstant(0x2222, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001966
1967 SDOperand FSMBuse_2222 =
1968 DAG.getCopyFromReg(FSMBdef_2222, FSMBreg_2222, MVT::v4i32);
1969
1970 SDOperand LoProd_1 =
1971 DAG.getCopyToReg(Chain, LoProd_reg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001972 DAG.getNode(SPUISD::SELB, MVT::v8i16, LLProd, LHProd,
1973 FSMBuse_2222));
Scott Michel266bc8f2007-12-04 22:23:35 +00001974
1975 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1976
1977 SDOperand LoProd =
1978 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001979 DAG.getCopyFromReg(LoProd_1, LoProd_reg, MVT::v4i32),
1980 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1981 LoProdMask, LoProdMask,
1982 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001983
1984 SDOperand rAH =
1985 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001986 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001987
1988 SDOperand rBH =
1989 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001990 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001991
1992 SDOperand HLProd =
1993 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001994 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1995 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001996
1997 SDOperand HHProd_1 =
1998 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001999 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2000 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
2001 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2002 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002003
2004 SDOperand HHProd =
2005 DAG.getCopyToReg(Chain, HiProd_reg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002006 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2007 HLProd,
2008 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2009 FSMBuse_2222));
Scott Michel266bc8f2007-12-04 22:23:35 +00002010
2011 SDOperand HiProd =
2012 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002013 DAG.getCopyFromReg(HHProd, HiProd_reg, MVT::v4i32), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002014
2015 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002016 DAG.getNode(ISD::OR, MVT::v4i32,
2017 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002018 }
2019
2020 default:
2021 cerr << "CellSPU: Unknown vector multiplication, got "
2022 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002023 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002024 abort();
2025 /*NOTREACHED*/
2026 }
2027
2028 return SDOperand();
2029}
2030
2031static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2032 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002033 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002034
2035 SDOperand A = Op.getOperand(0);
2036 SDOperand B = Op.getOperand(1);
2037 unsigned VT = Op.getValueType();
2038
2039 unsigned VRegBR, VRegC;
2040
2041 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002042 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2043 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002044 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002045 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2046 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002047 }
2048 // TODO: make sure we're feeding FPInterp the right arguments
2049 // Right now: fi B, frest(B)
2050
2051 // Computes BRcpl =
2052 // (Floating Interpolate (FP Reciprocal Estimate B))
2053 SDOperand BRcpl =
2054 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002055 DAG.getNode(SPUISD::FPInterp, VT, B,
2056 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002057
2058 // Computes A * BRcpl and stores in a temporary register
2059 SDOperand AxBRcpl =
2060 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002061 DAG.getNode(ISD::FMUL, VT, A,
2062 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002063 // What's the Chain variable do? It's magic!
2064 // TODO: set Chain = Op(0).getEntryNode()
2065
2066 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002067 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2068 DAG.getNode(ISD::FMUL, VT,
2069 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2070 DAG.getNode(ISD::FSUB, VT, A,
2071 DAG.getNode(ISD::FMUL, VT, B,
2072 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002073}
2074
Scott Michel266bc8f2007-12-04 22:23:35 +00002075static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2076 unsigned VT = Op.getValueType();
2077 SDOperand N = Op.getOperand(0);
2078 SDOperand Elt = Op.getOperand(1);
2079 SDOperand ShufMask[16];
2080 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2081
2082 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2083
2084 int EltNo = (int) C->getValue();
2085
2086 // sanity checks:
2087 if (VT == MVT::i8 && EltNo >= 16)
2088 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2089 else if (VT == MVT::i16 && EltNo >= 8)
2090 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2091 else if (VT == MVT::i32 && EltNo >= 4)
2092 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2093 else if (VT == MVT::i64 && EltNo >= 2)
2094 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2095
2096 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2097 // i32 and i64: Element 0 is the preferred slot
2098 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2099 }
2100
2101 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002102 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002103 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2104
2105 switch (VT) {
2106 case MVT::i8: {
2107 prefslot_begin = prefslot_end = 3;
2108 break;
2109 }
2110 case MVT::i16: {
2111 prefslot_begin = 2; prefslot_end = 3;
2112 break;
2113 }
2114 case MVT::i32: {
2115 prefslot_begin = 0; prefslot_end = 3;
2116 break;
2117 }
2118 case MVT::i64: {
2119 prefslot_begin = 0; prefslot_end = 7;
2120 break;
2121 }
2122 }
2123
Scott Michel0e5665b2007-12-19 21:17:42 +00002124 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002125 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002126
Scott Michel266bc8f2007-12-04 22:23:35 +00002127 for (int i = 0; i < 16; ++i) {
2128 // zero fill uppper part of preferred slot, don't care about the
2129 // other slots:
2130 unsigned int mask_val;
2131
2132 if (i <= prefslot_end) {
2133 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002134 ((i < prefslot_begin)
2135 ? 0x80
2136 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002137
Scott Michel0e5665b2007-12-19 21:17:42 +00002138 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002139 } else
2140 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2141 }
2142
2143 SDOperand ShufMaskVec =
2144 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002145 &ShufMask[0],
2146 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002147
2148 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002149 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2150 N, N, ShufMaskVec));
2151
Scott Michel266bc8f2007-12-04 22:23:35 +00002152}
2153
2154static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2155 SDOperand VecOp = Op.getOperand(0);
2156 SDOperand ValOp = Op.getOperand(1);
2157 SDOperand IdxOp = Op.getOperand(2);
2158 MVT::ValueType VT = Op.getValueType();
2159
2160 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2161 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2162
2163 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2164 // Use $2 because it's always 16-byte aligned and it's available:
2165 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2166
2167 SDOperand result =
2168 DAG.getNode(SPUISD::SHUFB, VT,
2169 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2170 VecOp,
2171 DAG.getNode(SPUISD::INSERT_MASK, VT,
2172 DAG.getNode(ISD::ADD, PtrVT,
2173 PtrBase,
2174 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002175 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002176
2177 return result;
2178}
2179
2180static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc) {
2181 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2182
2183 assert(Op.getValueType() == MVT::i8);
2184 switch (Opc) {
2185 default:
2186 assert(0 && "Unhandled i8 math operator");
2187 /*NOTREACHED*/
2188 break;
2189 case ISD::SUB: {
2190 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2191 // the result:
2192 SDOperand N1 = Op.getOperand(1);
2193 N0 = (N0.getOpcode() != ISD::Constant
2194 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2195 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2196 N1 = (N1.getOpcode() != ISD::Constant
2197 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2198 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2199 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2200 DAG.getNode(Opc, MVT::i16, N0, N1));
2201 }
2202 case ISD::ROTR:
2203 case ISD::ROTL: {
2204 SDOperand N1 = Op.getOperand(1);
2205 unsigned N1Opc;
2206 N0 = (N0.getOpcode() != ISD::Constant
2207 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2208 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2209 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2210 N1 = (N1.getOpcode() != ISD::Constant
2211 ? DAG.getNode(N1Opc, MVT::i16, N1)
2212 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2213 SDOperand ExpandArg =
2214 DAG.getNode(ISD::OR, MVT::i16, N0,
2215 DAG.getNode(ISD::SHL, MVT::i16,
2216 N0, DAG.getConstant(8, MVT::i16)));
2217 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2218 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2219 }
2220 case ISD::SRL:
2221 case ISD::SHL: {
2222 SDOperand N1 = Op.getOperand(1);
2223 unsigned N1Opc;
2224 N0 = (N0.getOpcode() != ISD::Constant
2225 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2226 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2227 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2228 N1 = (N1.getOpcode() != ISD::Constant
2229 ? DAG.getNode(N1Opc, MVT::i16, N1)
2230 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2231 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2232 DAG.getNode(Opc, MVT::i16, N0, N1));
2233 }
2234 case ISD::SRA: {
2235 SDOperand N1 = Op.getOperand(1);
2236 unsigned N1Opc;
2237 N0 = (N0.getOpcode() != ISD::Constant
2238 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2239 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2240 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2241 N1 = (N1.getOpcode() != ISD::Constant
2242 ? DAG.getNode(N1Opc, MVT::i16, N1)
2243 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2244 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2245 DAG.getNode(Opc, MVT::i16, N0, N1));
2246 }
2247 case ISD::MUL: {
2248 SDOperand N1 = Op.getOperand(1);
2249 unsigned N1Opc;
2250 N0 = (N0.getOpcode() != ISD::Constant
2251 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2252 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2253 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2254 N1 = (N1.getOpcode() != ISD::Constant
2255 ? DAG.getNode(N1Opc, MVT::i16, N1)
2256 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2257 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2258 DAG.getNode(Opc, MVT::i16, N0, N1));
2259 break;
2260 }
2261 }
2262
2263 return SDOperand();
2264}
2265
2266//! Lower byte immediate operations for v16i8 vectors:
2267static SDOperand
2268LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2269 SDOperand ConstVec;
2270 SDOperand Arg;
2271 MVT::ValueType VT = Op.getValueType();
2272
2273 ConstVec = Op.getOperand(0);
2274 Arg = Op.getOperand(1);
2275 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2276 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2277 ConstVec = ConstVec.getOperand(0);
2278 } else {
2279 ConstVec = Op.getOperand(1);
2280 Arg = Op.getOperand(0);
2281 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002282 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002283 }
2284 }
2285 }
2286
2287 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2288 uint64_t VectorBits[2];
2289 uint64_t UndefBits[2];
2290 uint64_t SplatBits, SplatUndef;
2291 int SplatSize;
2292
2293 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002294 && isConstantSplat(VectorBits, UndefBits,
2295 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2296 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002297 SDOperand tcVec[16];
2298 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2299 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2300
2301 // Turn the BUILD_VECTOR into a set of target constants:
2302 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002303 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002304
2305 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002306 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002307 }
2308 }
2309
2310 return SDOperand();
2311}
2312
2313//! Lower i32 multiplication
2314static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2315 unsigned Opc) {
2316 switch (VT) {
2317 default:
2318 cerr << "CellSPU: Unknown LowerMUL value type, got "
2319 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002320 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002321 abort();
2322 /*NOTREACHED*/
2323
2324 case MVT::i32: {
2325 SDOperand rA = Op.getOperand(0);
2326 SDOperand rB = Op.getOperand(1);
2327
2328 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002329 DAG.getNode(ISD::ADD, MVT::i32,
2330 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2331 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2332 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002333 }
2334 }
2335
2336 return SDOperand();
2337}
2338
2339//! Custom lowering for CTPOP (count population)
2340/*!
2341 Custom lowering code that counts the number ones in the input
2342 operand. SPU has such an instruction, but it counts the number of
2343 ones per byte, which then have to be accumulated.
2344*/
2345static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2346 unsigned VT = Op.getValueType();
2347 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2348
2349 switch (VT) {
2350 case MVT::i8: {
2351 SDOperand N = Op.getOperand(0);
2352 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2353
2354 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2355 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2356
2357 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2358 }
2359
2360 case MVT::i16: {
2361 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002362 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002363
Chris Lattner84bc5422007-12-31 04:13:23 +00002364 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002365
2366 SDOperand N = Op.getOperand(0);
2367 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2368 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2369 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2370
2371 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2372 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2373
2374 // CNTB_result becomes the chain to which all of the virtual registers
2375 // CNTB_reg, SUM1_reg become associated:
2376 SDOperand CNTB_result =
2377 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002378
Scott Michel266bc8f2007-12-04 22:23:35 +00002379 SDOperand CNTB_rescopy =
2380 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2381
2382 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2383
2384 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002385 DAG.getNode(ISD::ADD, MVT::i16,
2386 DAG.getNode(ISD::SRL, MVT::i16,
2387 Tmp1, Shift1),
2388 Tmp1),
2389 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002390 }
2391
2392 case MVT::i32: {
2393 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002394 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002395
Chris Lattner84bc5422007-12-31 04:13:23 +00002396 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2397 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002398
2399 SDOperand N = Op.getOperand(0);
2400 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2401 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2402 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2403 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2404
2405 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2406 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2407
2408 // CNTB_result becomes the chain to which all of the virtual registers
2409 // CNTB_reg, SUM1_reg become associated:
2410 SDOperand CNTB_result =
2411 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002412
Scott Michel266bc8f2007-12-04 22:23:35 +00002413 SDOperand CNTB_rescopy =
2414 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2415
2416 SDOperand Comp1 =
2417 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002418 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002419
2420 SDOperand Sum1 =
2421 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002422 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002423
2424 SDOperand Sum1_rescopy =
2425 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2426
2427 SDOperand Comp2 =
2428 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002429 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2430 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002431 SDOperand Sum2 =
2432 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002433 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002434
2435 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2436 }
2437
2438 case MVT::i64:
2439 break;
2440 }
2441
2442 return SDOperand();
2443}
2444
2445/// LowerOperation - Provide custom lowering hooks for some operations.
2446///
2447SDOperand
2448SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2449{
2450 switch (Op.getOpcode()) {
2451 default: {
2452 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
2453 cerr << "Op.getOpcode() = " << Op.getOpcode() << "\n";
2454 cerr << "*Op.Val:\n";
2455 Op.Val->dump();
2456 abort();
2457 }
2458 case ISD::LOAD:
2459 case ISD::SEXTLOAD:
2460 case ISD::ZEXTLOAD:
2461 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2462 case ISD::STORE:
2463 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2464 case ISD::ConstantPool:
2465 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2466 case ISD::GlobalAddress:
2467 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2468 case ISD::JumpTable:
2469 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2470 case ISD::Constant:
2471 return LowerConstant(Op, DAG);
2472 case ISD::ConstantFP:
2473 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002474 case ISD::BRCOND:
2475 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002476 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002477 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002478 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002479 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002480 case ISD::RET:
2481 return LowerRET(Op, DAG, getTargetMachine());
2482
2483 // i8 math ops:
2484 case ISD::SUB:
2485 case ISD::ROTR:
2486 case ISD::ROTL:
2487 case ISD::SRL:
2488 case ISD::SHL:
2489 case ISD::SRA:
2490 return LowerI8Math(Op, DAG, Op.getOpcode());
2491
2492 // Vector-related lowering.
2493 case ISD::BUILD_VECTOR:
2494 return LowerBUILD_VECTOR(Op, DAG);
2495 case ISD::SCALAR_TO_VECTOR:
2496 return LowerSCALAR_TO_VECTOR(Op, DAG);
2497 case ISD::VECTOR_SHUFFLE:
2498 return LowerVECTOR_SHUFFLE(Op, DAG);
2499 case ISD::EXTRACT_VECTOR_ELT:
2500 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2501 case ISD::INSERT_VECTOR_ELT:
2502 return LowerINSERT_VECTOR_ELT(Op, DAG);
2503
2504 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2505 case ISD::AND:
2506 case ISD::OR:
2507 case ISD::XOR:
2508 return LowerByteImmed(Op, DAG);
2509
2510 // Vector and i8 multiply:
2511 case ISD::MUL:
2512 if (MVT::isVector(Op.getValueType()))
2513 return LowerVectorMUL(Op, DAG);
2514 else if (Op.getValueType() == MVT::i8)
2515 return LowerI8Math(Op, DAG, Op.getOpcode());
2516 else
2517 return LowerMUL(Op, DAG, Op.getValueType(), Op.getOpcode());
2518
2519 case ISD::FDIV:
2520 if (Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::v4f32)
2521 return LowerFDIVf32(Op, DAG);
2522// else if (Op.getValueType() == MVT::f64)
2523// return LowerFDIVf64(Op, DAG);
2524 else
2525 assert(0 && "Calling FDIV on unsupported MVT");
2526
2527 case ISD::CTPOP:
2528 return LowerCTPOP(Op, DAG);
2529 }
2530
2531 return SDOperand();
2532}
2533
2534//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002535// Target Optimization Hooks
2536//===----------------------------------------------------------------------===//
2537
2538SDOperand
2539SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2540{
2541#if 0
2542 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002543#endif
2544 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002545 SelectionDAG &DAG = DCI.DAG;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002546 SDOperand N0 = N->getOperand(0); // everything has at least one operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002547
2548 switch (N->getOpcode()) {
2549 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002550 case SPUISD::IndirectAddr: {
2551 if (!ST->usingLargeMem() && N0.getOpcode() == SPUISD::AFormAddr) {
2552 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2553 if (CN->getValue() == 0) {
2554 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2555 // (SPUaform <addr>, 0)
2556
2557 DEBUG(cerr << "Replace: ");
2558 DEBUG(N->dump(&DAG));
2559 DEBUG(cerr << "\nWith: ");
2560 DEBUG(N0.Val->dump(&DAG));
2561 DEBUG(cerr << "\n");
2562
2563 return N0;
2564 }
2565 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002566 }
Scott Michel053c1da2008-01-29 02:16:57 +00002567 case ISD::ADD: {
2568 SDOperand Op0 = N->getOperand(0);
2569 SDOperand Op1 = N->getOperand(1);
2570
2571 if ((Op1.getOpcode() == ISD::Constant
2572 || Op1.getOpcode() == ISD::TargetConstant)
2573 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2574 SDOperand Op01 = Op0.getOperand(1);
2575 if (Op01.getOpcode() == ISD::Constant
2576 || Op01.getOpcode() == ISD::TargetConstant) {
2577 // (add <const>, (SPUindirect <arg>, <const>)) ->
2578 // (SPUindirect <arg>, <const + const>)
2579 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2580 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2581 SDOperand combinedConst =
2582 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2583 Op0.getValueType());
2584
2585 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2586 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2587 DEBUG(cerr << "With: (SPUindirect <arg>, "
2588 << CN0->getValue() + CN1->getValue() << ")\n");
2589 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2590 Op0.getOperand(0), combinedConst);
2591 }
2592 } else if ((Op0.getOpcode() == ISD::Constant
2593 || Op0.getOpcode() == ISD::TargetConstant)
2594 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2595 SDOperand Op11 = Op1.getOperand(1);
2596 if (Op11.getOpcode() == ISD::Constant
2597 || Op11.getOpcode() == ISD::TargetConstant) {
2598 // (add (SPUindirect <arg>, <const>), <const>) ->
2599 // (SPUindirect <arg>, <const + const>)
2600 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2601 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2602 SDOperand combinedConst =
2603 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2604 Op0.getValueType());
2605
2606 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2607 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2608 DEBUG(cerr << "With: (SPUindirect <arg>, "
2609 << CN0->getValue() + CN1->getValue() << ")\n");
2610
2611 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2612 Op1.getOperand(0), combinedConst);
2613 }
2614 }
2615 }
2616 }
Scott Michel58c58182008-01-17 20:38:41 +00002617 // Otherwise, return unchanged.
Scott Michel266bc8f2007-12-04 22:23:35 +00002618 return SDOperand();
2619}
2620
2621//===----------------------------------------------------------------------===//
2622// Inline Assembly Support
2623//===----------------------------------------------------------------------===//
2624
2625/// getConstraintType - Given a constraint letter, return the type of
2626/// constraint it is for this target.
2627SPUTargetLowering::ConstraintType
2628SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2629 if (ConstraintLetter.size() == 1) {
2630 switch (ConstraintLetter[0]) {
2631 default: break;
2632 case 'b':
2633 case 'r':
2634 case 'f':
2635 case 'v':
2636 case 'y':
2637 return C_RegisterClass;
2638 }
2639 }
2640 return TargetLowering::getConstraintType(ConstraintLetter);
2641}
2642
2643std::pair<unsigned, const TargetRegisterClass*>
2644SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2645 MVT::ValueType VT) const
2646{
2647 if (Constraint.size() == 1) {
2648 // GCC RS6000 Constraint Letters
2649 switch (Constraint[0]) {
2650 case 'b': // R1-R31
2651 case 'r': // R0-R31
2652 if (VT == MVT::i64)
2653 return std::make_pair(0U, SPU::R64CRegisterClass);
2654 return std::make_pair(0U, SPU::R32CRegisterClass);
2655 case 'f':
2656 if (VT == MVT::f32)
2657 return std::make_pair(0U, SPU::R32FPRegisterClass);
2658 else if (VT == MVT::f64)
2659 return std::make_pair(0U, SPU::R64FPRegisterClass);
2660 break;
2661 case 'v':
2662 return std::make_pair(0U, SPU::GPRCRegisterClass);
2663 }
2664 }
2665
2666 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2667}
2668
2669void
2670SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002671 APInt Mask,
2672 APInt &KnownZero,
2673 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002674 const SelectionDAG &DAG,
2675 unsigned Depth ) const {
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002676 KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002677}
2678
2679// LowerAsmOperandForConstraint
2680void
2681SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2682 char ConstraintLetter,
2683 std::vector<SDOperand> &Ops,
2684 SelectionDAG &DAG) {
2685 // Default, for the time being, to the base class handler
2686 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2687}
2688
2689/// isLegalAddressImmediate - Return true if the integer value can be used
2690/// as the offset of the target addressing mode.
2691bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2692 // SPU's addresses are 256K:
2693 return (V > -(1 << 18) && V < (1 << 18) - 1);
2694}
2695
2696bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2697 return false;
2698}