blob: 29226092688fc83db30bc35f4fe92047e2c5c2f3 [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:
Scott Michel504c3692007-12-17 22:32:34 +0000125 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
126 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
127 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
128 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
129 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
130 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000131 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
132
133 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000134 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000135 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
136 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000137 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
138 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
139 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
140 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000142
143 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
144 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
145 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000146 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
147 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
148 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
149 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
151
Scott Michel266bc8f2007-12-04 22:23:35 +0000152 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
153 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
154 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
155
156 // SPU constant load actions are custom lowered:
157 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000158 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000159 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
160
161 // SPU's loads and stores have to be custom lowered:
162 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
163 ++sctype) {
164 setOperationAction(ISD::LOAD, sctype, Custom);
165 setOperationAction(ISD::STORE, sctype, Custom);
166 }
167
Scott Michel58c58182008-01-17 20:38:41 +0000168 // Custom lower BRCOND for i1, i8 to "promote" the result to
169 // i32 and i16, respectively.
170 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000171
172 // Expand the jumptable branches
173 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
174 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
175 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
176
177 // SPU has no intrinsics for these particular operations:
178 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
179 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
180 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000181 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
182
Scott Michel266bc8f2007-12-04 22:23:35 +0000183 // PowerPC has no SREM/UREM instructions
184 setOperationAction(ISD::SREM, MVT::i32, Expand);
185 setOperationAction(ISD::UREM, MVT::i32, Expand);
186 setOperationAction(ISD::SREM, MVT::i64, Expand);
187 setOperationAction(ISD::UREM, MVT::i64, Expand);
188
189 // We don't support sin/cos/sqrt/fmod
190 setOperationAction(ISD::FSIN , MVT::f64, Expand);
191 setOperationAction(ISD::FCOS , MVT::f64, Expand);
192 setOperationAction(ISD::FREM , MVT::f64, Expand);
193 setOperationAction(ISD::FSIN , MVT::f32, Expand);
194 setOperationAction(ISD::FCOS , MVT::f32, Expand);
195 setOperationAction(ISD::FREM , MVT::f32, Expand);
196
197 // If we're enabling GP optimizations, use hardware square root
198 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
199 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
200
201 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
202 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
203
204 // SPU can do rotate right and left, so legalize it... but customize for i8
205 // because instructions don't exist.
206 setOperationAction(ISD::ROTR, MVT::i32, Legal);
207 setOperationAction(ISD::ROTR, MVT::i16, Legal);
208 setOperationAction(ISD::ROTR, MVT::i8, Custom);
209 setOperationAction(ISD::ROTL, MVT::i32, Legal);
210 setOperationAction(ISD::ROTL, MVT::i16, Legal);
211 setOperationAction(ISD::ROTL, MVT::i8, Custom);
212 // SPU has no native version of shift left/right for i8
213 setOperationAction(ISD::SHL, MVT::i8, Custom);
214 setOperationAction(ISD::SRL, MVT::i8, Custom);
215 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000216 // And SPU needs custom lowering for shift left/right for i64
217 setOperationAction(ISD::SHL, MVT::i64, Custom);
218 setOperationAction(ISD::SRL, MVT::i64, Custom);
219 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000220
221 // Custom lower i32 multiplications
222 setOperationAction(ISD::MUL, MVT::i32, Custom);
223
224 // Need to custom handle (some) common i8 math ops
225 setOperationAction(ISD::SUB, MVT::i8, Custom);
226 setOperationAction(ISD::MUL, MVT::i8, Custom);
227
228 // SPU does not have BSWAP. It does have i32 support CTLZ.
229 // CTPOP has to be custom lowered.
230 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
231 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
232
233 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
234 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
235 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
236 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
237
238 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
239 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
240
241 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
242
Scott Michel405fba12008-03-10 23:49:09 +0000243 // SPU has a version of select that implements (a&~c)|(b|c), just like
244 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000245 setOperationAction(ISD::SELECT, MVT::i1, Promote);
246 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000247 setOperationAction(ISD::SELECT, MVT::i16, Legal);
248 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000249 setOperationAction(ISD::SELECT, MVT::i64, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000250
Scott Michel78c47fa2008-03-10 16:58:52 +0000251 setOperationAction(ISD::SETCC, MVT::i1, Promote);
252 setOperationAction(ISD::SETCC, MVT::i8, Legal);
253 setOperationAction(ISD::SETCC, MVT::i16, Legal);
254 setOperationAction(ISD::SETCC, MVT::i32, Legal);
255 setOperationAction(ISD::SETCC, MVT::i64, Expand);
Scott Michelad2715e2008-03-05 23:02:02 +0000256
Scott Michela59d4692008-02-23 18:41:37 +0000257 // Zero extension and sign extension for i64 have to be
258 // custom legalized
259 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
260 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
261 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000262
263 // SPU has a legal FP -> signed INT instruction
264 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
265 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
266 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
267 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
268
269 // FDIV on SPU requires custom lowering
270 setOperationAction(ISD::FDIV, MVT::f32, Custom);
271 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
272
273 // SPU has [U|S]INT_TO_FP
274 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
275 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
276 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
277 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
278 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
279 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
280 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
281 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
282
Scott Michel86c041f2007-12-20 00:44:13 +0000283 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
284 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
285 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
286 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000287
288 // We cannot sextinreg(i1). Expand to shifts.
289 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
290
291 // Support label based line numbers.
292 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
293 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
294
295 // We want to legalize GlobalAddress and ConstantPool nodes into the
296 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000297 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
298 ++sctype) {
299 setOperationAction(ISD::GlobalAddress, sctype, Custom);
300 setOperationAction(ISD::ConstantPool, sctype, Custom);
301 setOperationAction(ISD::JumpTable, sctype, Custom);
302 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000303
304 // RET must be custom lowered, to meet ABI requirements
305 setOperationAction(ISD::RET, MVT::Other, Custom);
306
307 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
308 setOperationAction(ISD::VASTART , MVT::Other, Custom);
309
310 // Use the default implementation.
311 setOperationAction(ISD::VAARG , MVT::Other, Expand);
312 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
313 setOperationAction(ISD::VAEND , MVT::Other, Expand);
314 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
315 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
316 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
317 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
318
319 // Cell SPU has instructions for converting between i64 and fp.
320 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
321 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
322
323 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
324 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
325
326 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
327 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
328
329 // First set operation action for all vector types to expand. Then we
330 // will selectively turn on ones that can be effectively codegen'd.
331 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
332 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
333 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
334 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
335 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
336 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
337
338 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
339 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
340 // add/sub are legal for all supported vector VT's.
341 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
342 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
343 // mul has to be custom lowered.
344 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
345
346 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
347 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
348 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
349 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
350 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
351 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
352
353 // These operations need to be expanded:
354 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
355 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
356 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
357 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
358 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
359
360 // Custom lower build_vector, constant pool spills, insert and
361 // extract vector elements:
362 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
363 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
364 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
365 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
366 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
367 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
368 }
369
370 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
371 setOperationAction(ISD::AND, MVT::v16i8, Custom);
372 setOperationAction(ISD::OR, MVT::v16i8, Custom);
373 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
374 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000375
Scott Michel266bc8f2007-12-04 22:23:35 +0000376 setShiftAmountType(MVT::i32);
377 setSetCCResultContents(ZeroOrOneSetCCResult);
378
379 setStackPointerRegisterToSaveRestore(SPU::R1);
380
381 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000382 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000383 setTargetDAGCombine(ISD::ZERO_EXTEND);
384 setTargetDAGCombine(ISD::SIGN_EXTEND);
385 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel266bc8f2007-12-04 22:23:35 +0000386
387 computeRegisterProperties();
388}
389
390const char *
391SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
392{
393 if (node_names.empty()) {
394 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
395 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
396 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
397 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000398 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000399 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000400 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
401 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
402 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
403 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
404 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
405 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
406 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
407 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
408 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
409 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
410 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
411 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
412 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
413 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
414 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
415 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michela59d4692008-02-23 18:41:37 +0000416 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
417 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000418 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
419 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
420 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
421 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
422 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michela59d4692008-02-23 18:41:37 +0000423 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
424 "SPUISD::ROTQUAD_RZ_BYTES";
425 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
426 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel266bc8f2007-12-04 22:23:35 +0000427 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
428 "SPUISD::ROTBYTES_RIGHT_S";
429 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
430 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
431 "SPUISD::ROTBYTES_LEFT_CHAINED";
432 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
433 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel266bc8f2007-12-04 22:23:35 +0000434 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
435 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
436 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
437 }
438
439 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
440
441 return ((i != node_names.end()) ? i->second : 0);
442}
443
Scott Michel78c47fa2008-03-10 16:58:52 +0000444MVT::ValueType
445SPUTargetLowering::getSetCCResultType(const SDOperand &Op) const {
Scott Michel405fba12008-03-10 23:49:09 +0000446 MVT::ValueType VT = Op.getValueType();
447 if (MVT::isInteger(VT))
448 return VT;
449 else
450 return MVT::i32;
Scott Michel78c47fa2008-03-10 16:58:52 +0000451}
452
Scott Michel266bc8f2007-12-04 22:23:35 +0000453//===----------------------------------------------------------------------===//
454// Calling convention code:
455//===----------------------------------------------------------------------===//
456
457#include "SPUGenCallingConv.inc"
458
459//===----------------------------------------------------------------------===//
460// LowerOperation implementation
461//===----------------------------------------------------------------------===//
462
Scott Michel9de5d0d2008-01-11 02:53:15 +0000463/// Aligned load common code for CellSPU
464/*!
465 \param[in] Op The SelectionDAG load or store operand
466 \param[in] DAG The selection DAG
467 \param[in] ST CellSPU subtarget information structure
468 \param[in,out] alignment Caller initializes this to the load or store node's
469 value from getAlignment(), may be updated while generating the aligned load
470 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
471 offset (divisible by 16, modulo 16 == 0)
472 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
473 offset of the preferred slot (modulo 16 != 0)
474 \param[in,out] VT Caller initializes this value type to the the load or store
475 node's loaded or stored value type; may be updated if an i1-extended load or
476 store.
477 \param[out] was16aligned true if the base pointer had 16-byte alignment,
478 otherwise false. Can help to determine if the chunk needs to be rotated.
479
480 Both load and store lowering load a block of data aligned on a 16-byte
481 boundary. This is the common aligned load code shared between both.
482 */
483static SDOperand
484AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
485 LSBaseSDNode *LSN,
486 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000487 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000488{
489 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
490 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
491 SDOperand basePtr = LSN->getBasePtr();
492 SDOperand chain = LSN->getChain();
493
494 if (basePtr.getOpcode() == ISD::ADD) {
495 SDOperand Op1 = basePtr.Val->getOperand(1);
496
497 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000498 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000499
500 alignOffs = (int) CN->getValue();
501 prefSlotOffs = (int) (alignOffs & 0xf);
502
503 // Adjust the rotation amount to ensure that the final result ends up in
504 // the preferred slot:
505 prefSlotOffs -= vtm->prefslot_byte;
506 basePtr = basePtr.getOperand(0);
507
Scott Michel58c58182008-01-17 20:38:41 +0000508 // Loading from memory, can we adjust alignment?
509 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
510 SDOperand APtr = basePtr.getOperand(0);
511 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
512 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
513 alignment = GSDN->getGlobal()->getAlignment();
514 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000515 }
516 } else {
517 alignOffs = 0;
518 prefSlotOffs = -vtm->prefslot_byte;
519 }
520 } else {
521 alignOffs = 0;
522 prefSlotOffs = -vtm->prefslot_byte;
523 }
524
525 if (alignment == 16) {
526 // Realign the base pointer as a D-Form address:
527 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000528 basePtr = DAG.getNode(ISD::ADD, PtrVT,
529 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000530 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000531 }
532
533 // Emit the vector load:
534 was16aligned = true;
535 return DAG.getLoad(MVT::v16i8, chain, basePtr,
536 LSN->getSrcValue(), LSN->getSrcValueOffset(),
537 LSN->isVolatile(), 16);
538 }
539
540 // Unaligned load or we're using the "large memory" model, which means that
541 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000542 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000543 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000544 }
545
546 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000547 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000548 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000549 was16aligned = false;
550 return DAG.getLoad(MVT::v16i8, chain, basePtr,
551 LSN->getSrcValue(), LSN->getSrcValueOffset(),
552 LSN->isVolatile(), 16);
553}
554
Scott Michel266bc8f2007-12-04 22:23:35 +0000555/// Custom lower loads for CellSPU
556/*!
557 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
558 within a 16-byte block, we have to rotate to extract the requested element.
559 */
560static SDOperand
561LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
562 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000563 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000564 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000565 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000566 ISD::LoadExtType ExtType = LN->getExtensionType();
567 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000568 SDOperand Ops[8];
569
Scott Michel266bc8f2007-12-04 22:23:35 +0000570 switch (LN->getAddressingMode()) {
571 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000572 int offset, rotamt;
573 bool was16aligned;
574 SDOperand result =
575 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000576
Scott Michel9de5d0d2008-01-11 02:53:15 +0000577 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000578 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000579
580 the_chain = result.getValue(1);
581 // Rotate the chunk if necessary
582 if (rotamt < 0)
583 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000584 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000585 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
586
Scott Michel58c58182008-01-17 20:38:41 +0000587 Ops[0] = the_chain;
588 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000589 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000590 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
591 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000592 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000593 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000594 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000595 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000596 }
597
598 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
599 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000600 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000601
602 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
603 SDVTList scalarvts;
604 MVT::ValueType vecVT = MVT::v16i8;
605
606 // Convert the loaded v16i8 vector to the appropriate vector type
607 // specified by the operand:
608 if (OpVT == VT) {
609 if (VT != MVT::i1)
610 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
611 } else
612 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
613
614 Ops[0] = the_chain;
615 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
616 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
617 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
618 the_chain = result.getValue(1);
619 } else {
620 // Handle the sign and zero-extending loads for i1 and i8:
621 unsigned NewOpC;
622
623 if (ExtType == ISD::SEXTLOAD) {
624 NewOpC = (OpVT == MVT::i1
625 ? SPUISD::EXTRACT_I1_SEXT
626 : SPUISD::EXTRACT_I8_SEXT);
627 } else {
628 assert(ExtType == ISD::ZEXTLOAD);
629 NewOpC = (OpVT == MVT::i1
630 ? SPUISD::EXTRACT_I1_ZEXT
631 : SPUISD::EXTRACT_I8_ZEXT);
632 }
633
634 result = DAG.getNode(NewOpC, OpVT, result);
635 }
636
637 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000638 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000639 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000640 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000641 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000642
Scott Michel58c58182008-01-17 20:38:41 +0000643 result = DAG.getNode(SPUISD::LDRESULT, retvts,
644 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000645 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000646 }
647 case ISD::PRE_INC:
648 case ISD::PRE_DEC:
649 case ISD::POST_INC:
650 case ISD::POST_DEC:
651 case ISD::LAST_INDEXED_MODE:
652 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
653 "UNINDEXED\n";
654 cerr << (unsigned) LN->getAddressingMode() << "\n";
655 abort();
656 /*NOTREACHED*/
657 }
658
659 return SDOperand();
660}
661
662/// Custom lower stores for CellSPU
663/*!
664 All CellSPU stores are aligned to 16-byte boundaries, so for elements
665 within a 16-byte block, we have to generate a shuffle to insert the
666 requested element into its place, then store the resulting block.
667 */
668static SDOperand
669LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
670 StoreSDNode *SN = cast<StoreSDNode>(Op);
671 SDOperand Value = SN->getValue();
672 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000673 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000674 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000675 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000676
677 switch (SN->getAddressingMode()) {
678 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000679 int chunk_offset, slot_offset;
680 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000681
682 // The vector type we really want to load from the 16-byte chunk, except
683 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000684 unsigned vecVT, stVecVT = MVT::v16i8;
685
Scott Michel266bc8f2007-12-04 22:23:35 +0000686 if (StVT != MVT::i1)
687 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000688 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
689
Scott Michel9de5d0d2008-01-11 02:53:15 +0000690 SDOperand alignLoadVec =
691 AlignedLoad(Op, DAG, ST, SN, alignment,
692 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000693
Scott Michel9de5d0d2008-01-11 02:53:15 +0000694 if (alignLoadVec.Val == 0)
695 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000696
Scott Michel9de5d0d2008-01-11 02:53:15 +0000697 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
698 SDOperand basePtr = LN->getBasePtr();
699 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000700 SDOperand theValue = SN->getValue();
701 SDOperand result;
702
703 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000704 && (theValue.getOpcode() == ISD::AssertZext
705 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000706 // Drill down and get the value for zero- and sign-extended
707 // quantities
708 theValue = theValue.getOperand(0);
709 }
710
Scott Michel9de5d0d2008-01-11 02:53:15 +0000711 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000712
Scott Michel9de5d0d2008-01-11 02:53:15 +0000713 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
714 SDOperand insertEltPtr;
715 SDOperand insertEltOp;
716
717 // If the base pointer is already a D-form address, then just create
718 // a new D-form address with a slot offset and the orignal base pointer.
719 // Otherwise generate a D-form address with the slot offset relative
720 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000721 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
722 DEBUG(basePtr.Val->dump(&DAG));
723 DEBUG(cerr << "\n");
724
Scott Michel053c1da2008-01-29 02:16:57 +0000725 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
726 (basePtr.getOpcode() == ISD::ADD
727 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000728 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000729 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000730 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000731 }
732
733 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000734 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000735 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
736 alignLoadVec,
737 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000738
Scott Michel9de5d0d2008-01-11 02:53:15 +0000739 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000740 LN->getSrcValue(), LN->getSrcValueOffset(),
741 LN->isVolatile(), LN->getAlignment());
742
743 return result;
744 /*UNREACHED*/
745 }
746 case ISD::PRE_INC:
747 case ISD::PRE_DEC:
748 case ISD::POST_INC:
749 case ISD::POST_DEC:
750 case ISD::LAST_INDEXED_MODE:
751 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
752 "UNINDEXED\n";
753 cerr << (unsigned) SN->getAddressingMode() << "\n";
754 abort();
755 /*NOTREACHED*/
756 }
757
758 return SDOperand();
759}
760
761/// Generate the address of a constant pool entry.
762static SDOperand
763LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
764 MVT::ValueType PtrVT = Op.getValueType();
765 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
766 Constant *C = CP->getConstVal();
767 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000768 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000769 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000770
771 if (TM.getRelocationModel() == Reloc::Static) {
772 if (!ST->usingLargeMem()) {
773 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000774 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000775 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000776 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
777 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000778 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000779 }
780 }
781
782 assert(0 &&
783 "LowerConstantPool: Relocation model other than static not supported.");
784 return SDOperand();
785}
786
787static SDOperand
788LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
789 MVT::ValueType PtrVT = Op.getValueType();
790 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
791 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
792 SDOperand Zero = DAG.getConstant(0, PtrVT);
793 const TargetMachine &TM = DAG.getTarget();
794
795 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000796 if (!ST->usingLargeMem()) {
797 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
798 } else {
799 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
800 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
801 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
802 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000803 }
804
805 assert(0 &&
806 "LowerJumpTable: Relocation model other than static not supported.");
807 return SDOperand();
808}
809
810static SDOperand
811LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
812 MVT::ValueType PtrVT = Op.getValueType();
813 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
814 GlobalValue *GV = GSDN->getGlobal();
815 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000816 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000817 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000818
819 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000820 if (!ST->usingLargeMem()) {
821 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
822 } else {
823 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
824 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
825 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
826 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000827 } else {
828 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000829 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000830 abort();
831 /*NOTREACHED*/
832 }
833
834 return SDOperand();
835}
836
837//! Custom lower i64 integer constants
838/*!
839 This code inserts all of the necessary juggling that needs to occur to load
840 a 64-bit constant into a register.
841 */
842static SDOperand
843LowerConstant(SDOperand Op, SelectionDAG &DAG) {
844 unsigned VT = Op.getValueType();
845 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
846
847 if (VT == MVT::i64) {
848 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
849 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000850 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000851 } else {
852 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000853 << MVT::getValueTypeString(VT)
854 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000855 abort();
856 /*NOTREACHED*/
857 }
858
859 return SDOperand();
860}
861
Nate Begemanccef5802008-02-14 18:43:04 +0000862//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000863static SDOperand
864LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
865 unsigned VT = Op.getValueType();
866 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
867
868 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000869 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000870
Nate Begemanccef5802008-02-14 18:43:04 +0000871 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000872 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000873 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000874 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000875 }
876
877 return SDOperand();
878}
879
Scott Michel58c58182008-01-17 20:38:41 +0000880//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
881static SDOperand
882LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
883{
884 SDOperand Cond = Op.getOperand(1);
885 MVT::ValueType CondVT = Cond.getValueType();
886 MVT::ValueType CondNVT;
887
888 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
889 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
890 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
891 Op.getOperand(0),
892 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
893 Op.getOperand(2));
894 } else
895 return SDOperand(); // Unchanged
896}
897
Scott Michel266bc8f2007-12-04 22:23:35 +0000898static SDOperand
899LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
900{
901 MachineFunction &MF = DAG.getMachineFunction();
902 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000903 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000904 SmallVector<SDOperand, 8> ArgValues;
905 SDOperand Root = Op.getOperand(0);
906 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
907
908 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
909 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
910
911 unsigned ArgOffset = SPUFrameInfo::minStackSize();
912 unsigned ArgRegIdx = 0;
913 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
914
915 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
916
917 // Add DAG nodes to load the arguments or copy them out of registers.
918 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
919 SDOperand ArgVal;
920 bool needsLoad = false;
921 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
922 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
923
924 switch (ObjectVT) {
925 default: {
926 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000927 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000928 << "\n";
929 abort();
930 }
931 case MVT::i8:
932 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000933 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
934 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000935 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
936 ++ArgRegIdx;
937 } else {
938 needsLoad = true;
939 }
940 break;
941 case MVT::i16:
942 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000943 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
944 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000945 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
946 ++ArgRegIdx;
947 } else {
948 needsLoad = true;
949 }
950 break;
951 case MVT::i32:
952 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000953 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
954 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000955 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
956 ++ArgRegIdx;
957 } else {
958 needsLoad = true;
959 }
960 break;
961 case MVT::i64:
962 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000963 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
964 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000965 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
966 ++ArgRegIdx;
967 } else {
968 needsLoad = true;
969 }
970 break;
971 case MVT::f32:
972 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000973 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
974 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000975 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
976 ++ArgRegIdx;
977 } else {
978 needsLoad = true;
979 }
980 break;
981 case MVT::f64:
982 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000983 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
984 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000985 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
986 ++ArgRegIdx;
987 } else {
988 needsLoad = true;
989 }
990 break;
991 case MVT::v2f64:
992 case MVT::v4f32:
Scott Michelad2715e2008-03-05 23:02:02 +0000993 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +0000994 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();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001359 if (ValueType == MVT::i64) {
1360 uint64_t UValue = CN->getValue();
1361 uint32_t upper = uint32_t(UValue >> 32);
1362 uint32_t lower = uint32_t(UValue);
1363 if (upper != lower)
1364 return SDOperand();
1365 Value = Value >> 32;
1366 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001367 if (Value <= 0x3ffff)
1368 return DAG.getConstant(Value, ValueType);
1369 }
1370
1371 return SDOperand();
1372}
1373
1374/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1375/// and the value fits into a signed 16-bit constant, and if so, return the
1376/// constant
1377SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1378 MVT::ValueType ValueType) {
1379 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001380 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001381 if (ValueType == MVT::i64) {
1382 uint64_t UValue = CN->getValue();
1383 uint32_t upper = uint32_t(UValue >> 32);
1384 uint32_t lower = uint32_t(UValue);
1385 if (upper != lower)
1386 return SDOperand();
1387 Value = Value >> 32;
1388 }
Scott Michelad2715e2008-03-05 23:02:02 +00001389 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1390 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001391 }
1392 }
1393
1394 return SDOperand();
1395}
1396
1397/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1398/// and the value fits into a signed 10-bit constant, and if so, return the
1399/// constant
1400SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1401 MVT::ValueType ValueType) {
1402 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001403 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001404 if (ValueType == MVT::i64) {
1405 uint64_t UValue = CN->getValue();
1406 uint32_t upper = uint32_t(UValue >> 32);
1407 uint32_t lower = uint32_t(UValue);
1408 if (upper != lower)
1409 return SDOperand();
1410 Value = Value >> 32;
1411 }
Scott Michelad2715e2008-03-05 23:02:02 +00001412 if (isS10Constant(Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001413 return DAG.getConstant(Value, ValueType);
1414 }
1415
1416 return SDOperand();
1417}
1418
1419/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1420/// and the value fits into a signed 8-bit constant, and if so, return the
1421/// constant.
1422///
1423/// @note: The incoming vector is v16i8 because that's the only way we can load
1424/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1425/// same value.
1426SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1427 MVT::ValueType ValueType) {
1428 if (ConstantSDNode *CN = getVecImm(N)) {
1429 int Value = (int) CN->getValue();
1430 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001431 && Value <= 0xffff /* truncated from uint64_t */
1432 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001433 return DAG.getConstant(Value & 0xff, ValueType);
1434 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001435 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001436 return DAG.getConstant(Value, ValueType);
1437 }
1438
1439 return SDOperand();
1440}
1441
1442/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1443/// and the value fits into a signed 16-bit constant, and if so, return the
1444/// constant
1445SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1446 MVT::ValueType ValueType) {
1447 if (ConstantSDNode *CN = getVecImm(N)) {
1448 uint64_t Value = CN->getValue();
1449 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001450 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1451 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001452 return DAG.getConstant(Value >> 16, ValueType);
1453 }
1454
1455 return SDOperand();
1456}
1457
1458/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1459SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1460 if (ConstantSDNode *CN = getVecImm(N)) {
1461 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1462 }
1463
1464 return SDOperand();
1465}
1466
1467/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1468SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1469 if (ConstantSDNode *CN = getVecImm(N)) {
1470 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1471 }
1472
1473 return SDOperand();
1474}
1475
1476// If this is a vector of constants or undefs, get the bits. A bit in
1477// UndefBits is set if the corresponding element of the vector is an
1478// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1479// zero. Return true if this is not an array of constants, false if it is.
1480//
1481static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1482 uint64_t UndefBits[2]) {
1483 // Start with zero'd results.
1484 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1485
1486 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1487 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1488 SDOperand OpVal = BV->getOperand(i);
1489
1490 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1491 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1492
1493 uint64_t EltBits = 0;
1494 if (OpVal.getOpcode() == ISD::UNDEF) {
1495 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1496 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1497 continue;
1498 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1499 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1500 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1501 const APFloat &apf = CN->getValueAPF();
1502 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001503 ? FloatToBits(apf.convertToFloat())
1504 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001505 } else {
1506 // Nonconstant element.
1507 return true;
1508 }
1509
1510 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1511 }
1512
1513 //printf("%llx %llx %llx %llx\n",
1514 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1515 return false;
1516}
1517
1518/// If this is a splat (repetition) of a value across the whole vector, return
1519/// the smallest size that splats it. For example, "0x01010101010101..." is a
1520/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1521/// SplatSize = 1 byte.
1522static bool isConstantSplat(const uint64_t Bits128[2],
1523 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001524 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001525 uint64_t &SplatBits, uint64_t &SplatUndef,
1526 int &SplatSize) {
1527 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1528 // the same as the lower 64-bits, ignoring undefs.
1529 uint64_t Bits64 = Bits128[0] | Bits128[1];
1530 uint64_t Undef64 = Undef128[0] & Undef128[1];
1531 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1532 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1533 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1534 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1535
1536 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1537 if (MinSplatBits < 64) {
1538
1539 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1540 // undefs.
1541 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001542 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001543
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001544 // If the top 16-bits are different than the lower 16-bits, ignoring
1545 // undefs, we have an i32 splat.
1546 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1547 if (MinSplatBits < 16) {
1548 // If the top 8-bits are different than the lower 8-bits, ignoring
1549 // undefs, we have an i16 splat.
1550 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1551 // Otherwise, we have an 8-bit splat.
1552 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1553 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1554 SplatSize = 1;
1555 return true;
1556 }
1557 } else {
1558 SplatBits = Bits16;
1559 SplatUndef = Undef16;
1560 SplatSize = 2;
1561 return true;
1562 }
1563 }
1564 } else {
1565 SplatBits = Bits32;
1566 SplatUndef = Undef32;
1567 SplatSize = 4;
1568 return true;
1569 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001570 }
1571 } else {
1572 SplatBits = Bits128[0];
1573 SplatUndef = Undef128[0];
1574 SplatSize = 8;
1575 return true;
1576 }
1577 }
1578
1579 return false; // Can't be a splat if two pieces don't match.
1580}
1581
1582// If this is a case we can't handle, return null and let the default
1583// expansion code take care of it. If we CAN select this case, and if it
1584// selects to a single instruction, return Op. Otherwise, if we can codegen
1585// this case more efficiently than a constant pool load, lower it to the
1586// sequence of ops that should be used.
1587static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1588 MVT::ValueType VT = Op.getValueType();
1589 // If this is a vector of constants or undefs, get the bits. A bit in
1590 // UndefBits is set if the corresponding element of the vector is an
1591 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1592 // zero.
1593 uint64_t VectorBits[2];
1594 uint64_t UndefBits[2];
1595 uint64_t SplatBits, SplatUndef;
1596 int SplatSize;
1597 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1598 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001599 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001600 SplatBits, SplatUndef, SplatSize))
1601 return SDOperand(); // Not a constant vector, not a splat.
1602
1603 switch (VT) {
1604 default:
1605 case MVT::v4f32: {
1606 uint32_t Value32 = SplatBits;
1607 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001608 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001609 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1610 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1611 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001612 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001613 break;
1614 }
1615 case MVT::v2f64: {
1616 uint64_t f64val = SplatBits;
1617 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001618 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001619 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1620 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1621 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001622 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001623 break;
1624 }
1625 case MVT::v16i8: {
1626 // 8-bit constants have to be expanded to 16-bits
1627 unsigned short Value16 = SplatBits | (SplatBits << 8);
1628 SDOperand Ops[8];
1629 for (int i = 0; i < 8; ++i)
1630 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1631 return DAG.getNode(ISD::BIT_CONVERT, VT,
1632 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1633 }
1634 case MVT::v8i16: {
1635 unsigned short Value16;
1636 if (SplatSize == 2)
1637 Value16 = (unsigned short) (SplatBits & 0xffff);
1638 else
1639 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1640 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1641 SDOperand Ops[8];
1642 for (int i = 0; i < 8; ++i) Ops[i] = T;
1643 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1644 }
1645 case MVT::v4i32: {
1646 unsigned int Value = SplatBits;
1647 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1648 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1649 }
1650 case MVT::v2i64: {
1651 uint64_t val = SplatBits;
1652 uint32_t upper = uint32_t(val >> 32);
1653 uint32_t lower = uint32_t(val);
1654
Scott Michel4cb8bd82008-03-06 04:02:54 +00001655 if (upper == lower) {
1656 // Magic constant that can be matched by IL, ILA, et. al.
1657 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1658 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michelad2715e2008-03-05 23:02:02 +00001659 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +00001660 SDOperand LO32;
1661 SDOperand HI32;
1662 SmallVector<SDOperand, 16> ShufBytes;
1663 SDOperand Result;
1664 bool upper_special, lower_special;
1665
1666 // NOTE: This code creates common-case shuffle masks that can be easily
1667 // detected as common expressions. It is not attempting to create highly
1668 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1669
1670 // Detect if the upper or lower half is a special shuffle mask pattern:
1671 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1672 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1673
1674 // Create lower vector if not a special pattern
1675 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001676 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1677 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1678 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1679 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001680 }
1681
1682 // Create upper vector if not a special pattern
1683 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001684 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1685 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1686 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1687 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001688 }
1689
1690 // If either upper or lower are special, then the two input operands are
1691 // the same (basically, one of them is a "don't care")
1692 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001693 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001694 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001695 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001696 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001697 // Unhappy situation... both upper and lower are special, so punt with
1698 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001699 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001700 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001701 Zero, Zero);
1702 }
1703
1704 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001705 for (int j = 0; j < 4; ++j) {
1706 SDOperand V;
1707 bool process_upper, process_lower;
1708 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001709
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001710 process_upper = (upper_special && (i & 1) == 0);
1711 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001712
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001713 if (process_upper || process_lower) {
1714 if ((process_upper && upper == 0)
1715 || (process_lower && lower == 0))
1716 val = 0x80;
1717 else if ((process_upper && upper == 0xffffffff)
1718 || (process_lower && lower == 0xffffffff))
1719 val = 0xc0;
1720 else if ((process_upper && upper == 0x80000000)
1721 || (process_lower && lower == 0x80000000))
1722 val = (j == 0 ? 0xe0 : 0x80);
1723 } else
1724 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001725
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001726 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1727 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001728 }
1729
1730 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001731 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1732 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001733 }
1734 }
1735 }
1736
1737 return SDOperand();
1738}
1739
1740/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1741/// which the Cell can operate. The code inspects V3 to ascertain whether the
1742/// permutation vector, V3, is monotonically increasing with one "exception"
1743/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1744/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1745/// In either case, the net result is going to eventually invoke SHUFB to
1746/// permute/shuffle the bytes from V1 and V2.
1747/// \note
1748/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1749/// control word for byte/halfword/word insertion. This takes care of a single
1750/// element move from V2 into V1.
1751/// \note
1752/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1753static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1754 SDOperand V1 = Op.getOperand(0);
1755 SDOperand V2 = Op.getOperand(1);
1756 SDOperand PermMask = Op.getOperand(2);
1757
1758 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1759
1760 // If we have a single element being moved from V1 to V2, this can be handled
1761 // using the C*[DX] compute mask instructions, but the vector elements have
1762 // to be monotonically increasing with one exception element.
1763 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1764 unsigned EltsFromV2 = 0;
1765 unsigned V2Elt = 0;
1766 unsigned V2EltIdx0 = 0;
1767 unsigned CurrElt = 0;
1768 bool monotonic = true;
1769 if (EltVT == MVT::i8)
1770 V2EltIdx0 = 16;
1771 else if (EltVT == MVT::i16)
1772 V2EltIdx0 = 8;
1773 else if (EltVT == MVT::i32)
1774 V2EltIdx0 = 4;
1775 else
1776 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1777
1778 for (unsigned i = 0, e = PermMask.getNumOperands();
1779 EltsFromV2 <= 1 && monotonic && i != e;
1780 ++i) {
1781 unsigned SrcElt;
1782 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1783 SrcElt = 0;
1784 else
1785 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1786
1787 if (SrcElt >= V2EltIdx0) {
1788 ++EltsFromV2;
1789 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1790 } else if (CurrElt != SrcElt) {
1791 monotonic = false;
1792 }
1793
1794 ++CurrElt;
1795 }
1796
1797 if (EltsFromV2 == 1 && monotonic) {
1798 // Compute mask and shuffle
1799 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001800 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1801 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001802 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1803 // Initialize temporary register to 0
1804 SDOperand InitTempReg =
1805 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1806 // Copy register's contents as index in INSERT_MASK:
1807 SDOperand ShufMaskOp =
1808 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001809 DAG.getTargetConstant(V2Elt, MVT::i32),
1810 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001811 // Use shuffle mask in SHUFB synthetic instruction:
1812 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1813 } else {
1814 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1815 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1816
1817 SmallVector<SDOperand, 16> ResultMask;
1818 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1819 unsigned SrcElt;
1820 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001821 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001822 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001823 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001824
Scott Michela59d4692008-02-23 18:41:37 +00001825 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001826 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1827 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001828 }
1829 }
1830
1831 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001832 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001833 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1834 }
1835}
1836
1837static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001838 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001839
1840 if (Op0.Val->getOpcode() == ISD::Constant) {
1841 // For a constant, build the appropriate constant vector, which will
1842 // eventually simplify to a vector register load.
1843
1844 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1845 SmallVector<SDOperand, 16> ConstVecValues;
1846 MVT::ValueType VT;
1847 size_t n_copies;
1848
1849 // Create a constant vector:
1850 switch (Op.getValueType()) {
1851 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001852 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001853 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1854 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1855 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1856 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1857 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1858 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1859 }
1860
1861 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1862 for (size_t j = 0; j < n_copies; ++j)
1863 ConstVecValues.push_back(CValue);
1864
1865 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001866 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001867 } else {
1868 // Otherwise, copy the value from one register to another:
1869 switch (Op0.getValueType()) {
1870 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1871 case MVT::i8:
1872 case MVT::i16:
1873 case MVT::i32:
1874 case MVT::i64:
1875 case MVT::f32:
1876 case MVT::f64:
1877 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1878 }
1879 }
1880
1881 return SDOperand();
1882}
1883
1884static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1885 switch (Op.getValueType()) {
1886 case MVT::v4i32: {
1887 SDOperand rA = Op.getOperand(0);
1888 SDOperand rB = Op.getOperand(1);
1889 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1890 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1891 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1892 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1893
1894 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1895 break;
1896 }
1897
1898 // Multiply two v8i16 vectors (pipeline friendly version):
1899 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1900 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1901 // c) Use SELB to select upper and lower halves from the intermediate results
1902 //
1903 // NOTE: We really want to move the FSMBI to earlier to actually get the
1904 // dual-issue. This code does manage to do this, even if it's a little on
1905 // the wacky side
1906 case MVT::v8i16: {
1907 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001908 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001909 SDOperand Chain = Op.getOperand(0);
1910 SDOperand rA = Op.getOperand(0);
1911 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001912 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1913 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001914
1915 SDOperand FSMBOp =
1916 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001917 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1918 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001919
1920 SDOperand HHProd =
1921 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001922 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001923
1924 SDOperand HHProd_v4i32 =
1925 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001926 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001927
1928 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001929 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1930 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1931 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1932 HHProd_v4i32,
1933 DAG.getConstant(16, MVT::i16))),
1934 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001935 }
1936
1937 // This M00sE is N@stI! (apologies to Monty Python)
1938 //
1939 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1940 // is to break it all apart, sign extend, and reassemble the various
1941 // intermediate products.
1942 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001943 SDOperand rA = Op.getOperand(0);
1944 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001945 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1946 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001947
1948 SDOperand LLProd =
1949 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001950 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1951 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001952
1953 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1954
1955 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1956
1957 SDOperand LHProd =
1958 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001959 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001960
Scott Michela59d4692008-02-23 18:41:37 +00001961 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1962 DAG.getConstant(0x2222, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001963
Scott Michela59d4692008-02-23 18:41:37 +00001964 SDOperand LoProdParts =
1965 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1966 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1967 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001968
1969 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1970
1971 SDOperand LoProd =
1972 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001973 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001974 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1975 LoProdMask, LoProdMask,
1976 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001977
1978 SDOperand rAH =
1979 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001980 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001981
1982 SDOperand rBH =
1983 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001984 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001985
1986 SDOperand HLProd =
1987 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001988 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1989 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001990
1991 SDOperand HHProd_1 =
1992 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001993 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1994 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1995 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1996 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001997
1998 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00001999 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2000 HLProd,
2001 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2002 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00002003
2004 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00002005 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002006
2007 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002008 DAG.getNode(ISD::OR, MVT::v4i32,
2009 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002010 }
2011
2012 default:
2013 cerr << "CellSPU: Unknown vector multiplication, got "
2014 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002015 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002016 abort();
2017 /*NOTREACHED*/
2018 }
2019
2020 return SDOperand();
2021}
2022
2023static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2024 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002025 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002026
2027 SDOperand A = Op.getOperand(0);
2028 SDOperand B = Op.getOperand(1);
2029 unsigned VT = Op.getValueType();
2030
2031 unsigned VRegBR, VRegC;
2032
2033 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002034 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2035 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002036 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002037 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2038 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002039 }
2040 // TODO: make sure we're feeding FPInterp the right arguments
2041 // Right now: fi B, frest(B)
2042
2043 // Computes BRcpl =
2044 // (Floating Interpolate (FP Reciprocal Estimate B))
2045 SDOperand BRcpl =
2046 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002047 DAG.getNode(SPUISD::FPInterp, VT, B,
2048 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002049
2050 // Computes A * BRcpl and stores in a temporary register
2051 SDOperand AxBRcpl =
2052 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002053 DAG.getNode(ISD::FMUL, VT, A,
2054 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002055 // What's the Chain variable do? It's magic!
2056 // TODO: set Chain = Op(0).getEntryNode()
2057
2058 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002059 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2060 DAG.getNode(ISD::FMUL, VT,
2061 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2062 DAG.getNode(ISD::FSUB, VT, A,
2063 DAG.getNode(ISD::FMUL, VT, B,
2064 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002065}
2066
Scott Michel266bc8f2007-12-04 22:23:35 +00002067static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2068 unsigned VT = Op.getValueType();
2069 SDOperand N = Op.getOperand(0);
2070 SDOperand Elt = Op.getOperand(1);
2071 SDOperand ShufMask[16];
2072 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2073
2074 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2075
2076 int EltNo = (int) C->getValue();
2077
2078 // sanity checks:
2079 if (VT == MVT::i8 && EltNo >= 16)
2080 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2081 else if (VT == MVT::i16 && EltNo >= 8)
2082 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2083 else if (VT == MVT::i32 && EltNo >= 4)
2084 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2085 else if (VT == MVT::i64 && EltNo >= 2)
2086 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2087
2088 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2089 // i32 and i64: Element 0 is the preferred slot
2090 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2091 }
2092
2093 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002094 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002095 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2096
2097 switch (VT) {
2098 case MVT::i8: {
2099 prefslot_begin = prefslot_end = 3;
2100 break;
2101 }
2102 case MVT::i16: {
2103 prefslot_begin = 2; prefslot_end = 3;
2104 break;
2105 }
2106 case MVT::i32: {
2107 prefslot_begin = 0; prefslot_end = 3;
2108 break;
2109 }
2110 case MVT::i64: {
2111 prefslot_begin = 0; prefslot_end = 7;
2112 break;
2113 }
2114 }
2115
Scott Michel0e5665b2007-12-19 21:17:42 +00002116 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002117 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002118
Scott Michel266bc8f2007-12-04 22:23:35 +00002119 for (int i = 0; i < 16; ++i) {
2120 // zero fill uppper part of preferred slot, don't care about the
2121 // other slots:
2122 unsigned int mask_val;
2123
2124 if (i <= prefslot_end) {
2125 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002126 ((i < prefslot_begin)
2127 ? 0x80
2128 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002129
Scott Michel0e5665b2007-12-19 21:17:42 +00002130 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002131 } else
2132 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2133 }
2134
2135 SDOperand ShufMaskVec =
2136 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002137 &ShufMask[0],
2138 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002139
2140 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002141 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2142 N, N, ShufMaskVec));
2143
Scott Michel266bc8f2007-12-04 22:23:35 +00002144}
2145
2146static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2147 SDOperand VecOp = Op.getOperand(0);
2148 SDOperand ValOp = Op.getOperand(1);
2149 SDOperand IdxOp = Op.getOperand(2);
2150 MVT::ValueType VT = Op.getValueType();
2151
2152 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2153 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2154
2155 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2156 // Use $2 because it's always 16-byte aligned and it's available:
2157 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2158
2159 SDOperand result =
2160 DAG.getNode(SPUISD::SHUFB, VT,
2161 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2162 VecOp,
2163 DAG.getNode(SPUISD::INSERT_MASK, VT,
2164 DAG.getNode(ISD::ADD, PtrVT,
2165 PtrBase,
2166 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002167 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002168
2169 return result;
2170}
2171
Scott Michela59d4692008-02-23 18:41:37 +00002172static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2173{
Scott Michel266bc8f2007-12-04 22:23:35 +00002174 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2175
2176 assert(Op.getValueType() == MVT::i8);
2177 switch (Opc) {
2178 default:
2179 assert(0 && "Unhandled i8 math operator");
2180 /*NOTREACHED*/
2181 break;
2182 case ISD::SUB: {
2183 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2184 // the result:
2185 SDOperand N1 = Op.getOperand(1);
2186 N0 = (N0.getOpcode() != ISD::Constant
2187 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2188 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2189 N1 = (N1.getOpcode() != ISD::Constant
2190 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2191 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2192 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2193 DAG.getNode(Opc, MVT::i16, N0, N1));
2194 }
2195 case ISD::ROTR:
2196 case ISD::ROTL: {
2197 SDOperand N1 = Op.getOperand(1);
2198 unsigned N1Opc;
2199 N0 = (N0.getOpcode() != ISD::Constant
2200 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2201 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2202 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2203 N1 = (N1.getOpcode() != ISD::Constant
2204 ? DAG.getNode(N1Opc, MVT::i16, N1)
2205 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2206 SDOperand ExpandArg =
2207 DAG.getNode(ISD::OR, MVT::i16, N0,
2208 DAG.getNode(ISD::SHL, MVT::i16,
2209 N0, DAG.getConstant(8, MVT::i16)));
2210 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2211 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2212 }
2213 case ISD::SRL:
2214 case ISD::SHL: {
2215 SDOperand N1 = Op.getOperand(1);
2216 unsigned N1Opc;
2217 N0 = (N0.getOpcode() != ISD::Constant
2218 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2219 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2220 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2221 N1 = (N1.getOpcode() != ISD::Constant
2222 ? DAG.getNode(N1Opc, MVT::i16, N1)
2223 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2224 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2225 DAG.getNode(Opc, MVT::i16, N0, N1));
2226 }
2227 case ISD::SRA: {
2228 SDOperand N1 = Op.getOperand(1);
2229 unsigned N1Opc;
2230 N0 = (N0.getOpcode() != ISD::Constant
2231 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2232 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2233 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2234 N1 = (N1.getOpcode() != ISD::Constant
2235 ? DAG.getNode(N1Opc, MVT::i16, N1)
2236 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2237 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2238 DAG.getNode(Opc, MVT::i16, N0, N1));
2239 }
2240 case ISD::MUL: {
2241 SDOperand N1 = Op.getOperand(1);
2242 unsigned N1Opc;
2243 N0 = (N0.getOpcode() != ISD::Constant
2244 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2245 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2246 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2247 N1 = (N1.getOpcode() != ISD::Constant
2248 ? DAG.getNode(N1Opc, MVT::i16, N1)
2249 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2250 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2251 DAG.getNode(Opc, MVT::i16, N0, N1));
2252 break;
2253 }
2254 }
2255
2256 return SDOperand();
2257}
2258
Scott Michela59d4692008-02-23 18:41:37 +00002259static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2260{
2261 MVT::ValueType VT = Op.getValueType();
2262 unsigned VecVT =
2263 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2264
2265 SDOperand Op0 = Op.getOperand(0);
2266
2267 switch (Opc) {
2268 case ISD::ZERO_EXTEND:
2269 case ISD::SIGN_EXTEND:
2270 case ISD::ANY_EXTEND: {
2271 MVT::ValueType Op0VT = Op0.getValueType();
2272 unsigned Op0VecVT =
2273 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2274
2275 assert(Op0VT == MVT::i32
2276 && "CellSPU: Zero/sign extending something other than i32");
2277
2278 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2279 ? SPUISD::ROTBYTES_RIGHT_S
2280 : SPUISD::ROTQUAD_RZ_BYTES);
2281 SDOperand PromoteScalar =
2282 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2283
2284 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2285 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2286 DAG.getNode(NewOpc, Op0VecVT,
2287 PromoteScalar,
2288 DAG.getConstant(4, MVT::i32))));
2289 }
2290
2291 case ISD::SHL: {
2292 SDOperand ShiftAmt = Op.getOperand(1);
2293 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2294 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2295 SDOperand MaskLower =
2296 DAG.getNode(SPUISD::SELB, VecVT,
2297 Op0Vec,
2298 DAG.getConstant(0, VecVT),
2299 DAG.getNode(SPUISD::FSMBI, VecVT,
2300 DAG.getConstant(0xff00ULL, MVT::i16)));
2301 SDOperand ShiftAmtBytes =
2302 DAG.getNode(ISD::SRL, ShiftAmtVT,
2303 ShiftAmt,
2304 DAG.getConstant(3, ShiftAmtVT));
2305 SDOperand ShiftAmtBits =
2306 DAG.getNode(ISD::AND, ShiftAmtVT,
2307 ShiftAmt,
2308 DAG.getConstant(7, ShiftAmtVT));
2309
2310 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2311 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2312 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2313 MaskLower, ShiftAmtBytes),
2314 ShiftAmtBits));
2315 }
2316
2317 case ISD::SRL: {
2318 unsigned VT = unsigned(Op.getValueType());
2319 SDOperand ShiftAmt = Op.getOperand(1);
2320 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2321 SDOperand ShiftAmtBytes =
2322 DAG.getNode(ISD::SRL, ShiftAmtVT,
2323 ShiftAmt,
2324 DAG.getConstant(3, ShiftAmtVT));
2325 SDOperand ShiftAmtBits =
2326 DAG.getNode(ISD::AND, ShiftAmtVT,
2327 ShiftAmt,
2328 DAG.getConstant(7, ShiftAmtVT));
2329
2330 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2331 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2332 Op0, ShiftAmtBytes),
2333 ShiftAmtBits);
2334 }
2335 }
2336
2337 return SDOperand();
2338}
2339
Scott Michel266bc8f2007-12-04 22:23:35 +00002340//! Lower byte immediate operations for v16i8 vectors:
2341static SDOperand
2342LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2343 SDOperand ConstVec;
2344 SDOperand Arg;
2345 MVT::ValueType VT = Op.getValueType();
2346
2347 ConstVec = Op.getOperand(0);
2348 Arg = Op.getOperand(1);
2349 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2350 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2351 ConstVec = ConstVec.getOperand(0);
2352 } else {
2353 ConstVec = Op.getOperand(1);
2354 Arg = Op.getOperand(0);
2355 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002356 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002357 }
2358 }
2359 }
2360
2361 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2362 uint64_t VectorBits[2];
2363 uint64_t UndefBits[2];
2364 uint64_t SplatBits, SplatUndef;
2365 int SplatSize;
2366
2367 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002368 && isConstantSplat(VectorBits, UndefBits,
2369 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2370 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002371 SDOperand tcVec[16];
2372 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2373 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2374
2375 // Turn the BUILD_VECTOR into a set of target constants:
2376 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002377 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002378
2379 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002380 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002381 }
2382 }
2383
2384 return SDOperand();
2385}
2386
2387//! Lower i32 multiplication
2388static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2389 unsigned Opc) {
2390 switch (VT) {
2391 default:
2392 cerr << "CellSPU: Unknown LowerMUL value type, got "
2393 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002394 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002395 abort();
2396 /*NOTREACHED*/
2397
2398 case MVT::i32: {
2399 SDOperand rA = Op.getOperand(0);
2400 SDOperand rB = Op.getOperand(1);
2401
2402 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002403 DAG.getNode(ISD::ADD, MVT::i32,
2404 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2405 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2406 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002407 }
2408 }
2409
2410 return SDOperand();
2411}
2412
2413//! Custom lowering for CTPOP (count population)
2414/*!
2415 Custom lowering code that counts the number ones in the input
2416 operand. SPU has such an instruction, but it counts the number of
2417 ones per byte, which then have to be accumulated.
2418*/
2419static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2420 unsigned VT = Op.getValueType();
2421 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2422
2423 switch (VT) {
2424 case MVT::i8: {
2425 SDOperand N = Op.getOperand(0);
2426 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2427
2428 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2429 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2430
2431 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2432 }
2433
2434 case MVT::i16: {
2435 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002436 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002437
Chris Lattner84bc5422007-12-31 04:13:23 +00002438 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002439
2440 SDOperand N = Op.getOperand(0);
2441 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2442 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2443 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2444
2445 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2446 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2447
2448 // CNTB_result becomes the chain to which all of the virtual registers
2449 // CNTB_reg, SUM1_reg become associated:
2450 SDOperand CNTB_result =
2451 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002452
Scott Michel266bc8f2007-12-04 22:23:35 +00002453 SDOperand CNTB_rescopy =
2454 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2455
2456 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2457
2458 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002459 DAG.getNode(ISD::ADD, MVT::i16,
2460 DAG.getNode(ISD::SRL, MVT::i16,
2461 Tmp1, Shift1),
2462 Tmp1),
2463 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002464 }
2465
2466 case MVT::i32: {
2467 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002468 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002469
Chris Lattner84bc5422007-12-31 04:13:23 +00002470 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2471 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002472
2473 SDOperand N = Op.getOperand(0);
2474 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2475 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2476 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2477 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2478
2479 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2480 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2481
2482 // CNTB_result becomes the chain to which all of the virtual registers
2483 // CNTB_reg, SUM1_reg become associated:
2484 SDOperand CNTB_result =
2485 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002486
Scott Michel266bc8f2007-12-04 22:23:35 +00002487 SDOperand CNTB_rescopy =
2488 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2489
2490 SDOperand Comp1 =
2491 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002492 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002493
2494 SDOperand Sum1 =
2495 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002496 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002497
2498 SDOperand Sum1_rescopy =
2499 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2500
2501 SDOperand Comp2 =
2502 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002503 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2504 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002505 SDOperand Sum2 =
2506 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002507 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002508
2509 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2510 }
2511
2512 case MVT::i64:
2513 break;
2514 }
2515
2516 return SDOperand();
2517}
2518
2519/// LowerOperation - Provide custom lowering hooks for some operations.
2520///
2521SDOperand
2522SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2523{
Scott Michela59d4692008-02-23 18:41:37 +00002524 unsigned Opc = (unsigned) Op.getOpcode();
2525 unsigned VT = (unsigned) Op.getValueType();
2526
2527 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002528 default: {
2529 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002530 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002531 cerr << "*Op.Val:\n";
2532 Op.Val->dump();
2533 abort();
2534 }
2535 case ISD::LOAD:
2536 case ISD::SEXTLOAD:
2537 case ISD::ZEXTLOAD:
2538 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2539 case ISD::STORE:
2540 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2541 case ISD::ConstantPool:
2542 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2543 case ISD::GlobalAddress:
2544 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2545 case ISD::JumpTable:
2546 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2547 case ISD::Constant:
2548 return LowerConstant(Op, DAG);
2549 case ISD::ConstantFP:
2550 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002551 case ISD::BRCOND:
2552 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002553 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002554 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002555 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002556 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002557 case ISD::RET:
2558 return LowerRET(Op, DAG, getTargetMachine());
2559
Scott Michela59d4692008-02-23 18:41:37 +00002560
2561 // i8, i64 math ops:
2562 case ISD::ZERO_EXTEND:
2563 case ISD::SIGN_EXTEND:
2564 case ISD::ANY_EXTEND:
Scott Michel266bc8f2007-12-04 22:23:35 +00002565 case ISD::SUB:
2566 case ISD::ROTR:
2567 case ISD::ROTL:
2568 case ISD::SRL:
2569 case ISD::SHL:
2570 case ISD::SRA:
Scott Michela59d4692008-02-23 18:41:37 +00002571 if (VT == MVT::i8)
2572 return LowerI8Math(Op, DAG, Opc);
2573 else if (VT == MVT::i64)
2574 return LowerI64Math(Op, DAG, Opc);
2575 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00002576
2577 // Vector-related lowering.
2578 case ISD::BUILD_VECTOR:
2579 return LowerBUILD_VECTOR(Op, DAG);
2580 case ISD::SCALAR_TO_VECTOR:
2581 return LowerSCALAR_TO_VECTOR(Op, DAG);
2582 case ISD::VECTOR_SHUFFLE:
2583 return LowerVECTOR_SHUFFLE(Op, DAG);
2584 case ISD::EXTRACT_VECTOR_ELT:
2585 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2586 case ISD::INSERT_VECTOR_ELT:
2587 return LowerINSERT_VECTOR_ELT(Op, DAG);
2588
2589 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2590 case ISD::AND:
2591 case ISD::OR:
2592 case ISD::XOR:
2593 return LowerByteImmed(Op, DAG);
2594
2595 // Vector and i8 multiply:
2596 case ISD::MUL:
Scott Michela59d4692008-02-23 18:41:37 +00002597 if (MVT::isVector(VT))
Scott Michel266bc8f2007-12-04 22:23:35 +00002598 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002599 else if (VT == MVT::i8)
2600 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002601 else
Scott Michela59d4692008-02-23 18:41:37 +00002602 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002603
2604 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002605 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002606 return LowerFDIVf32(Op, DAG);
2607// else if (Op.getValueType() == MVT::f64)
2608// return LowerFDIVf64(Op, DAG);
2609 else
2610 assert(0 && "Calling FDIV on unsupported MVT");
2611
2612 case ISD::CTPOP:
2613 return LowerCTPOP(Op, DAG);
2614 }
2615
2616 return SDOperand();
2617}
2618
2619//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002620// Target Optimization Hooks
2621//===----------------------------------------------------------------------===//
2622
2623SDOperand
2624SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2625{
2626#if 0
2627 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002628#endif
2629 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002630 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002631 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2632 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002633
2634 switch (N->getOpcode()) {
2635 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002636 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002637 SDOperand Op1 = N->getOperand(1);
2638
2639 if ((Op1.getOpcode() == ISD::Constant
2640 || Op1.getOpcode() == ISD::TargetConstant)
2641 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2642 SDOperand Op01 = Op0.getOperand(1);
2643 if (Op01.getOpcode() == ISD::Constant
2644 || Op01.getOpcode() == ISD::TargetConstant) {
2645 // (add <const>, (SPUindirect <arg>, <const>)) ->
2646 // (SPUindirect <arg>, <const + const>)
2647 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2648 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2649 SDOperand combinedConst =
2650 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2651 Op0.getValueType());
2652
2653 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2654 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2655 DEBUG(cerr << "With: (SPUindirect <arg>, "
2656 << CN0->getValue() + CN1->getValue() << ")\n");
2657 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2658 Op0.getOperand(0), combinedConst);
2659 }
2660 } else if ((Op0.getOpcode() == ISD::Constant
2661 || Op0.getOpcode() == ISD::TargetConstant)
2662 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2663 SDOperand Op11 = Op1.getOperand(1);
2664 if (Op11.getOpcode() == ISD::Constant
2665 || Op11.getOpcode() == ISD::TargetConstant) {
2666 // (add (SPUindirect <arg>, <const>), <const>) ->
2667 // (SPUindirect <arg>, <const + const>)
2668 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2669 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2670 SDOperand combinedConst =
2671 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2672 Op0.getValueType());
2673
2674 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2675 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2676 DEBUG(cerr << "With: (SPUindirect <arg>, "
2677 << CN0->getValue() + CN1->getValue() << ")\n");
2678
2679 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2680 Op1.getOperand(0), combinedConst);
2681 }
2682 }
Scott Michela59d4692008-02-23 18:41:37 +00002683 break;
2684 }
2685 case ISD::SIGN_EXTEND:
2686 case ISD::ZERO_EXTEND:
2687 case ISD::ANY_EXTEND: {
2688 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2689 N->getValueType(0) == Op0.getValueType()) {
2690 // (any_extend (SPUextract_elt0 <arg>)) ->
2691 // (SPUextract_elt0 <arg>)
2692 // Types must match, however...
2693 DEBUG(cerr << "Replace: ");
2694 DEBUG(N->dump(&DAG));
2695 DEBUG(cerr << "\nWith: ");
2696 DEBUG(Op0.Val->dump(&DAG));
2697 DEBUG(cerr << "\n");
2698
2699 return Op0;
2700 }
2701 break;
2702 }
2703 case SPUISD::IndirectAddr: {
2704 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2705 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2706 if (CN->getValue() == 0) {
2707 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2708 // (SPUaform <addr>, 0)
2709
2710 DEBUG(cerr << "Replace: ");
2711 DEBUG(N->dump(&DAG));
2712 DEBUG(cerr << "\nWith: ");
2713 DEBUG(Op0.Val->dump(&DAG));
2714 DEBUG(cerr << "\n");
2715
2716 return Op0;
2717 }
2718 }
2719 break;
2720 }
2721 case SPUISD::SHLQUAD_L_BITS:
2722 case SPUISD::SHLQUAD_L_BYTES:
2723 case SPUISD::VEC_SHL:
2724 case SPUISD::VEC_SRL:
2725 case SPUISD::VEC_SRA:
2726 case SPUISD::ROTQUAD_RZ_BYTES:
2727 case SPUISD::ROTQUAD_RZ_BITS: {
2728 SDOperand Op1 = N->getOperand(1);
2729
2730 if (isa<ConstantSDNode>(Op1)) {
2731 // Kill degenerate vector shifts:
2732 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2733
2734 if (CN->getValue() == 0) {
2735 Result = Op0;
2736 }
2737 }
2738 break;
2739 }
2740 case SPUISD::PROMOTE_SCALAR: {
2741 switch (Op0.getOpcode()) {
2742 default:
2743 break;
2744 case ISD::ANY_EXTEND:
2745 case ISD::ZERO_EXTEND:
2746 case ISD::SIGN_EXTEND: {
2747 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2748 // <arg>
2749 // but only if the SPUpromote_scalar and <arg> types match.
2750 SDOperand Op00 = Op0.getOperand(0);
2751 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2752 SDOperand Op000 = Op00.getOperand(0);
2753 if (Op000.getValueType() == N->getValueType(0)) {
2754 Result = Op000;
2755 }
2756 }
2757 break;
2758 }
2759 case SPUISD::EXTRACT_ELT0: {
2760 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2761 // <arg>
2762 Result = Op0.getOperand(0);
2763 break;
2764 }
2765 }
2766 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002767 }
2768 }
Scott Michel58c58182008-01-17 20:38:41 +00002769 // Otherwise, return unchanged.
Scott Michela59d4692008-02-23 18:41:37 +00002770#if 0
2771 if (Result.Val) {
2772 DEBUG(cerr << "\nReplace.SPU: ");
2773 DEBUG(N->dump(&DAG));
2774 DEBUG(cerr << "\nWith: ");
2775 DEBUG(Result.Val->dump(&DAG));
2776 DEBUG(cerr << "\n");
2777 }
2778#endif
2779
2780 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002781}
2782
2783//===----------------------------------------------------------------------===//
2784// Inline Assembly Support
2785//===----------------------------------------------------------------------===//
2786
2787/// getConstraintType - Given a constraint letter, return the type of
2788/// constraint it is for this target.
2789SPUTargetLowering::ConstraintType
2790SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2791 if (ConstraintLetter.size() == 1) {
2792 switch (ConstraintLetter[0]) {
2793 default: break;
2794 case 'b':
2795 case 'r':
2796 case 'f':
2797 case 'v':
2798 case 'y':
2799 return C_RegisterClass;
2800 }
2801 }
2802 return TargetLowering::getConstraintType(ConstraintLetter);
2803}
2804
2805std::pair<unsigned, const TargetRegisterClass*>
2806SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2807 MVT::ValueType VT) const
2808{
2809 if (Constraint.size() == 1) {
2810 // GCC RS6000 Constraint Letters
2811 switch (Constraint[0]) {
2812 case 'b': // R1-R31
2813 case 'r': // R0-R31
2814 if (VT == MVT::i64)
2815 return std::make_pair(0U, SPU::R64CRegisterClass);
2816 return std::make_pair(0U, SPU::R32CRegisterClass);
2817 case 'f':
2818 if (VT == MVT::f32)
2819 return std::make_pair(0U, SPU::R32FPRegisterClass);
2820 else if (VT == MVT::f64)
2821 return std::make_pair(0U, SPU::R64FPRegisterClass);
2822 break;
2823 case 'v':
2824 return std::make_pair(0U, SPU::GPRCRegisterClass);
2825 }
2826 }
2827
2828 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2829}
2830
Scott Michela59d4692008-02-23 18:41:37 +00002831//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002832void
2833SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002834 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002835 APInt &KnownZero,
2836 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002837 const SelectionDAG &DAG,
2838 unsigned Depth ) const {
Scott Michela59d4692008-02-23 18:41:37 +00002839 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2840
2841 switch (Op.getOpcode()) {
2842 default:
2843 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2844 break;
2845
2846#if 0
2847 case CALL:
2848 case SHUFB:
2849 case INSERT_MASK:
2850 case CNTB:
2851#endif
2852
2853 case SPUISD::PROMOTE_SCALAR: {
2854 SDOperand Op0 = Op.getOperand(0);
2855 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2856 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2857 KnownOne |= APInt(uint64_sizebits, InMask, false);
2858 break;
2859 }
2860
2861 case SPUISD::LDRESULT:
2862 case SPUISD::EXTRACT_ELT0:
2863 case SPUISD::EXTRACT_ELT0_CHAINED: {
2864 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2865 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2866 KnownOne |= APInt(uint64_sizebits, InMask, false);
2867 break;
2868 }
2869
2870#if 0
2871 case EXTRACT_I1_ZEXT:
2872 case EXTRACT_I1_SEXT:
2873 case EXTRACT_I8_ZEXT:
2874 case EXTRACT_I8_SEXT:
2875 case MPY:
2876 case MPYU:
2877 case MPYH:
2878 case MPYHH:
2879 case SHLQUAD_L_BITS:
2880 case SHLQUAD_L_BYTES:
2881 case VEC_SHL:
2882 case VEC_SRL:
2883 case VEC_SRA:
2884 case VEC_ROTL:
2885 case VEC_ROTR:
2886 case ROTQUAD_RZ_BYTES:
2887 case ROTQUAD_RZ_BITS:
2888 case ROTBYTES_RIGHT_S:
2889 case ROTBYTES_LEFT:
2890 case ROTBYTES_LEFT_CHAINED:
2891 case FSMBI:
2892 case SELB:
2893 case SFPConstant:
2894 case FPInterp:
2895 case FPRecipEst:
2896 case SEXT32TO64:
2897#endif
2898 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002899}
2900
2901// LowerAsmOperandForConstraint
2902void
2903SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2904 char ConstraintLetter,
2905 std::vector<SDOperand> &Ops,
2906 SelectionDAG &DAG) {
2907 // Default, for the time being, to the base class handler
2908 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2909}
2910
2911/// isLegalAddressImmediate - Return true if the integer value can be used
2912/// as the offset of the target addressing mode.
2913bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2914 // SPU's addresses are 256K:
2915 return (V > -(1 << 18) && V < (1 << 18) - 1);
2916}
2917
2918bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2919 return false;
2920}