blob: 0a736d7203502e598d7d20a6f785fbc46cd7e3ab [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"
Scott Michel203b2d62008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000018#include "llvm/ADT/VectorExtras.h"
19#include "llvm/Analysis/ScalarEvolutionExpressions.h"
20#include "llvm/CodeGen/CallingConvLower.h"
21#include "llvm/CodeGen/MachineFrameInfo.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000026#include "llvm/Constants.h"
27#include "llvm/Function.h"
28#include "llvm/Intrinsics.h"
29#include "llvm/Support/Debug.h"
30#include "llvm/Support/MathExtras.h"
31#include "llvm/Target/TargetOptions.h"
32
33#include <map>
34
35using namespace llvm;
36
37// Used in getTargetNodeName() below
38namespace {
39 std::map<unsigned, const char *> node_names;
40
41 //! MVT::ValueType mapping to useful data for Cell SPU
42 struct valtype_map_s {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000043 const MVT::ValueType valtype;
44 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000045 };
46
47 const valtype_map_s valtype_map[] = {
48 { MVT::i1, 3 },
49 { MVT::i8, 3 },
50 { MVT::i16, 2 },
51 { MVT::i32, 0 },
52 { MVT::f32, 0 },
53 { MVT::i64, 0 },
54 { MVT::f64, 0 },
55 { MVT::i128, 0 }
56 };
57
58 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
59
60 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) {
61 const valtype_map_s *retval = 0;
62
63 for (size_t i = 0; i < n_valtype_map; ++i) {
64 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000065 retval = valtype_map + i;
66 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000067 }
68 }
69
70#ifndef NDEBUG
71 if (retval == 0) {
72 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel7f9ba9b2008-01-30 02:55:46 +000073 << MVT::getValueTypeString(VT)
74 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000075 abort();
76 }
77#endif
78
79 return retval;
80 }
81
82 //! Predicate that returns true if operand is a memory target
83 /*!
84 \arg Op Operand to test
85 \return true if the operand is a memory target (i.e., global
Scott Michel9de5d0d2008-01-11 02:53:15 +000086 address, external symbol, constant pool) or an A-form
Scott Michel266bc8f2007-12-04 22:23:35 +000087 address.
88 */
89 bool isMemoryOperand(const SDOperand &Op)
90 {
91 const unsigned Opc = Op.getOpcode();
92 return (Opc == ISD::GlobalAddress
93 || Opc == ISD::GlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000094 || Opc == ISD::JumpTable
95 || Opc == ISD::ConstantPool
96 || Opc == ISD::ExternalSymbol
97 || Opc == ISD::TargetGlobalAddress
98 || Opc == ISD::TargetGlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000099 || Opc == ISD::TargetJumpTable
100 || Opc == ISD::TargetConstantPool
101 || Opc == ISD::TargetExternalSymbol
Scott Michel9de5d0d2008-01-11 02:53:15 +0000102 || Opc == SPUISD::AFormAddr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000103 }
Scott Michel58c58182008-01-17 20:38:41 +0000104
105 //! Predicate that returns true if the operand is an indirect target
106 bool isIndirectOperand(const SDOperand &Op)
107 {
108 const unsigned Opc = Op.getOpcode();
109 return (Opc == ISD::Register
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000110 || Opc == SPUISD::LDRESULT);
Scott Michel58c58182008-01-17 20:38:41 +0000111 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000112}
113
114SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
115 : TargetLowering(TM),
116 SPUTM(TM)
117{
118 // Fold away setcc operations if possible.
119 setPow2DivIsCheap();
120
121 // Use _setjmp/_longjmp instead of setjmp/longjmp.
122 setUseUnderscoreSetJmp(true);
123 setUseUnderscoreLongJmp(true);
124
125 // Set up the SPU's register classes:
Scott Michel504c3692007-12-17 22:32:34 +0000126 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
127 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
128 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
129 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
130 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
131 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000132 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
133
134 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000135 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000136 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
137 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000138 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
139 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
140 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
142 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000143
144 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
145 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
146 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000147 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
148 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
149 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
151 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
152
Scott Michel266bc8f2007-12-04 22:23:35 +0000153 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
154 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
155 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
156
157 // SPU constant load actions are custom lowered:
158 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000159 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000160 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
161
162 // SPU's loads and stores have to be custom lowered:
163 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
164 ++sctype) {
165 setOperationAction(ISD::LOAD, sctype, Custom);
166 setOperationAction(ISD::STORE, sctype, Custom);
167 }
168
Scott Michel58c58182008-01-17 20:38:41 +0000169 // Custom lower BRCOND for i1, i8 to "promote" the result to
170 // i32 and i16, respectively.
171 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000172
173 // Expand the jumptable branches
174 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
175 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
176 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
177
178 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000179 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
180
Scott Michel266bc8f2007-12-04 22:23:35 +0000181 // PowerPC has no SREM/UREM instructions
182 setOperationAction(ISD::SREM, MVT::i32, Expand);
183 setOperationAction(ISD::UREM, MVT::i32, Expand);
184 setOperationAction(ISD::SREM, MVT::i64, Expand);
185 setOperationAction(ISD::UREM, MVT::i64, Expand);
186
187 // We don't support sin/cos/sqrt/fmod
188 setOperationAction(ISD::FSIN , MVT::f64, Expand);
189 setOperationAction(ISD::FCOS , MVT::f64, Expand);
190 setOperationAction(ISD::FREM , MVT::f64, Expand);
191 setOperationAction(ISD::FSIN , MVT::f32, Expand);
192 setOperationAction(ISD::FCOS , MVT::f32, Expand);
193 setOperationAction(ISD::FREM , MVT::f32, Expand);
194
195 // If we're enabling GP optimizations, use hardware square root
196 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
197 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
198
199 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
200 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
201
202 // SPU can do rotate right and left, so legalize it... but customize for i8
203 // because instructions don't exist.
204 setOperationAction(ISD::ROTR, MVT::i32, Legal);
205 setOperationAction(ISD::ROTR, MVT::i16, Legal);
206 setOperationAction(ISD::ROTR, MVT::i8, Custom);
207 setOperationAction(ISD::ROTL, MVT::i32, Legal);
208 setOperationAction(ISD::ROTL, MVT::i16, Legal);
209 setOperationAction(ISD::ROTL, MVT::i8, Custom);
210 // SPU has no native version of shift left/right for i8
211 setOperationAction(ISD::SHL, MVT::i8, Custom);
212 setOperationAction(ISD::SRL, MVT::i8, Custom);
213 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000214 // And SPU needs custom lowering for shift left/right for i64
215 setOperationAction(ISD::SHL, MVT::i64, Custom);
216 setOperationAction(ISD::SRL, MVT::i64, Custom);
217 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000218
219 // Custom lower i32 multiplications
220 setOperationAction(ISD::MUL, MVT::i32, Custom);
221
Scott Michel8bf61e82008-06-02 22:18:03 +0000222 // Need to custom handle (some) common i8, i64 math ops
223 setOperationAction(ISD::ADD, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000224 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel8bf61e82008-06-02 22:18:03 +0000225 setOperationAction(ISD::SUB, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000226 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 Michel8bf61e82008-06-02 22:18:03 +0000243 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000244 // 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";
Scott Michel8bf61e82008-06-02 22:18:03 +0000432 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
433 "SPUISD::ROTBYTES_LEFT_BITS";
434 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000435 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel8bf61e82008-06-02 22:18:03 +0000436 node_names[(unsigned) SPUISD::ADD_EXTENDED] = "SPUISD::ADD_EXTENDED";
437 node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
438 node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
439 node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
Scott Michel266bc8f2007-12-04 22:23:35 +0000440 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
441 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
442 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
443 }
444
445 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
446
447 return ((i != node_names.end()) ? i->second : 0);
448}
449
Scott Michel78c47fa2008-03-10 16:58:52 +0000450MVT::ValueType
451SPUTargetLowering::getSetCCResultType(const SDOperand &Op) const {
Scott Michel405fba12008-03-10 23:49:09 +0000452 MVT::ValueType VT = Op.getValueType();
453 if (MVT::isInteger(VT))
454 return VT;
455 else
456 return MVT::i32;
Scott Michel78c47fa2008-03-10 16:58:52 +0000457}
458
Scott Michel266bc8f2007-12-04 22:23:35 +0000459//===----------------------------------------------------------------------===//
460// Calling convention code:
461//===----------------------------------------------------------------------===//
462
463#include "SPUGenCallingConv.inc"
464
465//===----------------------------------------------------------------------===//
466// LowerOperation implementation
467//===----------------------------------------------------------------------===//
468
Scott Michel9de5d0d2008-01-11 02:53:15 +0000469/// Aligned load common code for CellSPU
470/*!
471 \param[in] Op The SelectionDAG load or store operand
472 \param[in] DAG The selection DAG
473 \param[in] ST CellSPU subtarget information structure
474 \param[in,out] alignment Caller initializes this to the load or store node's
475 value from getAlignment(), may be updated while generating the aligned load
476 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
477 offset (divisible by 16, modulo 16 == 0)
478 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
479 offset of the preferred slot (modulo 16 != 0)
480 \param[in,out] VT Caller initializes this value type to the the load or store
481 node's loaded or stored value type; may be updated if an i1-extended load or
482 store.
483 \param[out] was16aligned true if the base pointer had 16-byte alignment,
484 otherwise false. Can help to determine if the chunk needs to be rotated.
485
486 Both load and store lowering load a block of data aligned on a 16-byte
487 boundary. This is the common aligned load code shared between both.
488 */
489static SDOperand
490AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
491 LSBaseSDNode *LSN,
492 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000493 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000494{
495 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
496 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
497 SDOperand basePtr = LSN->getBasePtr();
498 SDOperand chain = LSN->getChain();
499
500 if (basePtr.getOpcode() == ISD::ADD) {
501 SDOperand Op1 = basePtr.Val->getOperand(1);
502
503 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000504 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000505
506 alignOffs = (int) CN->getValue();
507 prefSlotOffs = (int) (alignOffs & 0xf);
508
509 // Adjust the rotation amount to ensure that the final result ends up in
510 // the preferred slot:
511 prefSlotOffs -= vtm->prefslot_byte;
512 basePtr = basePtr.getOperand(0);
513
Scott Michel58c58182008-01-17 20:38:41 +0000514 // Loading from memory, can we adjust alignment?
515 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
516 SDOperand APtr = basePtr.getOperand(0);
517 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
518 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
519 alignment = GSDN->getGlobal()->getAlignment();
520 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000521 }
522 } else {
523 alignOffs = 0;
524 prefSlotOffs = -vtm->prefslot_byte;
525 }
Scott Michel203b2d62008-04-30 00:30:08 +0000526 } else if (basePtr.getOpcode() == ISD::FrameIndex) {
527 FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(basePtr);
528 alignOffs = int(FIN->getIndex() * SPUFrameInfo::stackSlotSize());
529 prefSlotOffs = (int) (alignOffs & 0xf);
530 prefSlotOffs -= vtm->prefslot_byte;
531 basePtr = DAG.getRegister(SPU::R1, VT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000532 } else {
533 alignOffs = 0;
534 prefSlotOffs = -vtm->prefslot_byte;
535 }
536
537 if (alignment == 16) {
538 // Realign the base pointer as a D-Form address:
539 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000540 basePtr = DAG.getNode(ISD::ADD, PtrVT,
541 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000542 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000543 }
544
545 // Emit the vector load:
546 was16aligned = true;
547 return DAG.getLoad(MVT::v16i8, chain, basePtr,
548 LSN->getSrcValue(), LSN->getSrcValueOffset(),
549 LSN->isVolatile(), 16);
550 }
551
552 // Unaligned load or we're using the "large memory" model, which means that
553 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000554 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000555 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000556 }
557
558 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000559 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000560 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000561 was16aligned = false;
562 return DAG.getLoad(MVT::v16i8, chain, basePtr,
563 LSN->getSrcValue(), LSN->getSrcValueOffset(),
564 LSN->isVolatile(), 16);
565}
566
Scott Michel266bc8f2007-12-04 22:23:35 +0000567/// Custom lower loads for CellSPU
568/*!
569 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
570 within a 16-byte block, we have to rotate to extract the requested element.
571 */
572static SDOperand
573LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
574 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000575 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000576 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000577 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000578 ISD::LoadExtType ExtType = LN->getExtensionType();
579 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000580 SDOperand Ops[8];
581
Scott Michel266bc8f2007-12-04 22:23:35 +0000582 switch (LN->getAddressingMode()) {
583 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000584 int offset, rotamt;
585 bool was16aligned;
586 SDOperand result =
587 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000588
Scott Michel9de5d0d2008-01-11 02:53:15 +0000589 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000590 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000591
592 the_chain = result.getValue(1);
593 // Rotate the chunk if necessary
594 if (rotamt < 0)
595 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000596 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000597 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
598
Scott Michel58c58182008-01-17 20:38:41 +0000599 Ops[0] = the_chain;
600 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000601 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000602 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
603 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000604 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000605 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000606 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000607 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000608 }
609
610 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
611 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000612 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000613
614 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
615 SDVTList scalarvts;
616 MVT::ValueType vecVT = MVT::v16i8;
617
618 // Convert the loaded v16i8 vector to the appropriate vector type
619 // specified by the operand:
620 if (OpVT == VT) {
621 if (VT != MVT::i1)
622 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
623 } else
624 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
625
626 Ops[0] = the_chain;
627 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
628 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
629 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
630 the_chain = result.getValue(1);
631 } else {
632 // Handle the sign and zero-extending loads for i1 and i8:
633 unsigned NewOpC;
634
635 if (ExtType == ISD::SEXTLOAD) {
636 NewOpC = (OpVT == MVT::i1
637 ? SPUISD::EXTRACT_I1_SEXT
638 : SPUISD::EXTRACT_I8_SEXT);
639 } else {
640 assert(ExtType == ISD::ZEXTLOAD);
641 NewOpC = (OpVT == MVT::i1
642 ? SPUISD::EXTRACT_I1_ZEXT
643 : SPUISD::EXTRACT_I8_ZEXT);
644 }
645
646 result = DAG.getNode(NewOpC, OpVT, result);
647 }
648
649 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000650 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000651 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000652 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000653 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000654
Scott Michel58c58182008-01-17 20:38:41 +0000655 result = DAG.getNode(SPUISD::LDRESULT, retvts,
656 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000657 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000658 }
659 case ISD::PRE_INC:
660 case ISD::PRE_DEC:
661 case ISD::POST_INC:
662 case ISD::POST_DEC:
663 case ISD::LAST_INDEXED_MODE:
664 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
665 "UNINDEXED\n";
666 cerr << (unsigned) LN->getAddressingMode() << "\n";
667 abort();
668 /*NOTREACHED*/
669 }
670
671 return SDOperand();
672}
673
674/// Custom lower stores for CellSPU
675/*!
676 All CellSPU stores are aligned to 16-byte boundaries, so for elements
677 within a 16-byte block, we have to generate a shuffle to insert the
678 requested element into its place, then store the resulting block.
679 */
680static SDOperand
681LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
682 StoreSDNode *SN = cast<StoreSDNode>(Op);
683 SDOperand Value = SN->getValue();
684 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000685 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000686 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000687 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000688
689 switch (SN->getAddressingMode()) {
690 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000691 int chunk_offset, slot_offset;
692 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000693
694 // The vector type we really want to load from the 16-byte chunk, except
695 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000696 unsigned vecVT, stVecVT = MVT::v16i8;
697
Scott Michel266bc8f2007-12-04 22:23:35 +0000698 if (StVT != MVT::i1)
699 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000700 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
701
Scott Michel9de5d0d2008-01-11 02:53:15 +0000702 SDOperand alignLoadVec =
703 AlignedLoad(Op, DAG, ST, SN, alignment,
704 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000705
Scott Michel9de5d0d2008-01-11 02:53:15 +0000706 if (alignLoadVec.Val == 0)
707 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000708
Scott Michel9de5d0d2008-01-11 02:53:15 +0000709 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
710 SDOperand basePtr = LN->getBasePtr();
711 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000712 SDOperand theValue = SN->getValue();
713 SDOperand result;
714
715 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000716 && (theValue.getOpcode() == ISD::AssertZext
717 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000718 // Drill down and get the value for zero- and sign-extended
719 // quantities
720 theValue = theValue.getOperand(0);
721 }
722
Scott Michel9de5d0d2008-01-11 02:53:15 +0000723 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000724
Scott Michel9de5d0d2008-01-11 02:53:15 +0000725 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
726 SDOperand insertEltPtr;
727 SDOperand insertEltOp;
728
729 // If the base pointer is already a D-form address, then just create
730 // a new D-form address with a slot offset and the orignal base pointer.
731 // Otherwise generate a D-form address with the slot offset relative
732 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000733 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
734 DEBUG(basePtr.Val->dump(&DAG));
735 DEBUG(cerr << "\n");
736
Scott Michel053c1da2008-01-29 02:16:57 +0000737 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
738 (basePtr.getOpcode() == ISD::ADD
739 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000740 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000741 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000742 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000743 }
744
745 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000746 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000747 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
748 alignLoadVec,
749 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000750
Scott Michel9de5d0d2008-01-11 02:53:15 +0000751 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000752 LN->getSrcValue(), LN->getSrcValueOffset(),
753 LN->isVolatile(), LN->getAlignment());
754
755 return result;
756 /*UNREACHED*/
757 }
758 case ISD::PRE_INC:
759 case ISD::PRE_DEC:
760 case ISD::POST_INC:
761 case ISD::POST_DEC:
762 case ISD::LAST_INDEXED_MODE:
763 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
764 "UNINDEXED\n";
765 cerr << (unsigned) SN->getAddressingMode() << "\n";
766 abort();
767 /*NOTREACHED*/
768 }
769
770 return SDOperand();
771}
772
773/// Generate the address of a constant pool entry.
774static SDOperand
775LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
776 MVT::ValueType PtrVT = Op.getValueType();
777 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
778 Constant *C = CP->getConstVal();
779 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000780 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000781 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000782
783 if (TM.getRelocationModel() == Reloc::Static) {
784 if (!ST->usingLargeMem()) {
785 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000786 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000787 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000788 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
789 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000790 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000791 }
792 }
793
794 assert(0 &&
795 "LowerConstantPool: Relocation model other than static not supported.");
796 return SDOperand();
797}
798
799static SDOperand
800LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
801 MVT::ValueType PtrVT = Op.getValueType();
802 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
803 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
804 SDOperand Zero = DAG.getConstant(0, PtrVT);
805 const TargetMachine &TM = DAG.getTarget();
806
807 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000808 if (!ST->usingLargeMem()) {
809 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
810 } else {
811 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
812 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
813 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
814 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000815 }
816
817 assert(0 &&
818 "LowerJumpTable: Relocation model other than static not supported.");
819 return SDOperand();
820}
821
822static SDOperand
823LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
824 MVT::ValueType PtrVT = Op.getValueType();
825 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
826 GlobalValue *GV = GSDN->getGlobal();
827 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000828 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000829 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000830
831 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000832 if (!ST->usingLargeMem()) {
833 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
834 } else {
835 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
836 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
837 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
838 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000839 } else {
840 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000841 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000842 abort();
843 /*NOTREACHED*/
844 }
845
846 return SDOperand();
847}
848
849//! Custom lower i64 integer constants
850/*!
851 This code inserts all of the necessary juggling that needs to occur to load
852 a 64-bit constant into a register.
853 */
854static SDOperand
855LowerConstant(SDOperand Op, SelectionDAG &DAG) {
856 unsigned VT = Op.getValueType();
857 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
858
859 if (VT == MVT::i64) {
860 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
861 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000862 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000863 } else {
864 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000865 << MVT::getValueTypeString(VT)
866 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000867 abort();
868 /*NOTREACHED*/
869 }
870
871 return SDOperand();
872}
873
Nate Begemanccef5802008-02-14 18:43:04 +0000874//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000875static SDOperand
876LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
877 unsigned VT = Op.getValueType();
878 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
879
880 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000881 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000882
Nate Begemanccef5802008-02-14 18:43:04 +0000883 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000884 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000885 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000886 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000887 }
888
889 return SDOperand();
890}
891
Scott Michel58c58182008-01-17 20:38:41 +0000892//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
893static SDOperand
894LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
895{
896 SDOperand Cond = Op.getOperand(1);
897 MVT::ValueType CondVT = Cond.getValueType();
898 MVT::ValueType CondNVT;
899
900 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
901 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
902 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
903 Op.getOperand(0),
904 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
905 Op.getOperand(2));
906 } else
907 return SDOperand(); // Unchanged
908}
909
Scott Michel266bc8f2007-12-04 22:23:35 +0000910static SDOperand
911LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
912{
913 MachineFunction &MF = DAG.getMachineFunction();
914 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000915 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000916 SmallVector<SDOperand, 8> ArgValues;
917 SDOperand Root = Op.getOperand(0);
918 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
919
920 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
921 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
922
923 unsigned ArgOffset = SPUFrameInfo::minStackSize();
924 unsigned ArgRegIdx = 0;
925 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
926
927 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
928
929 // Add DAG nodes to load the arguments or copy them out of registers.
930 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
931 SDOperand ArgVal;
932 bool needsLoad = false;
933 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
934 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
935
936 switch (ObjectVT) {
937 default: {
938 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000939 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000940 << "\n";
941 abort();
942 }
943 case MVT::i8:
944 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000945 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
946 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000947 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
948 ++ArgRegIdx;
949 } else {
950 needsLoad = true;
951 }
952 break;
953 case MVT::i16:
954 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000955 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
956 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000957 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
958 ++ArgRegIdx;
959 } else {
960 needsLoad = true;
961 }
962 break;
963 case MVT::i32:
964 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000965 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
966 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000967 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
968 ++ArgRegIdx;
969 } else {
970 needsLoad = true;
971 }
972 break;
973 case MVT::i64:
974 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000975 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
976 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000977 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
978 ++ArgRegIdx;
979 } else {
980 needsLoad = true;
981 }
982 break;
983 case MVT::f32:
984 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000985 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
986 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000987 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
988 ++ArgRegIdx;
989 } else {
990 needsLoad = true;
991 }
992 break;
993 case MVT::f64:
994 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000995 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
996 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000997 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
998 ++ArgRegIdx;
999 } else {
1000 needsLoad = true;
1001 }
1002 break;
1003 case MVT::v2f64:
1004 case MVT::v4f32:
Scott Michelad2715e2008-03-05 23:02:02 +00001005 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001006 case MVT::v4i32:
1007 case MVT::v8i16:
1008 case MVT::v16i8:
1009 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001010 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1011 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001012 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
1013 ++ArgRegIdx;
1014 } else {
1015 needsLoad = true;
1016 }
1017 break;
1018 }
1019
1020 // We need to load the argument to a virtual register if we determined above
1021 // that we ran out of physical registers of the appropriate type
1022 if (needsLoad) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001023 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1024 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1025 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001026 ArgOffset += StackSlotSize;
1027 }
1028
1029 ArgValues.push_back(ArgVal);
1030 }
1031
1032 // If the function takes variable number of arguments, make a frame index for
1033 // the start of the first vararg value... for expansion of llvm.va_start.
1034 if (isVarArg) {
1035 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1036 ArgOffset);
1037 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1038 // If this function is vararg, store any remaining integer argument regs to
1039 // their spots on the stack so that they may be loaded by deferencing the
1040 // result of va_next.
1041 SmallVector<SDOperand, 8> MemOps;
1042 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001043 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1044 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001045 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1046 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1047 MemOps.push_back(Store);
1048 // Increment the address by four for the next argument to store
1049 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1050 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1051 }
1052 if (!MemOps.empty())
1053 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1054 }
1055
1056 ArgValues.push_back(Root);
1057
1058 // Return the new list of results.
1059 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1060 Op.Val->value_end());
1061 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1062}
1063
1064/// isLSAAddress - Return the immediate to use if the specified
1065/// value is representable as a LSA address.
1066static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1067 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1068 if (!C) return 0;
1069
1070 int Addr = C->getValue();
1071 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1072 (Addr << 14 >> 14) != Addr)
1073 return 0; // Top 14 bits have to be sext of immediate.
1074
1075 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1076}
1077
1078static
1079SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001080LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001081 SDOperand Chain = Op.getOperand(0);
1082#if 0
1083 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1084 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1085#endif
1086 SDOperand Callee = Op.getOperand(4);
1087 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1088 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1089 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1090 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1091
1092 // Handy pointer type
1093 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1094
1095 // Accumulate how many bytes are to be pushed on the stack, including the
1096 // linkage area, and parameter passing area. According to the SPU ABI,
1097 // we minimally need space for [LR] and [SP]
1098 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1099
1100 // Set up a copy of the stack pointer for use loading and storing any
1101 // arguments that may not fit in the registers available for argument
1102 // passing.
1103 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1104
1105 // Figure out which arguments are going to go in registers, and which in
1106 // memory.
1107 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1108 unsigned ArgRegIdx = 0;
1109
1110 // Keep track of registers passing arguments
1111 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1112 // And the arguments passed on the stack
1113 SmallVector<SDOperand, 8> MemOpChains;
1114
1115 for (unsigned i = 0; i != NumOps; ++i) {
1116 SDOperand Arg = Op.getOperand(5+2*i);
1117
1118 // PtrOff will be used to store the current argument to the stack if a
1119 // register cannot be found for it.
1120 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1121 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1122
1123 switch (Arg.getValueType()) {
1124 default: assert(0 && "Unexpected ValueType for argument!");
1125 case MVT::i32:
1126 case MVT::i64:
1127 case MVT::i128:
1128 if (ArgRegIdx != NumArgRegs) {
1129 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1130 } else {
1131 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001132 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001133 }
1134 break;
1135 case MVT::f32:
1136 case MVT::f64:
1137 if (ArgRegIdx != NumArgRegs) {
1138 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1139 } else {
1140 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001141 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001142 }
1143 break;
1144 case MVT::v4f32:
1145 case MVT::v4i32:
1146 case MVT::v8i16:
1147 case MVT::v16i8:
1148 if (ArgRegIdx != NumArgRegs) {
1149 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1150 } else {
1151 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001152 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001153 }
1154 break;
1155 }
1156 }
1157
1158 // Update number of stack bytes actually used, insert a call sequence start
1159 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1160 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1161
1162 if (!MemOpChains.empty()) {
1163 // Adjust the stack pointer for the stack arguments.
1164 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1165 &MemOpChains[0], MemOpChains.size());
1166 }
1167
1168 // Build a sequence of copy-to-reg nodes chained together with token chain
1169 // and flag operands which copy the outgoing args into the appropriate regs.
1170 SDOperand InFlag;
1171 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1172 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1173 InFlag);
1174 InFlag = Chain.getValue(1);
1175 }
1176
1177 std::vector<MVT::ValueType> NodeTys;
1178 NodeTys.push_back(MVT::Other); // Returns a chain
1179 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1180
1181 SmallVector<SDOperand, 8> Ops;
1182 unsigned CallOpc = SPUISD::CALL;
1183
1184 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1185 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1186 // node so that legalize doesn't hack it.
1187 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1188 GlobalValue *GV = G->getGlobal();
1189 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001190 SDOperand Zero = DAG.getConstant(0, PtrVT);
1191 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001192
Scott Michel9de5d0d2008-01-11 02:53:15 +00001193 if (!ST->usingLargeMem()) {
1194 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1195 // style calls, otherwise, external symbols are BRASL calls. This assumes
1196 // that declared/defined symbols are in the same compilation unit and can
1197 // be reached through PC-relative jumps.
1198 //
1199 // NOTE:
1200 // This may be an unsafe assumption for JIT and really large compilation
1201 // units.
1202 if (GV->isDeclaration()) {
1203 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1204 } else {
1205 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1206 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001207 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001208 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1209 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001210 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001211 }
1212 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1213 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001214 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001215 // If this is an absolute destination address that appears to be a legal
1216 // local store address, use the munged value.
1217 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001218 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001219
1220 Ops.push_back(Chain);
1221 Ops.push_back(Callee);
1222
1223 // Add argument registers to the end of the list so that they are known live
1224 // into the call.
1225 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1226 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1227 RegsToPass[i].second.getValueType()));
1228
1229 if (InFlag.Val)
1230 Ops.push_back(InFlag);
1231 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1232 InFlag = Chain.getValue(1);
1233
Evan Chengebaaa912008-02-05 22:44:06 +00001234 Chain = DAG.getCALLSEQ_END(Chain,
1235 DAG.getConstant(NumStackBytes, PtrVT),
1236 DAG.getConstant(0, PtrVT),
1237 InFlag);
1238 if (Op.Val->getValueType(0) != MVT::Other)
1239 InFlag = Chain.getValue(1);
1240
Scott Michel266bc8f2007-12-04 22:23:35 +00001241 SDOperand ResultVals[3];
1242 unsigned NumResults = 0;
1243 NodeTys.clear();
1244
1245 // If the call has results, copy the values out of the ret val registers.
1246 switch (Op.Val->getValueType(0)) {
1247 default: assert(0 && "Unexpected ret value!");
1248 case MVT::Other: break;
1249 case MVT::i32:
1250 if (Op.Val->getValueType(1) == MVT::i32) {
1251 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1252 ResultVals[0] = Chain.getValue(0);
1253 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1254 Chain.getValue(2)).getValue(1);
1255 ResultVals[1] = Chain.getValue(0);
1256 NumResults = 2;
1257 NodeTys.push_back(MVT::i32);
1258 } else {
1259 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1260 ResultVals[0] = Chain.getValue(0);
1261 NumResults = 1;
1262 }
1263 NodeTys.push_back(MVT::i32);
1264 break;
1265 case MVT::i64:
1266 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1267 ResultVals[0] = Chain.getValue(0);
1268 NumResults = 1;
1269 NodeTys.push_back(MVT::i64);
1270 break;
1271 case MVT::f32:
1272 case MVT::f64:
1273 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1274 InFlag).getValue(1);
1275 ResultVals[0] = Chain.getValue(0);
1276 NumResults = 1;
1277 NodeTys.push_back(Op.Val->getValueType(0));
1278 break;
1279 case MVT::v2f64:
1280 case MVT::v4f32:
1281 case MVT::v4i32:
1282 case MVT::v8i16:
1283 case MVT::v16i8:
1284 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1285 InFlag).getValue(1);
1286 ResultVals[0] = Chain.getValue(0);
1287 NumResults = 1;
1288 NodeTys.push_back(Op.Val->getValueType(0));
1289 break;
1290 }
1291
Scott Michel266bc8f2007-12-04 22:23:35 +00001292 NodeTys.push_back(MVT::Other);
1293
1294 // If the function returns void, just return the chain.
1295 if (NumResults == 0)
1296 return Chain;
1297
1298 // Otherwise, merge everything together with a MERGE_VALUES node.
1299 ResultVals[NumResults++] = Chain;
1300 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1301 ResultVals, NumResults);
1302 return Res.getValue(Op.ResNo);
1303}
1304
1305static SDOperand
1306LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1307 SmallVector<CCValAssign, 16> RVLocs;
1308 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1309 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1310 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1311 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1312
1313 // If this is the first return lowered for this function, add the regs to the
1314 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001315 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001316 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001317 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001318 }
1319
1320 SDOperand Chain = Op.getOperand(0);
1321 SDOperand Flag;
1322
1323 // Copy the result values into the output registers.
1324 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1325 CCValAssign &VA = RVLocs[i];
1326 assert(VA.isRegLoc() && "Can only return in registers!");
1327 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1328 Flag = Chain.getValue(1);
1329 }
1330
1331 if (Flag.Val)
1332 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1333 else
1334 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1335}
1336
1337
1338//===----------------------------------------------------------------------===//
1339// Vector related lowering:
1340//===----------------------------------------------------------------------===//
1341
1342static ConstantSDNode *
1343getVecImm(SDNode *N) {
1344 SDOperand OpVal(0, 0);
1345
1346 // Check to see if this buildvec has a single non-undef value in its elements.
1347 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1348 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1349 if (OpVal.Val == 0)
1350 OpVal = N->getOperand(i);
1351 else if (OpVal != N->getOperand(i))
1352 return 0;
1353 }
1354
1355 if (OpVal.Val != 0) {
1356 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1357 return CN;
1358 }
1359 }
1360
1361 return 0; // All UNDEF: use implicit def.; not Constant node
1362}
1363
1364/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1365/// and the value fits into an unsigned 18-bit constant, and if so, return the
1366/// constant
1367SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1368 MVT::ValueType ValueType) {
1369 if (ConstantSDNode *CN = getVecImm(N)) {
1370 uint64_t Value = CN->getValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001371 if (ValueType == MVT::i64) {
1372 uint64_t UValue = CN->getValue();
1373 uint32_t upper = uint32_t(UValue >> 32);
1374 uint32_t lower = uint32_t(UValue);
1375 if (upper != lower)
1376 return SDOperand();
1377 Value = Value >> 32;
1378 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001379 if (Value <= 0x3ffff)
1380 return DAG.getConstant(Value, ValueType);
1381 }
1382
1383 return SDOperand();
1384}
1385
1386/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1387/// and the value fits into a signed 16-bit constant, and if so, return the
1388/// constant
1389SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1390 MVT::ValueType ValueType) {
1391 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001392 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001393 if (ValueType == MVT::i64) {
1394 uint64_t UValue = CN->getValue();
1395 uint32_t upper = uint32_t(UValue >> 32);
1396 uint32_t lower = uint32_t(UValue);
1397 if (upper != lower)
1398 return SDOperand();
1399 Value = Value >> 32;
1400 }
Scott Michelad2715e2008-03-05 23:02:02 +00001401 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1402 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001403 }
1404 }
1405
1406 return SDOperand();
1407}
1408
1409/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1410/// and the value fits into a signed 10-bit constant, and if so, return the
1411/// constant
1412SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1413 MVT::ValueType ValueType) {
1414 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001415 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001416 if (ValueType == MVT::i64) {
1417 uint64_t UValue = CN->getValue();
1418 uint32_t upper = uint32_t(UValue >> 32);
1419 uint32_t lower = uint32_t(UValue);
1420 if (upper != lower)
1421 return SDOperand();
1422 Value = Value >> 32;
1423 }
Scott Michelad2715e2008-03-05 23:02:02 +00001424 if (isS10Constant(Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001425 return DAG.getConstant(Value, ValueType);
1426 }
1427
1428 return SDOperand();
1429}
1430
1431/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1432/// and the value fits into a signed 8-bit constant, and if so, return the
1433/// constant.
1434///
1435/// @note: The incoming vector is v16i8 because that's the only way we can load
1436/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1437/// same value.
1438SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1439 MVT::ValueType ValueType) {
1440 if (ConstantSDNode *CN = getVecImm(N)) {
1441 int Value = (int) CN->getValue();
1442 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001443 && Value <= 0xffff /* truncated from uint64_t */
1444 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001445 return DAG.getConstant(Value & 0xff, ValueType);
1446 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001447 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001448 return DAG.getConstant(Value, ValueType);
1449 }
1450
1451 return SDOperand();
1452}
1453
1454/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1455/// and the value fits into a signed 16-bit constant, and if so, return the
1456/// constant
1457SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1458 MVT::ValueType ValueType) {
1459 if (ConstantSDNode *CN = getVecImm(N)) {
1460 uint64_t Value = CN->getValue();
1461 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001462 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1463 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001464 return DAG.getConstant(Value >> 16, ValueType);
1465 }
1466
1467 return SDOperand();
1468}
1469
1470/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1471SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1472 if (ConstantSDNode *CN = getVecImm(N)) {
1473 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1474 }
1475
1476 return SDOperand();
1477}
1478
1479/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1480SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1481 if (ConstantSDNode *CN = getVecImm(N)) {
1482 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1483 }
1484
1485 return SDOperand();
1486}
1487
1488// If this is a vector of constants or undefs, get the bits. A bit in
1489// UndefBits is set if the corresponding element of the vector is an
1490// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1491// zero. Return true if this is not an array of constants, false if it is.
1492//
1493static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1494 uint64_t UndefBits[2]) {
1495 // Start with zero'd results.
1496 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1497
1498 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1499 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1500 SDOperand OpVal = BV->getOperand(i);
1501
1502 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1503 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1504
1505 uint64_t EltBits = 0;
1506 if (OpVal.getOpcode() == ISD::UNDEF) {
1507 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1508 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1509 continue;
1510 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1511 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1512 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1513 const APFloat &apf = CN->getValueAPF();
1514 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001515 ? FloatToBits(apf.convertToFloat())
1516 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001517 } else {
1518 // Nonconstant element.
1519 return true;
1520 }
1521
1522 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1523 }
1524
1525 //printf("%llx %llx %llx %llx\n",
1526 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1527 return false;
1528}
1529
1530/// If this is a splat (repetition) of a value across the whole vector, return
1531/// the smallest size that splats it. For example, "0x01010101010101..." is a
1532/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1533/// SplatSize = 1 byte.
1534static bool isConstantSplat(const uint64_t Bits128[2],
1535 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001536 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001537 uint64_t &SplatBits, uint64_t &SplatUndef,
1538 int &SplatSize) {
1539 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1540 // the same as the lower 64-bits, ignoring undefs.
1541 uint64_t Bits64 = Bits128[0] | Bits128[1];
1542 uint64_t Undef64 = Undef128[0] & Undef128[1];
1543 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1544 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1545 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1546 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1547
1548 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1549 if (MinSplatBits < 64) {
1550
1551 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1552 // undefs.
1553 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001554 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001555
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001556 // If the top 16-bits are different than the lower 16-bits, ignoring
1557 // undefs, we have an i32 splat.
1558 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1559 if (MinSplatBits < 16) {
1560 // If the top 8-bits are different than the lower 8-bits, ignoring
1561 // undefs, we have an i16 splat.
1562 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1563 // Otherwise, we have an 8-bit splat.
1564 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1565 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1566 SplatSize = 1;
1567 return true;
1568 }
1569 } else {
1570 SplatBits = Bits16;
1571 SplatUndef = Undef16;
1572 SplatSize = 2;
1573 return true;
1574 }
1575 }
1576 } else {
1577 SplatBits = Bits32;
1578 SplatUndef = Undef32;
1579 SplatSize = 4;
1580 return true;
1581 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001582 }
1583 } else {
1584 SplatBits = Bits128[0];
1585 SplatUndef = Undef128[0];
1586 SplatSize = 8;
1587 return true;
1588 }
1589 }
1590
1591 return false; // Can't be a splat if two pieces don't match.
1592}
1593
1594// If this is a case we can't handle, return null and let the default
1595// expansion code take care of it. If we CAN select this case, and if it
1596// selects to a single instruction, return Op. Otherwise, if we can codegen
1597// this case more efficiently than a constant pool load, lower it to the
1598// sequence of ops that should be used.
1599static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1600 MVT::ValueType VT = Op.getValueType();
1601 // If this is a vector of constants or undefs, get the bits. A bit in
1602 // UndefBits is set if the corresponding element of the vector is an
1603 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1604 // zero.
1605 uint64_t VectorBits[2];
1606 uint64_t UndefBits[2];
1607 uint64_t SplatBits, SplatUndef;
1608 int SplatSize;
1609 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1610 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001611 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001612 SplatBits, SplatUndef, SplatSize))
1613 return SDOperand(); // Not a constant vector, not a splat.
1614
1615 switch (VT) {
1616 default:
1617 case MVT::v4f32: {
1618 uint32_t Value32 = SplatBits;
1619 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001620 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001621 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1622 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1623 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001624 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001625 break;
1626 }
1627 case MVT::v2f64: {
1628 uint64_t f64val = SplatBits;
1629 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001630 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001631 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1632 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1633 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001634 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001635 break;
1636 }
1637 case MVT::v16i8: {
1638 // 8-bit constants have to be expanded to 16-bits
1639 unsigned short Value16 = SplatBits | (SplatBits << 8);
1640 SDOperand Ops[8];
1641 for (int i = 0; i < 8; ++i)
1642 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1643 return DAG.getNode(ISD::BIT_CONVERT, VT,
1644 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1645 }
1646 case MVT::v8i16: {
1647 unsigned short Value16;
1648 if (SplatSize == 2)
1649 Value16 = (unsigned short) (SplatBits & 0xffff);
1650 else
1651 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1652 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1653 SDOperand Ops[8];
1654 for (int i = 0; i < 8; ++i) Ops[i] = T;
1655 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1656 }
1657 case MVT::v4i32: {
1658 unsigned int Value = SplatBits;
1659 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1660 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1661 }
1662 case MVT::v2i64: {
1663 uint64_t val = SplatBits;
1664 uint32_t upper = uint32_t(val >> 32);
1665 uint32_t lower = uint32_t(val);
1666
Scott Michel4cb8bd82008-03-06 04:02:54 +00001667 if (upper == lower) {
1668 // Magic constant that can be matched by IL, ILA, et. al.
1669 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1670 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michelad2715e2008-03-05 23:02:02 +00001671 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +00001672 SDOperand LO32;
1673 SDOperand HI32;
1674 SmallVector<SDOperand, 16> ShufBytes;
1675 SDOperand Result;
1676 bool upper_special, lower_special;
1677
1678 // NOTE: This code creates common-case shuffle masks that can be easily
1679 // detected as common expressions. It is not attempting to create highly
1680 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1681
1682 // Detect if the upper or lower half is a special shuffle mask pattern:
1683 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1684 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1685
1686 // Create lower vector if not a special pattern
1687 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001688 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1689 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1690 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1691 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001692 }
1693
1694 // Create upper vector if not a special pattern
1695 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001696 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1697 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1698 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1699 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001700 }
1701
1702 // If either upper or lower are special, then the two input operands are
1703 // the same (basically, one of them is a "don't care")
1704 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001705 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001706 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001707 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001708 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001709 // Unhappy situation... both upper and lower are special, so punt with
1710 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001711 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001712 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001713 Zero, Zero);
1714 }
1715
1716 for (int i = 0; i < 4; ++i) {
Scott Michel8bf61e82008-06-02 22:18:03 +00001717 uint64_t val = 0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001718 for (int j = 0; j < 4; ++j) {
1719 SDOperand V;
1720 bool process_upper, process_lower;
Scott Michel8bf61e82008-06-02 22:18:03 +00001721 val <<= 8;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001722 process_upper = (upper_special && (i & 1) == 0);
1723 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001724
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001725 if (process_upper || process_lower) {
1726 if ((process_upper && upper == 0)
1727 || (process_lower && lower == 0))
Scott Michel8bf61e82008-06-02 22:18:03 +00001728 val |= 0x80;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001729 else if ((process_upper && upper == 0xffffffff)
1730 || (process_lower && lower == 0xffffffff))
Scott Michel8bf61e82008-06-02 22:18:03 +00001731 val |= 0xc0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001732 else if ((process_upper && upper == 0x80000000)
1733 || (process_lower && lower == 0x80000000))
Scott Michel8bf61e82008-06-02 22:18:03 +00001734 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001735 } else
Scott Michel8bf61e82008-06-02 22:18:03 +00001736 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001737 }
Scott Michel8bf61e82008-06-02 22:18:03 +00001738
1739 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001740 }
1741
1742 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel8bf61e82008-06-02 22:18:03 +00001743 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001744 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001745 }
1746 }
1747 }
1748
1749 return SDOperand();
1750}
1751
1752/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1753/// which the Cell can operate. The code inspects V3 to ascertain whether the
1754/// permutation vector, V3, is monotonically increasing with one "exception"
1755/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1756/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1757/// In either case, the net result is going to eventually invoke SHUFB to
1758/// permute/shuffle the bytes from V1 and V2.
1759/// \note
1760/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1761/// control word for byte/halfword/word insertion. This takes care of a single
1762/// element move from V2 into V1.
1763/// \note
1764/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1765static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1766 SDOperand V1 = Op.getOperand(0);
1767 SDOperand V2 = Op.getOperand(1);
1768 SDOperand PermMask = Op.getOperand(2);
1769
1770 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1771
1772 // If we have a single element being moved from V1 to V2, this can be handled
1773 // using the C*[DX] compute mask instructions, but the vector elements have
1774 // to be monotonically increasing with one exception element.
1775 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1776 unsigned EltsFromV2 = 0;
1777 unsigned V2Elt = 0;
1778 unsigned V2EltIdx0 = 0;
1779 unsigned CurrElt = 0;
1780 bool monotonic = true;
1781 if (EltVT == MVT::i8)
1782 V2EltIdx0 = 16;
1783 else if (EltVT == MVT::i16)
1784 V2EltIdx0 = 8;
1785 else if (EltVT == MVT::i32)
1786 V2EltIdx0 = 4;
1787 else
1788 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1789
1790 for (unsigned i = 0, e = PermMask.getNumOperands();
1791 EltsFromV2 <= 1 && monotonic && i != e;
1792 ++i) {
1793 unsigned SrcElt;
1794 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1795 SrcElt = 0;
1796 else
1797 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1798
1799 if (SrcElt >= V2EltIdx0) {
1800 ++EltsFromV2;
1801 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1802 } else if (CurrElt != SrcElt) {
1803 monotonic = false;
1804 }
1805
1806 ++CurrElt;
1807 }
1808
1809 if (EltsFromV2 == 1 && monotonic) {
1810 // Compute mask and shuffle
1811 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001812 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1813 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001814 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1815 // Initialize temporary register to 0
1816 SDOperand InitTempReg =
1817 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1818 // Copy register's contents as index in INSERT_MASK:
1819 SDOperand ShufMaskOp =
1820 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001821 DAG.getTargetConstant(V2Elt, MVT::i32),
1822 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001823 // Use shuffle mask in SHUFB synthetic instruction:
1824 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1825 } else {
1826 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1827 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1828
1829 SmallVector<SDOperand, 16> ResultMask;
1830 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1831 unsigned SrcElt;
1832 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001833 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001834 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001835 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001836
Scott Michela59d4692008-02-23 18:41:37 +00001837 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001838 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1839 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001840 }
1841 }
1842
1843 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001844 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001845 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1846 }
1847}
1848
1849static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001850 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001851
1852 if (Op0.Val->getOpcode() == ISD::Constant) {
1853 // For a constant, build the appropriate constant vector, which will
1854 // eventually simplify to a vector register load.
1855
1856 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1857 SmallVector<SDOperand, 16> ConstVecValues;
1858 MVT::ValueType VT;
1859 size_t n_copies;
1860
1861 // Create a constant vector:
1862 switch (Op.getValueType()) {
1863 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001864 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001865 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1866 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1867 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1868 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1869 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1870 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1871 }
1872
1873 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1874 for (size_t j = 0; j < n_copies; ++j)
1875 ConstVecValues.push_back(CValue);
1876
1877 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001878 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001879 } else {
1880 // Otherwise, copy the value from one register to another:
1881 switch (Op0.getValueType()) {
1882 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1883 case MVT::i8:
1884 case MVT::i16:
1885 case MVT::i32:
1886 case MVT::i64:
1887 case MVT::f32:
1888 case MVT::f64:
1889 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1890 }
1891 }
1892
1893 return SDOperand();
1894}
1895
1896static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1897 switch (Op.getValueType()) {
1898 case MVT::v4i32: {
1899 SDOperand rA = Op.getOperand(0);
1900 SDOperand rB = Op.getOperand(1);
1901 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1902 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1903 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1904 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1905
1906 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1907 break;
1908 }
1909
1910 // Multiply two v8i16 vectors (pipeline friendly version):
1911 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1912 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1913 // c) Use SELB to select upper and lower halves from the intermediate results
1914 //
Scott Michel8bf61e82008-06-02 22:18:03 +00001915 // NOTE: We really want to move the SELECT_MASK to earlier to actually get the
Scott Michel266bc8f2007-12-04 22:23:35 +00001916 // dual-issue. This code does manage to do this, even if it's a little on
1917 // the wacky side
1918 case MVT::v8i16: {
1919 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001920 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001921 SDOperand Chain = Op.getOperand(0);
1922 SDOperand rA = Op.getOperand(0);
1923 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001924 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1925 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001926
1927 SDOperand FSMBOp =
1928 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel8bf61e82008-06-02 22:18:03 +00001929 DAG.getNode(SPUISD::SELECT_MASK, MVT::v8i16,
Scott Michel203b2d62008-04-30 00:30:08 +00001930 DAG.getConstant(0xcccc, MVT::i16)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001931
1932 SDOperand HHProd =
1933 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001934 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001935
1936 SDOperand HHProd_v4i32 =
1937 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001938 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001939
1940 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001941 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1942 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1943 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1944 HHProd_v4i32,
1945 DAG.getConstant(16, MVT::i16))),
1946 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001947 }
1948
1949 // This M00sE is N@stI! (apologies to Monty Python)
1950 //
1951 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1952 // is to break it all apart, sign extend, and reassemble the various
1953 // intermediate products.
1954 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001955 SDOperand rA = Op.getOperand(0);
1956 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001957 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1958 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001959
1960 SDOperand LLProd =
1961 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001962 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1963 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001964
1965 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1966
1967 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1968
1969 SDOperand LHProd =
1970 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001971 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001972
Scott Michel8bf61e82008-06-02 22:18:03 +00001973 SDOperand FSMBmask = DAG.getNode(SPUISD::SELECT_MASK, MVT::v8i16,
Scott Michel203b2d62008-04-30 00:30:08 +00001974 DAG.getConstant(0x2222, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001975
Scott Michela59d4692008-02-23 18:41:37 +00001976 SDOperand LoProdParts =
1977 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1978 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1979 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001980
1981 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1982
1983 SDOperand LoProd =
1984 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001985 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001986 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1987 LoProdMask, LoProdMask,
1988 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001989
1990 SDOperand rAH =
1991 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001992 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001993
1994 SDOperand rBH =
1995 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001996 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001997
1998 SDOperand HLProd =
1999 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002000 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
2001 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00002002
2003 SDOperand HHProd_1 =
2004 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002005 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2006 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
2007 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2008 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002009
2010 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00002011 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2012 HLProd,
2013 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2014 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00002015
2016 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00002017 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002018
2019 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002020 DAG.getNode(ISD::OR, MVT::v4i32,
2021 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002022 }
2023
2024 default:
2025 cerr << "CellSPU: Unknown vector multiplication, got "
2026 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002027 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002028 abort();
2029 /*NOTREACHED*/
2030 }
2031
2032 return SDOperand();
2033}
2034
2035static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2036 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002037 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002038
2039 SDOperand A = Op.getOperand(0);
2040 SDOperand B = Op.getOperand(1);
2041 unsigned VT = Op.getValueType();
2042
2043 unsigned VRegBR, VRegC;
2044
2045 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002046 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2047 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002048 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002049 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2050 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002051 }
2052 // TODO: make sure we're feeding FPInterp the right arguments
2053 // Right now: fi B, frest(B)
2054
2055 // Computes BRcpl =
2056 // (Floating Interpolate (FP Reciprocal Estimate B))
2057 SDOperand BRcpl =
2058 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002059 DAG.getNode(SPUISD::FPInterp, VT, B,
2060 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002061
2062 // Computes A * BRcpl and stores in a temporary register
2063 SDOperand AxBRcpl =
2064 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002065 DAG.getNode(ISD::FMUL, VT, A,
2066 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002067 // What's the Chain variable do? It's magic!
2068 // TODO: set Chain = Op(0).getEntryNode()
2069
2070 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002071 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2072 DAG.getNode(ISD::FMUL, VT,
2073 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2074 DAG.getNode(ISD::FSUB, VT, A,
2075 DAG.getNode(ISD::FMUL, VT, B,
2076 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002077}
2078
Scott Michel266bc8f2007-12-04 22:23:35 +00002079static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2080 unsigned VT = Op.getValueType();
2081 SDOperand N = Op.getOperand(0);
2082 SDOperand Elt = Op.getOperand(1);
2083 SDOperand ShufMask[16];
2084 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2085
2086 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2087
2088 int EltNo = (int) C->getValue();
2089
2090 // sanity checks:
2091 if (VT == MVT::i8 && EltNo >= 16)
2092 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2093 else if (VT == MVT::i16 && EltNo >= 8)
2094 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2095 else if (VT == MVT::i32 && EltNo >= 4)
2096 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2097 else if (VT == MVT::i64 && EltNo >= 2)
2098 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2099
2100 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2101 // i32 and i64: Element 0 is the preferred slot
2102 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2103 }
2104
2105 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002106 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002107 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2108
2109 switch (VT) {
2110 case MVT::i8: {
2111 prefslot_begin = prefslot_end = 3;
2112 break;
2113 }
2114 case MVT::i16: {
2115 prefslot_begin = 2; prefslot_end = 3;
2116 break;
2117 }
2118 case MVT::i32: {
2119 prefslot_begin = 0; prefslot_end = 3;
2120 break;
2121 }
2122 case MVT::i64: {
2123 prefslot_begin = 0; prefslot_end = 7;
2124 break;
2125 }
2126 }
2127
Scott Michel0e5665b2007-12-19 21:17:42 +00002128 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002129 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002130
Scott Michel266bc8f2007-12-04 22:23:35 +00002131 for (int i = 0; i < 16; ++i) {
2132 // zero fill uppper part of preferred slot, don't care about the
2133 // other slots:
2134 unsigned int mask_val;
2135
2136 if (i <= prefslot_end) {
2137 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002138 ((i < prefslot_begin)
2139 ? 0x80
2140 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002141
Scott Michel0e5665b2007-12-19 21:17:42 +00002142 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002143 } else
2144 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2145 }
2146
2147 SDOperand ShufMaskVec =
2148 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002149 &ShufMask[0],
2150 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002151
2152 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002153 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2154 N, N, ShufMaskVec));
2155
Scott Michel266bc8f2007-12-04 22:23:35 +00002156}
2157
2158static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2159 SDOperand VecOp = Op.getOperand(0);
2160 SDOperand ValOp = Op.getOperand(1);
2161 SDOperand IdxOp = Op.getOperand(2);
2162 MVT::ValueType VT = Op.getValueType();
2163
2164 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2165 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2166
2167 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2168 // Use $2 because it's always 16-byte aligned and it's available:
2169 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2170
2171 SDOperand result =
2172 DAG.getNode(SPUISD::SHUFB, VT,
2173 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2174 VecOp,
2175 DAG.getNode(SPUISD::INSERT_MASK, VT,
2176 DAG.getNode(ISD::ADD, PtrVT,
2177 PtrBase,
2178 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002179 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002180
2181 return result;
2182}
2183
Scott Michela59d4692008-02-23 18:41:37 +00002184static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2185{
Scott Michel266bc8f2007-12-04 22:23:35 +00002186 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2187
2188 assert(Op.getValueType() == MVT::i8);
2189 switch (Opc) {
2190 default:
2191 assert(0 && "Unhandled i8 math operator");
2192 /*NOTREACHED*/
2193 break;
2194 case ISD::SUB: {
2195 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2196 // the result:
2197 SDOperand N1 = Op.getOperand(1);
2198 N0 = (N0.getOpcode() != ISD::Constant
2199 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2200 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2201 N1 = (N1.getOpcode() != ISD::Constant
2202 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2203 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2204 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2205 DAG.getNode(Opc, MVT::i16, N0, N1));
2206 }
2207 case ISD::ROTR:
2208 case ISD::ROTL: {
2209 SDOperand N1 = Op.getOperand(1);
2210 unsigned N1Opc;
2211 N0 = (N0.getOpcode() != ISD::Constant
2212 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2213 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2214 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2215 N1 = (N1.getOpcode() != ISD::Constant
2216 ? DAG.getNode(N1Opc, MVT::i16, N1)
2217 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2218 SDOperand ExpandArg =
2219 DAG.getNode(ISD::OR, MVT::i16, N0,
2220 DAG.getNode(ISD::SHL, MVT::i16,
2221 N0, DAG.getConstant(8, MVT::i16)));
2222 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2223 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2224 }
2225 case ISD::SRL:
2226 case ISD::SHL: {
2227 SDOperand N1 = Op.getOperand(1);
2228 unsigned N1Opc;
2229 N0 = (N0.getOpcode() != ISD::Constant
2230 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2231 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2232 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2233 N1 = (N1.getOpcode() != ISD::Constant
2234 ? DAG.getNode(N1Opc, MVT::i16, N1)
2235 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2236 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2237 DAG.getNode(Opc, MVT::i16, N0, N1));
2238 }
2239 case ISD::SRA: {
2240 SDOperand N1 = Op.getOperand(1);
2241 unsigned N1Opc;
2242 N0 = (N0.getOpcode() != ISD::Constant
2243 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2244 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2245 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2246 N1 = (N1.getOpcode() != ISD::Constant
2247 ? DAG.getNode(N1Opc, MVT::i16, N1)
2248 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2249 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2250 DAG.getNode(Opc, MVT::i16, N0, N1));
2251 }
2252 case ISD::MUL: {
2253 SDOperand N1 = Op.getOperand(1);
2254 unsigned N1Opc;
2255 N0 = (N0.getOpcode() != ISD::Constant
2256 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2257 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2258 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2259 N1 = (N1.getOpcode() != ISD::Constant
2260 ? DAG.getNode(N1Opc, MVT::i16, N1)
2261 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2262 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2263 DAG.getNode(Opc, MVT::i16, N0, N1));
2264 break;
2265 }
2266 }
2267
2268 return SDOperand();
2269}
2270
Scott Michela59d4692008-02-23 18:41:37 +00002271static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2272{
2273 MVT::ValueType VT = Op.getValueType();
2274 unsigned VecVT =
2275 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2276
2277 SDOperand Op0 = Op.getOperand(0);
2278
2279 switch (Opc) {
2280 case ISD::ZERO_EXTEND:
2281 case ISD::SIGN_EXTEND:
2282 case ISD::ANY_EXTEND: {
2283 MVT::ValueType Op0VT = Op0.getValueType();
2284 unsigned Op0VecVT =
2285 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2286
2287 assert(Op0VT == MVT::i32
2288 && "CellSPU: Zero/sign extending something other than i32");
Scott Michel203b2d62008-04-30 00:30:08 +00002289 DEBUG(cerr << "CellSPU: LowerI64Math custom lowering zero/sign/any extend\n");
Scott Michela59d4692008-02-23 18:41:37 +00002290
2291 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2292 ? SPUISD::ROTBYTES_RIGHT_S
2293 : SPUISD::ROTQUAD_RZ_BYTES);
2294 SDOperand PromoteScalar =
2295 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2296
2297 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2298 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2299 DAG.getNode(NewOpc, Op0VecVT,
2300 PromoteScalar,
2301 DAG.getConstant(4, MVT::i32))));
2302 }
2303
Scott Michel8bf61e82008-06-02 22:18:03 +00002304 case ISD::ADD: {
2305 // Turn operands into vectors to satisfy type checking (shufb works on
2306 // vectors)
2307 SDOperand Op0 =
2308 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2309 SDOperand Op1 =
2310 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(1));
2311 SmallVector<SDOperand, 16> ShufBytes;
2312
2313 // Create the shuffle mask for "rotating" the borrow up one register slot
2314 // once the borrow is generated.
2315 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2316 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2317 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2318 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2319
2320 SDOperand CarryGen =
2321 DAG.getNode(SPUISD::CARRY_GENERATE, MVT::v2i64, Op0, Op1);
2322 SDOperand ShiftedCarry =
2323 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2324 CarryGen, CarryGen,
2325 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2326 &ShufBytes[0], ShufBytes.size()));
2327
2328 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2329 DAG.getNode(SPUISD::ADD_EXTENDED, MVT::v2i64,
2330 Op0, Op1, ShiftedCarry));
2331 }
2332
2333 case ISD::SUB: {
2334 // Turn operands into vectors to satisfy type checking (shufb works on
2335 // vectors)
2336 SDOperand Op0 =
2337 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2338 SDOperand Op1 =
2339 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(1));
2340 SmallVector<SDOperand, 16> ShufBytes;
2341
2342 // Create the shuffle mask for "rotating" the borrow up one register slot
2343 // once the borrow is generated.
2344 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2345 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2346 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2347 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2348
2349 SDOperand BorrowGen =
2350 DAG.getNode(SPUISD::BORROW_GENERATE, MVT::v2i64, Op0, Op1);
2351 SDOperand ShiftedBorrow =
2352 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2353 BorrowGen, BorrowGen,
2354 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2355 &ShufBytes[0], ShufBytes.size()));
2356
2357 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2358 DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64,
2359 Op0, Op1, ShiftedBorrow));
2360 }
2361
Scott Michela59d4692008-02-23 18:41:37 +00002362 case ISD::SHL: {
2363 SDOperand ShiftAmt = Op.getOperand(1);
2364 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2365 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2366 SDOperand MaskLower =
2367 DAG.getNode(SPUISD::SELB, VecVT,
2368 Op0Vec,
2369 DAG.getConstant(0, VecVT),
Scott Michel8bf61e82008-06-02 22:18:03 +00002370 DAG.getNode(SPUISD::SELECT_MASK, VecVT,
Scott Michela59d4692008-02-23 18:41:37 +00002371 DAG.getConstant(0xff00ULL, MVT::i16)));
2372 SDOperand ShiftAmtBytes =
2373 DAG.getNode(ISD::SRL, ShiftAmtVT,
2374 ShiftAmt,
2375 DAG.getConstant(3, ShiftAmtVT));
2376 SDOperand ShiftAmtBits =
2377 DAG.getNode(ISD::AND, ShiftAmtVT,
2378 ShiftAmt,
2379 DAG.getConstant(7, ShiftAmtVT));
2380
2381 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2382 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2383 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2384 MaskLower, ShiftAmtBytes),
2385 ShiftAmtBits));
2386 }
2387
2388 case ISD::SRL: {
2389 unsigned VT = unsigned(Op.getValueType());
2390 SDOperand ShiftAmt = Op.getOperand(1);
2391 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2392 SDOperand ShiftAmtBytes =
2393 DAG.getNode(ISD::SRL, ShiftAmtVT,
2394 ShiftAmt,
2395 DAG.getConstant(3, ShiftAmtVT));
2396 SDOperand ShiftAmtBits =
2397 DAG.getNode(ISD::AND, ShiftAmtVT,
2398 ShiftAmt,
2399 DAG.getConstant(7, ShiftAmtVT));
2400
2401 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2402 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2403 Op0, ShiftAmtBytes),
2404 ShiftAmtBits);
2405 }
Scott Michel8bf61e82008-06-02 22:18:03 +00002406
2407 case ISD::SRA: {
2408 // Promote Op0 to vector
2409 SDOperand Op0 =
2410 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2411 SDOperand ShiftAmt = Op.getOperand(1);
2412 unsigned ShiftVT = ShiftAmt.getValueType();
2413
2414 // Negate variable shift amounts
2415 if (!isa<ConstantSDNode>(ShiftAmt)) {
2416 ShiftAmt = DAG.getNode(ISD::SUB, ShiftVT,
2417 DAG.getConstant(0, ShiftVT), ShiftAmt);
2418 }
2419
2420 SDOperand UpperHalfSign =
2421 DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i32,
2422 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
2423 DAG.getNode(SPUISD::VEC_SRA, MVT::v2i64,
2424 Op0, DAG.getConstant(31, MVT::i32))));
2425 SDOperand UpperHalfSignMask =
2426 DAG.getNode(SPUISD::SELECT_MASK, MVT::v2i64, UpperHalfSign);
2427 SDOperand UpperLowerMask =
2428 DAG.getNode(SPUISD::SELECT_MASK, MVT::v2i64,
2429 DAG.getConstant(0xff00, MVT::i16));
2430 SDOperand UpperLowerSelect =
2431 DAG.getNode(SPUISD::SELB, MVT::v2i64,
2432 UpperHalfSignMask, Op0, UpperLowerMask);
2433 SDOperand RotateLeftBytes =
2434 DAG.getNode(SPUISD::ROTBYTES_LEFT_BITS, MVT::v2i64,
2435 UpperLowerSelect, ShiftAmt);
2436 SDOperand RotateLeftBits =
2437 DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v2i64,
2438 RotateLeftBytes, ShiftAmt);
2439
2440 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2441 RotateLeftBits);
2442 }
Scott Michela59d4692008-02-23 18:41:37 +00002443 }
2444
2445 return SDOperand();
2446}
2447
Scott Michel266bc8f2007-12-04 22:23:35 +00002448//! Lower byte immediate operations for v16i8 vectors:
2449static SDOperand
2450LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2451 SDOperand ConstVec;
2452 SDOperand Arg;
2453 MVT::ValueType VT = Op.getValueType();
2454
2455 ConstVec = Op.getOperand(0);
2456 Arg = Op.getOperand(1);
2457 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2458 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2459 ConstVec = ConstVec.getOperand(0);
2460 } else {
2461 ConstVec = Op.getOperand(1);
2462 Arg = Op.getOperand(0);
2463 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002464 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002465 }
2466 }
2467 }
2468
2469 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2470 uint64_t VectorBits[2];
2471 uint64_t UndefBits[2];
2472 uint64_t SplatBits, SplatUndef;
2473 int SplatSize;
2474
2475 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002476 && isConstantSplat(VectorBits, UndefBits,
2477 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2478 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002479 SDOperand tcVec[16];
2480 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2481 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2482
2483 // Turn the BUILD_VECTOR into a set of target constants:
2484 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002485 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002486
2487 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002488 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002489 }
2490 }
2491
2492 return SDOperand();
2493}
2494
2495//! Lower i32 multiplication
2496static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2497 unsigned Opc) {
2498 switch (VT) {
2499 default:
2500 cerr << "CellSPU: Unknown LowerMUL value type, got "
2501 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002502 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002503 abort();
2504 /*NOTREACHED*/
2505
2506 case MVT::i32: {
2507 SDOperand rA = Op.getOperand(0);
2508 SDOperand rB = Op.getOperand(1);
2509
2510 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002511 DAG.getNode(ISD::ADD, MVT::i32,
2512 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2513 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2514 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002515 }
2516 }
2517
2518 return SDOperand();
2519}
2520
2521//! Custom lowering for CTPOP (count population)
2522/*!
2523 Custom lowering code that counts the number ones in the input
2524 operand. SPU has such an instruction, but it counts the number of
2525 ones per byte, which then have to be accumulated.
2526*/
2527static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2528 unsigned VT = Op.getValueType();
2529 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2530
2531 switch (VT) {
2532 case MVT::i8: {
2533 SDOperand N = Op.getOperand(0);
2534 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2535
2536 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2537 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2538
2539 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2540 }
2541
2542 case MVT::i16: {
2543 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002544 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002545
Chris Lattner84bc5422007-12-31 04:13:23 +00002546 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002547
2548 SDOperand N = Op.getOperand(0);
2549 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2550 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2551 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2552
2553 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2554 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2555
2556 // CNTB_result becomes the chain to which all of the virtual registers
2557 // CNTB_reg, SUM1_reg become associated:
2558 SDOperand CNTB_result =
2559 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002560
Scott Michel266bc8f2007-12-04 22:23:35 +00002561 SDOperand CNTB_rescopy =
2562 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2563
2564 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2565
2566 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002567 DAG.getNode(ISD::ADD, MVT::i16,
2568 DAG.getNode(ISD::SRL, MVT::i16,
2569 Tmp1, Shift1),
2570 Tmp1),
2571 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002572 }
2573
2574 case MVT::i32: {
2575 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002576 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002577
Chris Lattner84bc5422007-12-31 04:13:23 +00002578 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2579 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002580
2581 SDOperand N = Op.getOperand(0);
2582 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2583 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2584 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2585 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2586
2587 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2588 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2589
2590 // CNTB_result becomes the chain to which all of the virtual registers
2591 // CNTB_reg, SUM1_reg become associated:
2592 SDOperand CNTB_result =
2593 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002594
Scott Michel266bc8f2007-12-04 22:23:35 +00002595 SDOperand CNTB_rescopy =
2596 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2597
2598 SDOperand Comp1 =
2599 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002600 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002601
2602 SDOperand Sum1 =
2603 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002604 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002605
2606 SDOperand Sum1_rescopy =
2607 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2608
2609 SDOperand Comp2 =
2610 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002611 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2612 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002613 SDOperand Sum2 =
2614 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002615 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002616
2617 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2618 }
2619
2620 case MVT::i64:
2621 break;
2622 }
2623
2624 return SDOperand();
2625}
2626
2627/// LowerOperation - Provide custom lowering hooks for some operations.
2628///
2629SDOperand
2630SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2631{
Scott Michela59d4692008-02-23 18:41:37 +00002632 unsigned Opc = (unsigned) Op.getOpcode();
2633 unsigned VT = (unsigned) Op.getValueType();
2634
2635 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002636 default: {
2637 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002638 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002639 cerr << "*Op.Val:\n";
2640 Op.Val->dump();
2641 abort();
2642 }
2643 case ISD::LOAD:
2644 case ISD::SEXTLOAD:
2645 case ISD::ZEXTLOAD:
2646 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2647 case ISD::STORE:
2648 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2649 case ISD::ConstantPool:
2650 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2651 case ISD::GlobalAddress:
2652 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2653 case ISD::JumpTable:
2654 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2655 case ISD::Constant:
2656 return LowerConstant(Op, DAG);
2657 case ISD::ConstantFP:
2658 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002659 case ISD::BRCOND:
2660 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002661 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002662 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002663 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002664 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002665 case ISD::RET:
2666 return LowerRET(Op, DAG, getTargetMachine());
2667
Scott Michela59d4692008-02-23 18:41:37 +00002668
2669 // i8, i64 math ops:
2670 case ISD::ZERO_EXTEND:
2671 case ISD::SIGN_EXTEND:
2672 case ISD::ANY_EXTEND:
Scott Michel8bf61e82008-06-02 22:18:03 +00002673 case ISD::ADD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002674 case ISD::SUB:
2675 case ISD::ROTR:
2676 case ISD::ROTL:
2677 case ISD::SRL:
2678 case ISD::SHL:
Scott Michel8bf61e82008-06-02 22:18:03 +00002679 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002680 if (VT == MVT::i8)
2681 return LowerI8Math(Op, DAG, Opc);
2682 else if (VT == MVT::i64)
2683 return LowerI64Math(Op, DAG, Opc);
2684 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002685 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002686
2687 // Vector-related lowering.
2688 case ISD::BUILD_VECTOR:
2689 return LowerBUILD_VECTOR(Op, DAG);
2690 case ISD::SCALAR_TO_VECTOR:
2691 return LowerSCALAR_TO_VECTOR(Op, DAG);
2692 case ISD::VECTOR_SHUFFLE:
2693 return LowerVECTOR_SHUFFLE(Op, DAG);
2694 case ISD::EXTRACT_VECTOR_ELT:
2695 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2696 case ISD::INSERT_VECTOR_ELT:
2697 return LowerINSERT_VECTOR_ELT(Op, DAG);
2698
2699 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2700 case ISD::AND:
2701 case ISD::OR:
2702 case ISD::XOR:
2703 return LowerByteImmed(Op, DAG);
2704
2705 // Vector and i8 multiply:
2706 case ISD::MUL:
Scott Michela59d4692008-02-23 18:41:37 +00002707 if (MVT::isVector(VT))
Scott Michel266bc8f2007-12-04 22:23:35 +00002708 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002709 else if (VT == MVT::i8)
2710 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002711 else
Scott Michela59d4692008-02-23 18:41:37 +00002712 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002713
2714 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002715 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002716 return LowerFDIVf32(Op, DAG);
2717// else if (Op.getValueType() == MVT::f64)
2718// return LowerFDIVf64(Op, DAG);
2719 else
2720 assert(0 && "Calling FDIV on unsupported MVT");
2721
2722 case ISD::CTPOP:
2723 return LowerCTPOP(Op, DAG);
2724 }
2725
2726 return SDOperand();
2727}
2728
2729//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002730// Target Optimization Hooks
2731//===----------------------------------------------------------------------===//
2732
2733SDOperand
2734SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2735{
2736#if 0
2737 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002738#endif
2739 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002740 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002741 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2742 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002743
2744 switch (N->getOpcode()) {
2745 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002746 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002747 SDOperand Op1 = N->getOperand(1);
2748
Scott Michel8bf61e82008-06-02 22:18:03 +00002749 if (isa<ConstantSDNode>(Op1) && Op0.getOpcode() == SPUISD::IndirectAddr) {
Scott Michel053c1da2008-01-29 02:16:57 +00002750 SDOperand Op01 = Op0.getOperand(1);
2751 if (Op01.getOpcode() == ISD::Constant
2752 || Op01.getOpcode() == ISD::TargetConstant) {
2753 // (add <const>, (SPUindirect <arg>, <const>)) ->
2754 // (SPUindirect <arg>, <const + const>)
2755 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2756 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2757 SDOperand combinedConst =
2758 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2759 Op0.getValueType());
2760
2761 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2762 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2763 DEBUG(cerr << "With: (SPUindirect <arg>, "
2764 << CN0->getValue() + CN1->getValue() << ")\n");
2765 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2766 Op0.getOperand(0), combinedConst);
2767 }
Scott Michel8bf61e82008-06-02 22:18:03 +00002768 } else if (isa<ConstantSDNode>(Op0)
Scott Michel053c1da2008-01-29 02:16:57 +00002769 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2770 SDOperand Op11 = Op1.getOperand(1);
2771 if (Op11.getOpcode() == ISD::Constant
2772 || Op11.getOpcode() == ISD::TargetConstant) {
2773 // (add (SPUindirect <arg>, <const>), <const>) ->
2774 // (SPUindirect <arg>, <const + const>)
2775 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2776 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2777 SDOperand combinedConst =
2778 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2779 Op0.getValueType());
2780
2781 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2782 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2783 DEBUG(cerr << "With: (SPUindirect <arg>, "
2784 << CN0->getValue() + CN1->getValue() << ")\n");
2785
2786 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2787 Op1.getOperand(0), combinedConst);
2788 }
2789 }
Scott Michela59d4692008-02-23 18:41:37 +00002790 break;
2791 }
2792 case ISD::SIGN_EXTEND:
2793 case ISD::ZERO_EXTEND:
2794 case ISD::ANY_EXTEND: {
2795 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2796 N->getValueType(0) == Op0.getValueType()) {
2797 // (any_extend (SPUextract_elt0 <arg>)) ->
2798 // (SPUextract_elt0 <arg>)
2799 // Types must match, however...
2800 DEBUG(cerr << "Replace: ");
2801 DEBUG(N->dump(&DAG));
2802 DEBUG(cerr << "\nWith: ");
2803 DEBUG(Op0.Val->dump(&DAG));
2804 DEBUG(cerr << "\n");
2805
2806 return Op0;
2807 }
2808 break;
2809 }
2810 case SPUISD::IndirectAddr: {
2811 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2812 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2813 if (CN->getValue() == 0) {
2814 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2815 // (SPUaform <addr>, 0)
2816
2817 DEBUG(cerr << "Replace: ");
2818 DEBUG(N->dump(&DAG));
2819 DEBUG(cerr << "\nWith: ");
2820 DEBUG(Op0.Val->dump(&DAG));
2821 DEBUG(cerr << "\n");
2822
2823 return Op0;
2824 }
2825 }
2826 break;
2827 }
2828 case SPUISD::SHLQUAD_L_BITS:
2829 case SPUISD::SHLQUAD_L_BYTES:
2830 case SPUISD::VEC_SHL:
2831 case SPUISD::VEC_SRL:
2832 case SPUISD::VEC_SRA:
2833 case SPUISD::ROTQUAD_RZ_BYTES:
2834 case SPUISD::ROTQUAD_RZ_BITS: {
2835 SDOperand Op1 = N->getOperand(1);
2836
2837 if (isa<ConstantSDNode>(Op1)) {
2838 // Kill degenerate vector shifts:
2839 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2840
2841 if (CN->getValue() == 0) {
2842 Result = Op0;
2843 }
2844 }
2845 break;
2846 }
2847 case SPUISD::PROMOTE_SCALAR: {
2848 switch (Op0.getOpcode()) {
2849 default:
2850 break;
2851 case ISD::ANY_EXTEND:
2852 case ISD::ZERO_EXTEND:
2853 case ISD::SIGN_EXTEND: {
2854 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2855 // <arg>
2856 // but only if the SPUpromote_scalar and <arg> types match.
2857 SDOperand Op00 = Op0.getOperand(0);
2858 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2859 SDOperand Op000 = Op00.getOperand(0);
2860 if (Op000.getValueType() == N->getValueType(0)) {
2861 Result = Op000;
2862 }
2863 }
2864 break;
2865 }
2866 case SPUISD::EXTRACT_ELT0: {
2867 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2868 // <arg>
2869 Result = Op0.getOperand(0);
2870 break;
2871 }
2872 }
2873 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002874 }
2875 }
Scott Michel58c58182008-01-17 20:38:41 +00002876 // Otherwise, return unchanged.
Scott Michel203b2d62008-04-30 00:30:08 +00002877#if 1
Scott Michela59d4692008-02-23 18:41:37 +00002878 if (Result.Val) {
2879 DEBUG(cerr << "\nReplace.SPU: ");
2880 DEBUG(N->dump(&DAG));
2881 DEBUG(cerr << "\nWith: ");
2882 DEBUG(Result.Val->dump(&DAG));
2883 DEBUG(cerr << "\n");
2884 }
2885#endif
2886
2887 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002888}
2889
2890//===----------------------------------------------------------------------===//
2891// Inline Assembly Support
2892//===----------------------------------------------------------------------===//
2893
2894/// getConstraintType - Given a constraint letter, return the type of
2895/// constraint it is for this target.
2896SPUTargetLowering::ConstraintType
2897SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2898 if (ConstraintLetter.size() == 1) {
2899 switch (ConstraintLetter[0]) {
2900 default: break;
2901 case 'b':
2902 case 'r':
2903 case 'f':
2904 case 'v':
2905 case 'y':
2906 return C_RegisterClass;
2907 }
2908 }
2909 return TargetLowering::getConstraintType(ConstraintLetter);
2910}
2911
2912std::pair<unsigned, const TargetRegisterClass*>
2913SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2914 MVT::ValueType VT) const
2915{
2916 if (Constraint.size() == 1) {
2917 // GCC RS6000 Constraint Letters
2918 switch (Constraint[0]) {
2919 case 'b': // R1-R31
2920 case 'r': // R0-R31
2921 if (VT == MVT::i64)
2922 return std::make_pair(0U, SPU::R64CRegisterClass);
2923 return std::make_pair(0U, SPU::R32CRegisterClass);
2924 case 'f':
2925 if (VT == MVT::f32)
2926 return std::make_pair(0U, SPU::R32FPRegisterClass);
2927 else if (VT == MVT::f64)
2928 return std::make_pair(0U, SPU::R64FPRegisterClass);
2929 break;
2930 case 'v':
2931 return std::make_pair(0U, SPU::GPRCRegisterClass);
2932 }
2933 }
2934
2935 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2936}
2937
Scott Michela59d4692008-02-23 18:41:37 +00002938//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002939void
2940SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002941 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002942 APInt &KnownZero,
2943 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002944 const SelectionDAG &DAG,
2945 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00002946#if 0
Scott Michela59d4692008-02-23 18:41:37 +00002947 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michel203b2d62008-04-30 00:30:08 +00002948#endif
Scott Michela59d4692008-02-23 18:41:37 +00002949
2950 switch (Op.getOpcode()) {
2951 default:
2952 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2953 break;
2954
2955#if 0
2956 case CALL:
2957 case SHUFB:
2958 case INSERT_MASK:
2959 case CNTB:
2960#endif
2961
2962 case SPUISD::PROMOTE_SCALAR: {
2963 SDOperand Op0 = Op.getOperand(0);
Scott Michel203b2d62008-04-30 00:30:08 +00002964 MVT::ValueType Op0VT = Op0.getValueType();
2965 unsigned Op0VTBits = MVT::getSizeInBits(Op0VT);
2966 uint64_t InMask = MVT::getIntVTBitMask(Op0VT);
2967 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2968 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002969 break;
2970 }
2971
2972 case SPUISD::LDRESULT:
2973 case SPUISD::EXTRACT_ELT0:
2974 case SPUISD::EXTRACT_ELT0_CHAINED: {
Scott Michel203b2d62008-04-30 00:30:08 +00002975 MVT::ValueType OpVT = Op.getValueType();
2976 unsigned OpVTBits = MVT::getSizeInBits(OpVT);
2977 uint64_t InMask = MVT::getIntVTBitMask(OpVT);
2978 KnownZero |= APInt(OpVTBits, ~InMask, false);
2979 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002980 break;
2981 }
2982
2983#if 0
2984 case EXTRACT_I1_ZEXT:
2985 case EXTRACT_I1_SEXT:
2986 case EXTRACT_I8_ZEXT:
2987 case EXTRACT_I8_SEXT:
2988 case MPY:
2989 case MPYU:
2990 case MPYH:
2991 case MPYHH:
Scott Michel203b2d62008-04-30 00:30:08 +00002992 case SPUISD::SHLQUAD_L_BITS:
2993 case SPUISD::SHLQUAD_L_BYTES:
2994 case SPUISD::VEC_SHL:
2995 case SPUISD::VEC_SRL:
2996 case SPUISD::VEC_SRA:
2997 case SPUISD::VEC_ROTL:
2998 case SPUISD::VEC_ROTR:
2999 case SPUISD::ROTQUAD_RZ_BYTES:
3000 case SPUISD::ROTQUAD_RZ_BITS:
3001 case SPUISD::ROTBYTES_RIGHT_S:
3002 case SPUISD::ROTBYTES_LEFT:
3003 case SPUISD::ROTBYTES_LEFT_CHAINED:
Scott Michel8bf61e82008-06-02 22:18:03 +00003004 case SPUISD::SELECT_MASK:
3005 case SPUISD::SELB:
3006 case SPUISD::FPInterp:
3007 case SPUISD::FPRecipEst:
3008 case SPUISD::SEXT32TO64:
Scott Michela59d4692008-02-23 18:41:37 +00003009#endif
3010 }
Scott Michel266bc8f2007-12-04 22:23:35 +00003011}
3012
Scott Michel203b2d62008-04-30 00:30:08 +00003013// LowerAsmOperandForConstraint
3014void
3015SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
3016 char ConstraintLetter,
3017 std::vector<SDOperand> &Ops,
3018 SelectionDAG &DAG) const {
3019 // Default, for the time being, to the base class handler
3020 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
3021}
3022
Scott Michel266bc8f2007-12-04 22:23:35 +00003023/// isLegalAddressImmediate - Return true if the integer value can be used
3024/// as the offset of the target addressing mode.
3025bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
3026 // SPU's addresses are 256K:
3027 return (V > -(1 << 18) && V < (1 << 18) - 1);
3028}
3029
3030bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
3031 return false;
3032}