blob: a6c0b8751b192e48c86986b62a559acae289f316 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
17#include "llvm/ADT/VectorExtras.h"
18#include "llvm/Analysis/ScalarEvolutionExpressions.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000024#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/Constants.h"
26#include "llvm/Function.h"
27#include "llvm/Intrinsics.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Target/TargetOptions.h"
31
32#include <map>
33
34using namespace llvm;
35
36// Used in getTargetNodeName() below
37namespace {
38 std::map<unsigned, const char *> node_names;
39
40 //! MVT::ValueType mapping to useful data for Cell SPU
41 struct valtype_map_s {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000042 const MVT::ValueType valtype;
43 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000044 };
45
46 const valtype_map_s valtype_map[] = {
47 { MVT::i1, 3 },
48 { MVT::i8, 3 },
49 { MVT::i16, 2 },
50 { MVT::i32, 0 },
51 { MVT::f32, 0 },
52 { MVT::i64, 0 },
53 { MVT::f64, 0 },
54 { MVT::i128, 0 }
55 };
56
57 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
58
59 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) {
60 const valtype_map_s *retval = 0;
61
62 for (size_t i = 0; i < n_valtype_map; ++i) {
63 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000064 retval = valtype_map + i;
65 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000066 }
67 }
68
69#ifndef NDEBUG
70 if (retval == 0) {
71 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel7f9ba9b2008-01-30 02:55:46 +000072 << MVT::getValueTypeString(VT)
73 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000074 abort();
75 }
76#endif
77
78 return retval;
79 }
80
81 //! Predicate that returns true if operand is a memory target
82 /*!
83 \arg Op Operand to test
84 \return true if the operand is a memory target (i.e., global
Scott Michel9de5d0d2008-01-11 02:53:15 +000085 address, external symbol, constant pool) or an A-form
Scott Michel266bc8f2007-12-04 22:23:35 +000086 address.
87 */
88 bool isMemoryOperand(const SDOperand &Op)
89 {
90 const unsigned Opc = Op.getOpcode();
91 return (Opc == ISD::GlobalAddress
92 || Opc == ISD::GlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000093 || Opc == ISD::JumpTable
94 || Opc == ISD::ConstantPool
95 || Opc == ISD::ExternalSymbol
96 || Opc == ISD::TargetGlobalAddress
97 || Opc == ISD::TargetGlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000098 || Opc == ISD::TargetJumpTable
99 || Opc == ISD::TargetConstantPool
100 || Opc == ISD::TargetExternalSymbol
Scott Michel9de5d0d2008-01-11 02:53:15 +0000101 || Opc == SPUISD::AFormAddr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000102 }
Scott Michel58c58182008-01-17 20:38:41 +0000103
104 //! Predicate that returns true if the operand is an indirect target
105 bool isIndirectOperand(const SDOperand &Op)
106 {
107 const unsigned Opc = Op.getOpcode();
108 return (Opc == ISD::Register
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000109 || Opc == SPUISD::LDRESULT);
Scott Michel58c58182008-01-17 20:38:41 +0000110 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000111}
112
113SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
114 : TargetLowering(TM),
115 SPUTM(TM)
116{
117 // Fold away setcc operations if possible.
118 setPow2DivIsCheap();
119
120 // Use _setjmp/_longjmp instead of setjmp/longjmp.
121 setUseUnderscoreSetJmp(true);
122 setUseUnderscoreLongJmp(true);
123
124 // Set up the SPU's register classes:
125 // NOTE: i8 register class is not registered because we cannot determine when
126 // we need to zero or sign extend for custom-lowered loads and stores.
Scott Michel504c3692007-12-17 22:32:34 +0000127 // NOTE: Ignore the previous note. For now. :-)
128 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
129 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
130 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
131 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
132 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
133 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000134 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
135
136 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000137 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000138 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
139 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000140 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
142 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
143 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
144 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000145
146 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
147 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
148 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000149 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
151 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
152 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
153 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
154
Scott Michel266bc8f2007-12-04 22:23:35 +0000155 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
156 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
157 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
158
159 // SPU constant load actions are custom lowered:
160 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000161 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000162 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
163
164 // SPU's loads and stores have to be custom lowered:
165 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
166 ++sctype) {
167 setOperationAction(ISD::LOAD, sctype, Custom);
168 setOperationAction(ISD::STORE, sctype, Custom);
169 }
170
Scott Michel58c58182008-01-17 20:38:41 +0000171 // Custom lower BRCOND for i1, i8 to "promote" the result to
172 // i32 and i16, respectively.
173 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000174
175 // Expand the jumptable branches
176 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
177 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
178 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
179
180 // SPU has no intrinsics for these particular operations:
181 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
182 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
183 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000184 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
185
Scott Michel266bc8f2007-12-04 22:23:35 +0000186 // PowerPC has no SREM/UREM instructions
187 setOperationAction(ISD::SREM, MVT::i32, Expand);
188 setOperationAction(ISD::UREM, MVT::i32, Expand);
189 setOperationAction(ISD::SREM, MVT::i64, Expand);
190 setOperationAction(ISD::UREM, MVT::i64, Expand);
191
192 // We don't support sin/cos/sqrt/fmod
193 setOperationAction(ISD::FSIN , MVT::f64, Expand);
194 setOperationAction(ISD::FCOS , MVT::f64, Expand);
195 setOperationAction(ISD::FREM , MVT::f64, Expand);
196 setOperationAction(ISD::FSIN , MVT::f32, Expand);
197 setOperationAction(ISD::FCOS , MVT::f32, Expand);
198 setOperationAction(ISD::FREM , MVT::f32, Expand);
199
200 // If we're enabling GP optimizations, use hardware square root
201 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
202 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
203
204 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
205 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
206
207 // SPU can do rotate right and left, so legalize it... but customize for i8
208 // because instructions don't exist.
209 setOperationAction(ISD::ROTR, MVT::i32, Legal);
210 setOperationAction(ISD::ROTR, MVT::i16, Legal);
211 setOperationAction(ISD::ROTR, MVT::i8, Custom);
212 setOperationAction(ISD::ROTL, MVT::i32, Legal);
213 setOperationAction(ISD::ROTL, MVT::i16, Legal);
214 setOperationAction(ISD::ROTL, MVT::i8, Custom);
215 // SPU has no native version of shift left/right for i8
216 setOperationAction(ISD::SHL, MVT::i8, Custom);
217 setOperationAction(ISD::SRL, MVT::i8, Custom);
218 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000219 // And SPU needs custom lowering for shift left/right for i64
220 setOperationAction(ISD::SHL, MVT::i64, Custom);
221 setOperationAction(ISD::SRL, MVT::i64, Custom);
222 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000223
224 // Custom lower i32 multiplications
225 setOperationAction(ISD::MUL, MVT::i32, Custom);
226
227 // Need to custom handle (some) common i8 math ops
228 setOperationAction(ISD::SUB, MVT::i8, Custom);
229 setOperationAction(ISD::MUL, MVT::i8, Custom);
230
231 // SPU does not have BSWAP. It does have i32 support CTLZ.
232 // CTPOP has to be custom lowered.
233 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
234 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
235
236 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
237 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
238 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
239 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
240
241 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
242 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
243
244 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
245
Scott Michelad2715e2008-03-05 23:02:02 +0000246 // SPU has a version of select
Scott Michel78c47fa2008-03-10 16:58:52 +0000247 setOperationAction(ISD::SELECT, MVT::i1, Promote);
248 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000249 setOperationAction(ISD::SELECT, MVT::i16, Legal);
250 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000251 setOperationAction(ISD::SELECT, MVT::i64, Expand);
252 setOperationAction(ISD::SELECT, MVT::f32, Expand);
253 setOperationAction(ISD::SELECT, MVT::f64, Expand);
254
Scott Michel78c47fa2008-03-10 16:58:52 +0000255 setOperationAction(ISD::SETCC, MVT::i1, Promote);
256 setOperationAction(ISD::SETCC, MVT::i8, Legal);
257 setOperationAction(ISD::SETCC, MVT::i16, Legal);
258 setOperationAction(ISD::SETCC, MVT::i32, Legal);
259 setOperationAction(ISD::SETCC, MVT::i64, Expand);
260 setOperationAction(ISD::SETCC, MVT::f32, Expand);
261 setOperationAction(ISD::SETCC, MVT::f64, Expand);
Scott Michelad2715e2008-03-05 23:02:02 +0000262
Scott Michela59d4692008-02-23 18:41:37 +0000263 // Zero extension and sign extension for i64 have to be
264 // custom legalized
265 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
266 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
267 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000268
269 // SPU has a legal FP -> signed INT instruction
270 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
271 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
272 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
273 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
274
275 // FDIV on SPU requires custom lowering
276 setOperationAction(ISD::FDIV, MVT::f32, Custom);
277 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
278
279 // SPU has [U|S]INT_TO_FP
280 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
281 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
282 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
283 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
284 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
285 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
286 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
287 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
288
Scott Michel86c041f2007-12-20 00:44:13 +0000289 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
290 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
291 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
292 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000293
294 // We cannot sextinreg(i1). Expand to shifts.
295 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
296
297 // Support label based line numbers.
298 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
299 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
300
301 // We want to legalize GlobalAddress and ConstantPool nodes into the
302 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000303 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
304 ++sctype) {
305 setOperationAction(ISD::GlobalAddress, sctype, Custom);
306 setOperationAction(ISD::ConstantPool, sctype, Custom);
307 setOperationAction(ISD::JumpTable, sctype, Custom);
308 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000309
310 // RET must be custom lowered, to meet ABI requirements
311 setOperationAction(ISD::RET, MVT::Other, Custom);
312
313 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
314 setOperationAction(ISD::VASTART , MVT::Other, Custom);
315
316 // Use the default implementation.
317 setOperationAction(ISD::VAARG , MVT::Other, Expand);
318 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
319 setOperationAction(ISD::VAEND , MVT::Other, Expand);
320 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
321 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
322 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
323 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
324
325 // Cell SPU has instructions for converting between i64 and fp.
326 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
327 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
328
329 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
330 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
331
332 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
333 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
334
335 // First set operation action for all vector types to expand. Then we
336 // will selectively turn on ones that can be effectively codegen'd.
337 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
338 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
339 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
340 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
341 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
342 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
343
344 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
345 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
346 // add/sub are legal for all supported vector VT's.
347 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
348 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
349 // mul has to be custom lowered.
350 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
351
352 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
353 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
354 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
355 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
356 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
357 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
358
359 // These operations need to be expanded:
360 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
361 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
362 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
363 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
364 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
365
366 // Custom lower build_vector, constant pool spills, insert and
367 // extract vector elements:
368 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
369 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
370 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
371 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
372 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
373 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
374 }
375
376 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
377 setOperationAction(ISD::AND, MVT::v16i8, Custom);
378 setOperationAction(ISD::OR, MVT::v16i8, Custom);
379 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
380 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000381
Scott Michel266bc8f2007-12-04 22:23:35 +0000382 setShiftAmountType(MVT::i32);
383 setSetCCResultContents(ZeroOrOneSetCCResult);
384
385 setStackPointerRegisterToSaveRestore(SPU::R1);
386
387 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000388 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000389 setTargetDAGCombine(ISD::ZERO_EXTEND);
390 setTargetDAGCombine(ISD::SIGN_EXTEND);
391 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel266bc8f2007-12-04 22:23:35 +0000392
393 computeRegisterProperties();
394}
395
396const char *
397SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
398{
399 if (node_names.empty()) {
400 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
401 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
402 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
403 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000404 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000405 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000406 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
407 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
408 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
409 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
410 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
411 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
412 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
413 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
414 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
415 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
416 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
417 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
418 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
419 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
420 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
421 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michela59d4692008-02-23 18:41:37 +0000422 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
423 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000424 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
425 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
426 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
427 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
428 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michela59d4692008-02-23 18:41:37 +0000429 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
430 "SPUISD::ROTQUAD_RZ_BYTES";
431 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
432 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel266bc8f2007-12-04 22:23:35 +0000433 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
434 "SPUISD::ROTBYTES_RIGHT_S";
435 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
436 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
437 "SPUISD::ROTBYTES_LEFT_CHAINED";
438 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
439 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
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 {
452 return Op.getValueType();
453}
454
Scott Michel266bc8f2007-12-04 22:23:35 +0000455//===----------------------------------------------------------------------===//
456// Calling convention code:
457//===----------------------------------------------------------------------===//
458
459#include "SPUGenCallingConv.inc"
460
461//===----------------------------------------------------------------------===//
462// LowerOperation implementation
463//===----------------------------------------------------------------------===//
464
Scott Michel9de5d0d2008-01-11 02:53:15 +0000465/// Aligned load common code for CellSPU
466/*!
467 \param[in] Op The SelectionDAG load or store operand
468 \param[in] DAG The selection DAG
469 \param[in] ST CellSPU subtarget information structure
470 \param[in,out] alignment Caller initializes this to the load or store node's
471 value from getAlignment(), may be updated while generating the aligned load
472 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
473 offset (divisible by 16, modulo 16 == 0)
474 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
475 offset of the preferred slot (modulo 16 != 0)
476 \param[in,out] VT Caller initializes this value type to the the load or store
477 node's loaded or stored value type; may be updated if an i1-extended load or
478 store.
479 \param[out] was16aligned true if the base pointer had 16-byte alignment,
480 otherwise false. Can help to determine if the chunk needs to be rotated.
481
482 Both load and store lowering load a block of data aligned on a 16-byte
483 boundary. This is the common aligned load code shared between both.
484 */
485static SDOperand
486AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
487 LSBaseSDNode *LSN,
488 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000489 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000490{
491 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
492 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
493 SDOperand basePtr = LSN->getBasePtr();
494 SDOperand chain = LSN->getChain();
495
496 if (basePtr.getOpcode() == ISD::ADD) {
497 SDOperand Op1 = basePtr.Val->getOperand(1);
498
499 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000500 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000501
502 alignOffs = (int) CN->getValue();
503 prefSlotOffs = (int) (alignOffs & 0xf);
504
505 // Adjust the rotation amount to ensure that the final result ends up in
506 // the preferred slot:
507 prefSlotOffs -= vtm->prefslot_byte;
508 basePtr = basePtr.getOperand(0);
509
Scott Michel58c58182008-01-17 20:38:41 +0000510 // Loading from memory, can we adjust alignment?
511 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
512 SDOperand APtr = basePtr.getOperand(0);
513 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
514 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
515 alignment = GSDN->getGlobal()->getAlignment();
516 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000517 }
518 } else {
519 alignOffs = 0;
520 prefSlotOffs = -vtm->prefslot_byte;
521 }
522 } else {
523 alignOffs = 0;
524 prefSlotOffs = -vtm->prefslot_byte;
525 }
526
527 if (alignment == 16) {
528 // Realign the base pointer as a D-Form address:
529 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000530 basePtr = DAG.getNode(ISD::ADD, PtrVT,
531 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000532 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000533 }
534
535 // Emit the vector load:
536 was16aligned = true;
537 return DAG.getLoad(MVT::v16i8, chain, basePtr,
538 LSN->getSrcValue(), LSN->getSrcValueOffset(),
539 LSN->isVolatile(), 16);
540 }
541
542 // Unaligned load or we're using the "large memory" model, which means that
543 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000544 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000545 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000546 }
547
548 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000549 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000550 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000551 was16aligned = false;
552 return DAG.getLoad(MVT::v16i8, chain, basePtr,
553 LSN->getSrcValue(), LSN->getSrcValueOffset(),
554 LSN->isVolatile(), 16);
555}
556
Scott Michel266bc8f2007-12-04 22:23:35 +0000557/// Custom lower loads for CellSPU
558/*!
559 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
560 within a 16-byte block, we have to rotate to extract the requested element.
561 */
562static SDOperand
563LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
564 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000565 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000566 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000567 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000568 ISD::LoadExtType ExtType = LN->getExtensionType();
569 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000570 SDOperand Ops[8];
571
Scott Michel266bc8f2007-12-04 22:23:35 +0000572 switch (LN->getAddressingMode()) {
573 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000574 int offset, rotamt;
575 bool was16aligned;
576 SDOperand result =
577 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000578
Scott Michel9de5d0d2008-01-11 02:53:15 +0000579 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000580 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000581
582 the_chain = result.getValue(1);
583 // Rotate the chunk if necessary
584 if (rotamt < 0)
585 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000586 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000587 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
588
Scott Michel58c58182008-01-17 20:38:41 +0000589 Ops[0] = the_chain;
590 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000591 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000592 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
593 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000594 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000595 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000596 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000597 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000598 }
599
600 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
601 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000602 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000603
604 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
605 SDVTList scalarvts;
606 MVT::ValueType vecVT = MVT::v16i8;
607
608 // Convert the loaded v16i8 vector to the appropriate vector type
609 // specified by the operand:
610 if (OpVT == VT) {
611 if (VT != MVT::i1)
612 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
613 } else
614 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
615
616 Ops[0] = the_chain;
617 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
618 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
619 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
620 the_chain = result.getValue(1);
621 } else {
622 // Handle the sign and zero-extending loads for i1 and i8:
623 unsigned NewOpC;
624
625 if (ExtType == ISD::SEXTLOAD) {
626 NewOpC = (OpVT == MVT::i1
627 ? SPUISD::EXTRACT_I1_SEXT
628 : SPUISD::EXTRACT_I8_SEXT);
629 } else {
630 assert(ExtType == ISD::ZEXTLOAD);
631 NewOpC = (OpVT == MVT::i1
632 ? SPUISD::EXTRACT_I1_ZEXT
633 : SPUISD::EXTRACT_I8_ZEXT);
634 }
635
636 result = DAG.getNode(NewOpC, OpVT, result);
637 }
638
639 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000640 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000641 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000642 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000643 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000644
Scott Michel58c58182008-01-17 20:38:41 +0000645 result = DAG.getNode(SPUISD::LDRESULT, retvts,
646 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000647 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000648 }
649 case ISD::PRE_INC:
650 case ISD::PRE_DEC:
651 case ISD::POST_INC:
652 case ISD::POST_DEC:
653 case ISD::LAST_INDEXED_MODE:
654 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
655 "UNINDEXED\n";
656 cerr << (unsigned) LN->getAddressingMode() << "\n";
657 abort();
658 /*NOTREACHED*/
659 }
660
661 return SDOperand();
662}
663
664/// Custom lower stores for CellSPU
665/*!
666 All CellSPU stores are aligned to 16-byte boundaries, so for elements
667 within a 16-byte block, we have to generate a shuffle to insert the
668 requested element into its place, then store the resulting block.
669 */
670static SDOperand
671LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
672 StoreSDNode *SN = cast<StoreSDNode>(Op);
673 SDOperand Value = SN->getValue();
674 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000675 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000676 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000677 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000678
679 switch (SN->getAddressingMode()) {
680 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000681 int chunk_offset, slot_offset;
682 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000683
684 // The vector type we really want to load from the 16-byte chunk, except
685 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000686 unsigned vecVT, stVecVT = MVT::v16i8;
687
Scott Michel266bc8f2007-12-04 22:23:35 +0000688 if (StVT != MVT::i1)
689 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000690 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
691
Scott Michel9de5d0d2008-01-11 02:53:15 +0000692 SDOperand alignLoadVec =
693 AlignedLoad(Op, DAG, ST, SN, alignment,
694 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000695
Scott Michel9de5d0d2008-01-11 02:53:15 +0000696 if (alignLoadVec.Val == 0)
697 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000698
Scott Michel9de5d0d2008-01-11 02:53:15 +0000699 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
700 SDOperand basePtr = LN->getBasePtr();
701 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000702 SDOperand theValue = SN->getValue();
703 SDOperand result;
704
705 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000706 && (theValue.getOpcode() == ISD::AssertZext
707 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000708 // Drill down and get the value for zero- and sign-extended
709 // quantities
710 theValue = theValue.getOperand(0);
711 }
712
Scott Michel9de5d0d2008-01-11 02:53:15 +0000713 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000714
Scott Michel9de5d0d2008-01-11 02:53:15 +0000715 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
716 SDOperand insertEltPtr;
717 SDOperand insertEltOp;
718
719 // If the base pointer is already a D-form address, then just create
720 // a new D-form address with a slot offset and the orignal base pointer.
721 // Otherwise generate a D-form address with the slot offset relative
722 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000723 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
724 DEBUG(basePtr.Val->dump(&DAG));
725 DEBUG(cerr << "\n");
726
Scott Michel053c1da2008-01-29 02:16:57 +0000727 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
728 (basePtr.getOpcode() == ISD::ADD
729 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000730 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000731 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000732 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000733 }
734
735 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000736 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000737 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
738 alignLoadVec,
739 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000740
Scott Michel9de5d0d2008-01-11 02:53:15 +0000741 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000742 LN->getSrcValue(), LN->getSrcValueOffset(),
743 LN->isVolatile(), LN->getAlignment());
744
745 return result;
746 /*UNREACHED*/
747 }
748 case ISD::PRE_INC:
749 case ISD::PRE_DEC:
750 case ISD::POST_INC:
751 case ISD::POST_DEC:
752 case ISD::LAST_INDEXED_MODE:
753 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
754 "UNINDEXED\n";
755 cerr << (unsigned) SN->getAddressingMode() << "\n";
756 abort();
757 /*NOTREACHED*/
758 }
759
760 return SDOperand();
761}
762
763/// Generate the address of a constant pool entry.
764static SDOperand
765LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
766 MVT::ValueType PtrVT = Op.getValueType();
767 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
768 Constant *C = CP->getConstVal();
769 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000770 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000771 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000772
773 if (TM.getRelocationModel() == Reloc::Static) {
774 if (!ST->usingLargeMem()) {
775 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000776 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000777 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000778 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
779 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000780 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000781 }
782 }
783
784 assert(0 &&
785 "LowerConstantPool: Relocation model other than static not supported.");
786 return SDOperand();
787}
788
789static SDOperand
790LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
791 MVT::ValueType PtrVT = Op.getValueType();
792 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
793 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
794 SDOperand Zero = DAG.getConstant(0, PtrVT);
795 const TargetMachine &TM = DAG.getTarget();
796
797 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000798 if (!ST->usingLargeMem()) {
799 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
800 } else {
801 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
802 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
803 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
804 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000805 }
806
807 assert(0 &&
808 "LowerJumpTable: Relocation model other than static not supported.");
809 return SDOperand();
810}
811
812static SDOperand
813LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
814 MVT::ValueType PtrVT = Op.getValueType();
815 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
816 GlobalValue *GV = GSDN->getGlobal();
817 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000818 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000819 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000820
821 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000822 if (!ST->usingLargeMem()) {
823 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
824 } else {
825 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
826 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
827 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
828 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000829 } else {
830 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000831 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000832 abort();
833 /*NOTREACHED*/
834 }
835
836 return SDOperand();
837}
838
839//! Custom lower i64 integer constants
840/*!
841 This code inserts all of the necessary juggling that needs to occur to load
842 a 64-bit constant into a register.
843 */
844static SDOperand
845LowerConstant(SDOperand Op, SelectionDAG &DAG) {
846 unsigned VT = Op.getValueType();
847 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
848
849 if (VT == MVT::i64) {
850 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
851 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000852 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000853 } else {
854 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000855 << MVT::getValueTypeString(VT)
856 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000857 abort();
858 /*NOTREACHED*/
859 }
860
861 return SDOperand();
862}
863
Nate Begemanccef5802008-02-14 18:43:04 +0000864//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000865static SDOperand
866LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
867 unsigned VT = Op.getValueType();
868 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
869
870 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000871 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000872
Nate Begemanccef5802008-02-14 18:43:04 +0000873 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000874 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000875 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000876 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000877 }
878
879 return SDOperand();
880}
881
Scott Michel58c58182008-01-17 20:38:41 +0000882//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
883static SDOperand
884LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
885{
886 SDOperand Cond = Op.getOperand(1);
887 MVT::ValueType CondVT = Cond.getValueType();
888 MVT::ValueType CondNVT;
889
890 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
891 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
892 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
893 Op.getOperand(0),
894 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
895 Op.getOperand(2));
896 } else
897 return SDOperand(); // Unchanged
898}
899
Scott Michel266bc8f2007-12-04 22:23:35 +0000900static SDOperand
901LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
902{
903 MachineFunction &MF = DAG.getMachineFunction();
904 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000905 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000906 SmallVector<SDOperand, 8> ArgValues;
907 SDOperand Root = Op.getOperand(0);
908 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
909
910 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
911 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
912
913 unsigned ArgOffset = SPUFrameInfo::minStackSize();
914 unsigned ArgRegIdx = 0;
915 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
916
917 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
918
919 // Add DAG nodes to load the arguments or copy them out of registers.
920 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
921 SDOperand ArgVal;
922 bool needsLoad = false;
923 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
924 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
925
926 switch (ObjectVT) {
927 default: {
928 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000929 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000930 << "\n";
931 abort();
932 }
933 case MVT::i8:
934 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000935 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
936 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000937 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
938 ++ArgRegIdx;
939 } else {
940 needsLoad = true;
941 }
942 break;
943 case MVT::i16:
944 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000945 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
946 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000947 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
948 ++ArgRegIdx;
949 } else {
950 needsLoad = true;
951 }
952 break;
953 case MVT::i32:
954 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000955 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
956 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000957 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
958 ++ArgRegIdx;
959 } else {
960 needsLoad = true;
961 }
962 break;
963 case MVT::i64:
964 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000965 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
966 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000967 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
968 ++ArgRegIdx;
969 } else {
970 needsLoad = true;
971 }
972 break;
973 case MVT::f32:
974 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000975 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
976 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000977 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
978 ++ArgRegIdx;
979 } else {
980 needsLoad = true;
981 }
982 break;
983 case MVT::f64:
984 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000985 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
986 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000987 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
988 ++ArgRegIdx;
989 } else {
990 needsLoad = true;
991 }
992 break;
993 case MVT::v2f64:
994 case MVT::v4f32:
Scott Michelad2715e2008-03-05 23:02:02 +0000995 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +0000996 case MVT::v4i32:
997 case MVT::v8i16:
998 case MVT::v16i8:
999 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001000 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1001 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001002 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
1003 ++ArgRegIdx;
1004 } else {
1005 needsLoad = true;
1006 }
1007 break;
1008 }
1009
1010 // We need to load the argument to a virtual register if we determined above
1011 // that we ran out of physical registers of the appropriate type
1012 if (needsLoad) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001013 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1014 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1015 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001016 ArgOffset += StackSlotSize;
1017 }
1018
1019 ArgValues.push_back(ArgVal);
1020 }
1021
1022 // If the function takes variable number of arguments, make a frame index for
1023 // the start of the first vararg value... for expansion of llvm.va_start.
1024 if (isVarArg) {
1025 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1026 ArgOffset);
1027 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1028 // If this function is vararg, store any remaining integer argument regs to
1029 // their spots on the stack so that they may be loaded by deferencing the
1030 // result of va_next.
1031 SmallVector<SDOperand, 8> MemOps;
1032 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001033 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1034 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001035 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1036 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1037 MemOps.push_back(Store);
1038 // Increment the address by four for the next argument to store
1039 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1040 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1041 }
1042 if (!MemOps.empty())
1043 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1044 }
1045
1046 ArgValues.push_back(Root);
1047
1048 // Return the new list of results.
1049 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1050 Op.Val->value_end());
1051 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1052}
1053
1054/// isLSAAddress - Return the immediate to use if the specified
1055/// value is representable as a LSA address.
1056static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1057 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1058 if (!C) return 0;
1059
1060 int Addr = C->getValue();
1061 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1062 (Addr << 14 >> 14) != Addr)
1063 return 0; // Top 14 bits have to be sext of immediate.
1064
1065 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1066}
1067
1068static
1069SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001070LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001071 SDOperand Chain = Op.getOperand(0);
1072#if 0
1073 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1074 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1075#endif
1076 SDOperand Callee = Op.getOperand(4);
1077 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1078 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1079 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1080 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1081
1082 // Handy pointer type
1083 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1084
1085 // Accumulate how many bytes are to be pushed on the stack, including the
1086 // linkage area, and parameter passing area. According to the SPU ABI,
1087 // we minimally need space for [LR] and [SP]
1088 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1089
1090 // Set up a copy of the stack pointer for use loading and storing any
1091 // arguments that may not fit in the registers available for argument
1092 // passing.
1093 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1094
1095 // Figure out which arguments are going to go in registers, and which in
1096 // memory.
1097 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1098 unsigned ArgRegIdx = 0;
1099
1100 // Keep track of registers passing arguments
1101 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1102 // And the arguments passed on the stack
1103 SmallVector<SDOperand, 8> MemOpChains;
1104
1105 for (unsigned i = 0; i != NumOps; ++i) {
1106 SDOperand Arg = Op.getOperand(5+2*i);
1107
1108 // PtrOff will be used to store the current argument to the stack if a
1109 // register cannot be found for it.
1110 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1111 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1112
1113 switch (Arg.getValueType()) {
1114 default: assert(0 && "Unexpected ValueType for argument!");
1115 case MVT::i32:
1116 case MVT::i64:
1117 case MVT::i128:
1118 if (ArgRegIdx != NumArgRegs) {
1119 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1120 } else {
1121 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001122 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001123 }
1124 break;
1125 case MVT::f32:
1126 case MVT::f64:
1127 if (ArgRegIdx != NumArgRegs) {
1128 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1129 } else {
1130 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001131 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001132 }
1133 break;
1134 case MVT::v4f32:
1135 case MVT::v4i32:
1136 case MVT::v8i16:
1137 case MVT::v16i8:
1138 if (ArgRegIdx != NumArgRegs) {
1139 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1140 } else {
1141 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001142 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001143 }
1144 break;
1145 }
1146 }
1147
1148 // Update number of stack bytes actually used, insert a call sequence start
1149 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1150 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1151
1152 if (!MemOpChains.empty()) {
1153 // Adjust the stack pointer for the stack arguments.
1154 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1155 &MemOpChains[0], MemOpChains.size());
1156 }
1157
1158 // Build a sequence of copy-to-reg nodes chained together with token chain
1159 // and flag operands which copy the outgoing args into the appropriate regs.
1160 SDOperand InFlag;
1161 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1162 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1163 InFlag);
1164 InFlag = Chain.getValue(1);
1165 }
1166
1167 std::vector<MVT::ValueType> NodeTys;
1168 NodeTys.push_back(MVT::Other); // Returns a chain
1169 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1170
1171 SmallVector<SDOperand, 8> Ops;
1172 unsigned CallOpc = SPUISD::CALL;
1173
1174 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1175 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1176 // node so that legalize doesn't hack it.
1177 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1178 GlobalValue *GV = G->getGlobal();
1179 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001180 SDOperand Zero = DAG.getConstant(0, PtrVT);
1181 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001182
Scott Michel9de5d0d2008-01-11 02:53:15 +00001183 if (!ST->usingLargeMem()) {
1184 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1185 // style calls, otherwise, external symbols are BRASL calls. This assumes
1186 // that declared/defined symbols are in the same compilation unit and can
1187 // be reached through PC-relative jumps.
1188 //
1189 // NOTE:
1190 // This may be an unsafe assumption for JIT and really large compilation
1191 // units.
1192 if (GV->isDeclaration()) {
1193 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1194 } else {
1195 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1196 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001197 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001198 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1199 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001200 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001201 }
1202 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1203 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001204 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001205 // If this is an absolute destination address that appears to be a legal
1206 // local store address, use the munged value.
1207 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001208 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001209
1210 Ops.push_back(Chain);
1211 Ops.push_back(Callee);
1212
1213 // Add argument registers to the end of the list so that they are known live
1214 // into the call.
1215 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1216 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1217 RegsToPass[i].second.getValueType()));
1218
1219 if (InFlag.Val)
1220 Ops.push_back(InFlag);
1221 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1222 InFlag = Chain.getValue(1);
1223
Evan Chengebaaa912008-02-05 22:44:06 +00001224 Chain = DAG.getCALLSEQ_END(Chain,
1225 DAG.getConstant(NumStackBytes, PtrVT),
1226 DAG.getConstant(0, PtrVT),
1227 InFlag);
1228 if (Op.Val->getValueType(0) != MVT::Other)
1229 InFlag = Chain.getValue(1);
1230
Scott Michel266bc8f2007-12-04 22:23:35 +00001231 SDOperand ResultVals[3];
1232 unsigned NumResults = 0;
1233 NodeTys.clear();
1234
1235 // If the call has results, copy the values out of the ret val registers.
1236 switch (Op.Val->getValueType(0)) {
1237 default: assert(0 && "Unexpected ret value!");
1238 case MVT::Other: break;
1239 case MVT::i32:
1240 if (Op.Val->getValueType(1) == MVT::i32) {
1241 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1242 ResultVals[0] = Chain.getValue(0);
1243 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1244 Chain.getValue(2)).getValue(1);
1245 ResultVals[1] = Chain.getValue(0);
1246 NumResults = 2;
1247 NodeTys.push_back(MVT::i32);
1248 } else {
1249 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1250 ResultVals[0] = Chain.getValue(0);
1251 NumResults = 1;
1252 }
1253 NodeTys.push_back(MVT::i32);
1254 break;
1255 case MVT::i64:
1256 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1257 ResultVals[0] = Chain.getValue(0);
1258 NumResults = 1;
1259 NodeTys.push_back(MVT::i64);
1260 break;
1261 case MVT::f32:
1262 case MVT::f64:
1263 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1264 InFlag).getValue(1);
1265 ResultVals[0] = Chain.getValue(0);
1266 NumResults = 1;
1267 NodeTys.push_back(Op.Val->getValueType(0));
1268 break;
1269 case MVT::v2f64:
1270 case MVT::v4f32:
1271 case MVT::v4i32:
1272 case MVT::v8i16:
1273 case MVT::v16i8:
1274 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1275 InFlag).getValue(1);
1276 ResultVals[0] = Chain.getValue(0);
1277 NumResults = 1;
1278 NodeTys.push_back(Op.Val->getValueType(0));
1279 break;
1280 }
1281
Scott Michel266bc8f2007-12-04 22:23:35 +00001282 NodeTys.push_back(MVT::Other);
1283
1284 // If the function returns void, just return the chain.
1285 if (NumResults == 0)
1286 return Chain;
1287
1288 // Otherwise, merge everything together with a MERGE_VALUES node.
1289 ResultVals[NumResults++] = Chain;
1290 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1291 ResultVals, NumResults);
1292 return Res.getValue(Op.ResNo);
1293}
1294
1295static SDOperand
1296LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1297 SmallVector<CCValAssign, 16> RVLocs;
1298 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1299 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1300 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1301 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1302
1303 // If this is the first return lowered for this function, add the regs to the
1304 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001305 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001306 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001307 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001308 }
1309
1310 SDOperand Chain = Op.getOperand(0);
1311 SDOperand Flag;
1312
1313 // Copy the result values into the output registers.
1314 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1315 CCValAssign &VA = RVLocs[i];
1316 assert(VA.isRegLoc() && "Can only return in registers!");
1317 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1318 Flag = Chain.getValue(1);
1319 }
1320
1321 if (Flag.Val)
1322 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1323 else
1324 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1325}
1326
1327
1328//===----------------------------------------------------------------------===//
1329// Vector related lowering:
1330//===----------------------------------------------------------------------===//
1331
1332static ConstantSDNode *
1333getVecImm(SDNode *N) {
1334 SDOperand OpVal(0, 0);
1335
1336 // Check to see if this buildvec has a single non-undef value in its elements.
1337 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1338 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1339 if (OpVal.Val == 0)
1340 OpVal = N->getOperand(i);
1341 else if (OpVal != N->getOperand(i))
1342 return 0;
1343 }
1344
1345 if (OpVal.Val != 0) {
1346 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1347 return CN;
1348 }
1349 }
1350
1351 return 0; // All UNDEF: use implicit def.; not Constant node
1352}
1353
1354/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1355/// and the value fits into an unsigned 18-bit constant, and if so, return the
1356/// constant
1357SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1358 MVT::ValueType ValueType) {
1359 if (ConstantSDNode *CN = getVecImm(N)) {
1360 uint64_t Value = CN->getValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001361 if (ValueType == MVT::i64) {
1362 uint64_t UValue = CN->getValue();
1363 uint32_t upper = uint32_t(UValue >> 32);
1364 uint32_t lower = uint32_t(UValue);
1365 if (upper != lower)
1366 return SDOperand();
1367 Value = Value >> 32;
1368 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001369 if (Value <= 0x3ffff)
1370 return DAG.getConstant(Value, ValueType);
1371 }
1372
1373 return SDOperand();
1374}
1375
1376/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1377/// and the value fits into a signed 16-bit constant, and if so, return the
1378/// constant
1379SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1380 MVT::ValueType ValueType) {
1381 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001382 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001383 if (ValueType == MVT::i64) {
1384 uint64_t UValue = CN->getValue();
1385 uint32_t upper = uint32_t(UValue >> 32);
1386 uint32_t lower = uint32_t(UValue);
1387 if (upper != lower)
1388 return SDOperand();
1389 Value = Value >> 32;
1390 }
Scott Michelad2715e2008-03-05 23:02:02 +00001391 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1392 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001393 }
1394 }
1395
1396 return SDOperand();
1397}
1398
1399/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1400/// and the value fits into a signed 10-bit constant, and if so, return the
1401/// constant
1402SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1403 MVT::ValueType ValueType) {
1404 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001405 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001406 if (ValueType == MVT::i64) {
1407 uint64_t UValue = CN->getValue();
1408 uint32_t upper = uint32_t(UValue >> 32);
1409 uint32_t lower = uint32_t(UValue);
1410 if (upper != lower)
1411 return SDOperand();
1412 Value = Value >> 32;
1413 }
Scott Michelad2715e2008-03-05 23:02:02 +00001414 if (isS10Constant(Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001415 return DAG.getConstant(Value, ValueType);
1416 }
1417
1418 return SDOperand();
1419}
1420
1421/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1422/// and the value fits into a signed 8-bit constant, and if so, return the
1423/// constant.
1424///
1425/// @note: The incoming vector is v16i8 because that's the only way we can load
1426/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1427/// same value.
1428SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1429 MVT::ValueType ValueType) {
1430 if (ConstantSDNode *CN = getVecImm(N)) {
1431 int Value = (int) CN->getValue();
1432 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001433 && Value <= 0xffff /* truncated from uint64_t */
1434 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001435 return DAG.getConstant(Value & 0xff, ValueType);
1436 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001437 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001438 return DAG.getConstant(Value, ValueType);
1439 }
1440
1441 return SDOperand();
1442}
1443
1444/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1445/// and the value fits into a signed 16-bit constant, and if so, return the
1446/// constant
1447SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1448 MVT::ValueType ValueType) {
1449 if (ConstantSDNode *CN = getVecImm(N)) {
1450 uint64_t Value = CN->getValue();
1451 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001452 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1453 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001454 return DAG.getConstant(Value >> 16, ValueType);
1455 }
1456
1457 return SDOperand();
1458}
1459
1460/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1461SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1462 if (ConstantSDNode *CN = getVecImm(N)) {
1463 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1464 }
1465
1466 return SDOperand();
1467}
1468
1469/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1470SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1471 if (ConstantSDNode *CN = getVecImm(N)) {
1472 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1473 }
1474
1475 return SDOperand();
1476}
1477
1478// If this is a vector of constants or undefs, get the bits. A bit in
1479// UndefBits is set if the corresponding element of the vector is an
1480// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1481// zero. Return true if this is not an array of constants, false if it is.
1482//
1483static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1484 uint64_t UndefBits[2]) {
1485 // Start with zero'd results.
1486 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1487
1488 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1489 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1490 SDOperand OpVal = BV->getOperand(i);
1491
1492 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1493 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1494
1495 uint64_t EltBits = 0;
1496 if (OpVal.getOpcode() == ISD::UNDEF) {
1497 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1498 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1499 continue;
1500 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1501 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1502 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1503 const APFloat &apf = CN->getValueAPF();
1504 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001505 ? FloatToBits(apf.convertToFloat())
1506 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001507 } else {
1508 // Nonconstant element.
1509 return true;
1510 }
1511
1512 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1513 }
1514
1515 //printf("%llx %llx %llx %llx\n",
1516 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1517 return false;
1518}
1519
1520/// If this is a splat (repetition) of a value across the whole vector, return
1521/// the smallest size that splats it. For example, "0x01010101010101..." is a
1522/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1523/// SplatSize = 1 byte.
1524static bool isConstantSplat(const uint64_t Bits128[2],
1525 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001526 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001527 uint64_t &SplatBits, uint64_t &SplatUndef,
1528 int &SplatSize) {
1529 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1530 // the same as the lower 64-bits, ignoring undefs.
1531 uint64_t Bits64 = Bits128[0] | Bits128[1];
1532 uint64_t Undef64 = Undef128[0] & Undef128[1];
1533 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1534 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1535 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1536 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1537
1538 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1539 if (MinSplatBits < 64) {
1540
1541 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1542 // undefs.
1543 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001544 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001545
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001546 // If the top 16-bits are different than the lower 16-bits, ignoring
1547 // undefs, we have an i32 splat.
1548 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1549 if (MinSplatBits < 16) {
1550 // If the top 8-bits are different than the lower 8-bits, ignoring
1551 // undefs, we have an i16 splat.
1552 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1553 // Otherwise, we have an 8-bit splat.
1554 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1555 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1556 SplatSize = 1;
1557 return true;
1558 }
1559 } else {
1560 SplatBits = Bits16;
1561 SplatUndef = Undef16;
1562 SplatSize = 2;
1563 return true;
1564 }
1565 }
1566 } else {
1567 SplatBits = Bits32;
1568 SplatUndef = Undef32;
1569 SplatSize = 4;
1570 return true;
1571 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001572 }
1573 } else {
1574 SplatBits = Bits128[0];
1575 SplatUndef = Undef128[0];
1576 SplatSize = 8;
1577 return true;
1578 }
1579 }
1580
1581 return false; // Can't be a splat if two pieces don't match.
1582}
1583
1584// If this is a case we can't handle, return null and let the default
1585// expansion code take care of it. If we CAN select this case, and if it
1586// selects to a single instruction, return Op. Otherwise, if we can codegen
1587// this case more efficiently than a constant pool load, lower it to the
1588// sequence of ops that should be used.
1589static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1590 MVT::ValueType VT = Op.getValueType();
1591 // If this is a vector of constants or undefs, get the bits. A bit in
1592 // UndefBits is set if the corresponding element of the vector is an
1593 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1594 // zero.
1595 uint64_t VectorBits[2];
1596 uint64_t UndefBits[2];
1597 uint64_t SplatBits, SplatUndef;
1598 int SplatSize;
1599 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1600 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001601 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001602 SplatBits, SplatUndef, SplatSize))
1603 return SDOperand(); // Not a constant vector, not a splat.
1604
1605 switch (VT) {
1606 default:
1607 case MVT::v4f32: {
1608 uint32_t Value32 = SplatBits;
1609 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001610 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001611 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1612 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1613 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001614 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001615 break;
1616 }
1617 case MVT::v2f64: {
1618 uint64_t f64val = SplatBits;
1619 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001620 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
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(f64val, MVT::i64);
1623 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001624 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001625 break;
1626 }
1627 case MVT::v16i8: {
1628 // 8-bit constants have to be expanded to 16-bits
1629 unsigned short Value16 = SplatBits | (SplatBits << 8);
1630 SDOperand Ops[8];
1631 for (int i = 0; i < 8; ++i)
1632 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1633 return DAG.getNode(ISD::BIT_CONVERT, VT,
1634 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1635 }
1636 case MVT::v8i16: {
1637 unsigned short Value16;
1638 if (SplatSize == 2)
1639 Value16 = (unsigned short) (SplatBits & 0xffff);
1640 else
1641 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1642 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1643 SDOperand Ops[8];
1644 for (int i = 0; i < 8; ++i) Ops[i] = T;
1645 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1646 }
1647 case MVT::v4i32: {
1648 unsigned int Value = SplatBits;
1649 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1650 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1651 }
1652 case MVT::v2i64: {
1653 uint64_t val = SplatBits;
1654 uint32_t upper = uint32_t(val >> 32);
1655 uint32_t lower = uint32_t(val);
1656
Scott Michel4cb8bd82008-03-06 04:02:54 +00001657 if (upper == lower) {
1658 // Magic constant that can be matched by IL, ILA, et. al.
1659 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1660 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michelad2715e2008-03-05 23:02:02 +00001661 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +00001662 SDOperand LO32;
1663 SDOperand HI32;
1664 SmallVector<SDOperand, 16> ShufBytes;
1665 SDOperand Result;
1666 bool upper_special, lower_special;
1667
1668 // NOTE: This code creates common-case shuffle masks that can be easily
1669 // detected as common expressions. It is not attempting to create highly
1670 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1671
1672 // Detect if the upper or lower half is a special shuffle mask pattern:
1673 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1674 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1675
1676 // Create lower vector if not a special pattern
1677 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001678 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1679 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1680 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1681 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001682 }
1683
1684 // Create upper vector if not a special pattern
1685 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001686 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1687 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1688 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1689 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001690 }
1691
1692 // If either upper or lower are special, then the two input operands are
1693 // the same (basically, one of them is a "don't care")
1694 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001695 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001696 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001697 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001698 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001699 // Unhappy situation... both upper and lower are special, so punt with
1700 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001701 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001702 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001703 Zero, Zero);
1704 }
1705
1706 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001707 for (int j = 0; j < 4; ++j) {
1708 SDOperand V;
1709 bool process_upper, process_lower;
1710 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001711
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001712 process_upper = (upper_special && (i & 1) == 0);
1713 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001714
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001715 if (process_upper || process_lower) {
1716 if ((process_upper && upper == 0)
1717 || (process_lower && lower == 0))
1718 val = 0x80;
1719 else if ((process_upper && upper == 0xffffffff)
1720 || (process_lower && lower == 0xffffffff))
1721 val = 0xc0;
1722 else if ((process_upper && upper == 0x80000000)
1723 || (process_lower && lower == 0x80000000))
1724 val = (j == 0 ? 0xe0 : 0x80);
1725 } else
1726 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001727
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001728 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1729 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001730 }
1731
1732 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001733 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1734 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001735 }
1736 }
1737 }
1738
1739 return SDOperand();
1740}
1741
1742/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1743/// which the Cell can operate. The code inspects V3 to ascertain whether the
1744/// permutation vector, V3, is monotonically increasing with one "exception"
1745/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1746/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1747/// In either case, the net result is going to eventually invoke SHUFB to
1748/// permute/shuffle the bytes from V1 and V2.
1749/// \note
1750/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1751/// control word for byte/halfword/word insertion. This takes care of a single
1752/// element move from V2 into V1.
1753/// \note
1754/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1755static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1756 SDOperand V1 = Op.getOperand(0);
1757 SDOperand V2 = Op.getOperand(1);
1758 SDOperand PermMask = Op.getOperand(2);
1759
1760 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1761
1762 // If we have a single element being moved from V1 to V2, this can be handled
1763 // using the C*[DX] compute mask instructions, but the vector elements have
1764 // to be monotonically increasing with one exception element.
1765 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1766 unsigned EltsFromV2 = 0;
1767 unsigned V2Elt = 0;
1768 unsigned V2EltIdx0 = 0;
1769 unsigned CurrElt = 0;
1770 bool monotonic = true;
1771 if (EltVT == MVT::i8)
1772 V2EltIdx0 = 16;
1773 else if (EltVT == MVT::i16)
1774 V2EltIdx0 = 8;
1775 else if (EltVT == MVT::i32)
1776 V2EltIdx0 = 4;
1777 else
1778 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1779
1780 for (unsigned i = 0, e = PermMask.getNumOperands();
1781 EltsFromV2 <= 1 && monotonic && i != e;
1782 ++i) {
1783 unsigned SrcElt;
1784 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1785 SrcElt = 0;
1786 else
1787 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1788
1789 if (SrcElt >= V2EltIdx0) {
1790 ++EltsFromV2;
1791 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1792 } else if (CurrElt != SrcElt) {
1793 monotonic = false;
1794 }
1795
1796 ++CurrElt;
1797 }
1798
1799 if (EltsFromV2 == 1 && monotonic) {
1800 // Compute mask and shuffle
1801 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001802 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1803 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001804 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1805 // Initialize temporary register to 0
1806 SDOperand InitTempReg =
1807 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1808 // Copy register's contents as index in INSERT_MASK:
1809 SDOperand ShufMaskOp =
1810 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001811 DAG.getTargetConstant(V2Elt, MVT::i32),
1812 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001813 // Use shuffle mask in SHUFB synthetic instruction:
1814 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1815 } else {
1816 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1817 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1818
1819 SmallVector<SDOperand, 16> ResultMask;
1820 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1821 unsigned SrcElt;
1822 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001823 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001824 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001825 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001826
Scott Michela59d4692008-02-23 18:41:37 +00001827 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001828 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1829 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001830 }
1831 }
1832
1833 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001834 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001835 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1836 }
1837}
1838
1839static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001840 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001841
1842 if (Op0.Val->getOpcode() == ISD::Constant) {
1843 // For a constant, build the appropriate constant vector, which will
1844 // eventually simplify to a vector register load.
1845
1846 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1847 SmallVector<SDOperand, 16> ConstVecValues;
1848 MVT::ValueType VT;
1849 size_t n_copies;
1850
1851 // Create a constant vector:
1852 switch (Op.getValueType()) {
1853 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001854 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001855 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1856 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1857 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1858 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1859 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1860 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1861 }
1862
1863 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1864 for (size_t j = 0; j < n_copies; ++j)
1865 ConstVecValues.push_back(CValue);
1866
1867 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001868 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001869 } else {
1870 // Otherwise, copy the value from one register to another:
1871 switch (Op0.getValueType()) {
1872 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1873 case MVT::i8:
1874 case MVT::i16:
1875 case MVT::i32:
1876 case MVT::i64:
1877 case MVT::f32:
1878 case MVT::f64:
1879 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1880 }
1881 }
1882
1883 return SDOperand();
1884}
1885
1886static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1887 switch (Op.getValueType()) {
1888 case MVT::v4i32: {
1889 SDOperand rA = Op.getOperand(0);
1890 SDOperand rB = Op.getOperand(1);
1891 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1892 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1893 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1894 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1895
1896 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1897 break;
1898 }
1899
1900 // Multiply two v8i16 vectors (pipeline friendly version):
1901 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1902 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1903 // c) Use SELB to select upper and lower halves from the intermediate results
1904 //
1905 // NOTE: We really want to move the FSMBI to earlier to actually get the
1906 // dual-issue. This code does manage to do this, even if it's a little on
1907 // the wacky side
1908 case MVT::v8i16: {
1909 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001910 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001911 SDOperand Chain = Op.getOperand(0);
1912 SDOperand rA = Op.getOperand(0);
1913 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001914 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1915 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001916
1917 SDOperand FSMBOp =
1918 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001919 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1920 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001921
1922 SDOperand HHProd =
1923 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001924 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001925
1926 SDOperand HHProd_v4i32 =
1927 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001928 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001929
1930 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001931 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1932 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1933 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1934 HHProd_v4i32,
1935 DAG.getConstant(16, MVT::i16))),
1936 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001937 }
1938
1939 // This M00sE is N@stI! (apologies to Monty Python)
1940 //
1941 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1942 // is to break it all apart, sign extend, and reassemble the various
1943 // intermediate products.
1944 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001945 SDOperand rA = Op.getOperand(0);
1946 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001947 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1948 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001949
1950 SDOperand LLProd =
1951 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001952 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1953 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001954
1955 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1956
1957 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1958
1959 SDOperand LHProd =
1960 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001961 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001962
Scott Michela59d4692008-02-23 18:41:37 +00001963 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1964 DAG.getConstant(0x2222, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001965
Scott Michela59d4692008-02-23 18:41:37 +00001966 SDOperand LoProdParts =
1967 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1968 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1969 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001970
1971 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1972
1973 SDOperand LoProd =
1974 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001975 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001976 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1977 LoProdMask, LoProdMask,
1978 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001979
1980 SDOperand rAH =
1981 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001982 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001983
1984 SDOperand rBH =
1985 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001986 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001987
1988 SDOperand HLProd =
1989 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001990 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1991 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001992
1993 SDOperand HHProd_1 =
1994 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001995 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1996 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1997 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1998 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001999
2000 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00002001 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2002 HLProd,
2003 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2004 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00002005
2006 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00002007 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002008
2009 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002010 DAG.getNode(ISD::OR, MVT::v4i32,
2011 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002012 }
2013
2014 default:
2015 cerr << "CellSPU: Unknown vector multiplication, got "
2016 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002017 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002018 abort();
2019 /*NOTREACHED*/
2020 }
2021
2022 return SDOperand();
2023}
2024
2025static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2026 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002027 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002028
2029 SDOperand A = Op.getOperand(0);
2030 SDOperand B = Op.getOperand(1);
2031 unsigned VT = Op.getValueType();
2032
2033 unsigned VRegBR, VRegC;
2034
2035 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002036 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2037 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002038 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002039 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2040 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002041 }
2042 // TODO: make sure we're feeding FPInterp the right arguments
2043 // Right now: fi B, frest(B)
2044
2045 // Computes BRcpl =
2046 // (Floating Interpolate (FP Reciprocal Estimate B))
2047 SDOperand BRcpl =
2048 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002049 DAG.getNode(SPUISD::FPInterp, VT, B,
2050 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002051
2052 // Computes A * BRcpl and stores in a temporary register
2053 SDOperand AxBRcpl =
2054 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002055 DAG.getNode(ISD::FMUL, VT, A,
2056 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002057 // What's the Chain variable do? It's magic!
2058 // TODO: set Chain = Op(0).getEntryNode()
2059
2060 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002061 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2062 DAG.getNode(ISD::FMUL, VT,
2063 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2064 DAG.getNode(ISD::FSUB, VT, A,
2065 DAG.getNode(ISD::FMUL, VT, B,
2066 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002067}
2068
Scott Michel266bc8f2007-12-04 22:23:35 +00002069static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2070 unsigned VT = Op.getValueType();
2071 SDOperand N = Op.getOperand(0);
2072 SDOperand Elt = Op.getOperand(1);
2073 SDOperand ShufMask[16];
2074 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2075
2076 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2077
2078 int EltNo = (int) C->getValue();
2079
2080 // sanity checks:
2081 if (VT == MVT::i8 && EltNo >= 16)
2082 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2083 else if (VT == MVT::i16 && EltNo >= 8)
2084 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2085 else if (VT == MVT::i32 && EltNo >= 4)
2086 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2087 else if (VT == MVT::i64 && EltNo >= 2)
2088 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2089
2090 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2091 // i32 and i64: Element 0 is the preferred slot
2092 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2093 }
2094
2095 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002096 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002097 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2098
2099 switch (VT) {
2100 case MVT::i8: {
2101 prefslot_begin = prefslot_end = 3;
2102 break;
2103 }
2104 case MVT::i16: {
2105 prefslot_begin = 2; prefslot_end = 3;
2106 break;
2107 }
2108 case MVT::i32: {
2109 prefslot_begin = 0; prefslot_end = 3;
2110 break;
2111 }
2112 case MVT::i64: {
2113 prefslot_begin = 0; prefslot_end = 7;
2114 break;
2115 }
2116 }
2117
Scott Michel0e5665b2007-12-19 21:17:42 +00002118 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002119 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002120
Scott Michel266bc8f2007-12-04 22:23:35 +00002121 for (int i = 0; i < 16; ++i) {
2122 // zero fill uppper part of preferred slot, don't care about the
2123 // other slots:
2124 unsigned int mask_val;
2125
2126 if (i <= prefslot_end) {
2127 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002128 ((i < prefslot_begin)
2129 ? 0x80
2130 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002131
Scott Michel0e5665b2007-12-19 21:17:42 +00002132 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002133 } else
2134 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2135 }
2136
2137 SDOperand ShufMaskVec =
2138 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002139 &ShufMask[0],
2140 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002141
2142 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002143 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2144 N, N, ShufMaskVec));
2145
Scott Michel266bc8f2007-12-04 22:23:35 +00002146}
2147
2148static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2149 SDOperand VecOp = Op.getOperand(0);
2150 SDOperand ValOp = Op.getOperand(1);
2151 SDOperand IdxOp = Op.getOperand(2);
2152 MVT::ValueType VT = Op.getValueType();
2153
2154 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2155 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2156
2157 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2158 // Use $2 because it's always 16-byte aligned and it's available:
2159 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2160
2161 SDOperand result =
2162 DAG.getNode(SPUISD::SHUFB, VT,
2163 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2164 VecOp,
2165 DAG.getNode(SPUISD::INSERT_MASK, VT,
2166 DAG.getNode(ISD::ADD, PtrVT,
2167 PtrBase,
2168 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002169 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002170
2171 return result;
2172}
2173
Scott Michela59d4692008-02-23 18:41:37 +00002174static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2175{
Scott Michel266bc8f2007-12-04 22:23:35 +00002176 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2177
2178 assert(Op.getValueType() == MVT::i8);
2179 switch (Opc) {
2180 default:
2181 assert(0 && "Unhandled i8 math operator");
2182 /*NOTREACHED*/
2183 break;
2184 case ISD::SUB: {
2185 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2186 // the result:
2187 SDOperand N1 = Op.getOperand(1);
2188 N0 = (N0.getOpcode() != ISD::Constant
2189 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2190 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2191 N1 = (N1.getOpcode() != ISD::Constant
2192 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2193 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2194 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2195 DAG.getNode(Opc, MVT::i16, N0, N1));
2196 }
2197 case ISD::ROTR:
2198 case ISD::ROTL: {
2199 SDOperand N1 = Op.getOperand(1);
2200 unsigned N1Opc;
2201 N0 = (N0.getOpcode() != ISD::Constant
2202 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2203 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2204 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2205 N1 = (N1.getOpcode() != ISD::Constant
2206 ? DAG.getNode(N1Opc, MVT::i16, N1)
2207 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2208 SDOperand ExpandArg =
2209 DAG.getNode(ISD::OR, MVT::i16, N0,
2210 DAG.getNode(ISD::SHL, MVT::i16,
2211 N0, DAG.getConstant(8, MVT::i16)));
2212 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2213 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2214 }
2215 case ISD::SRL:
2216 case ISD::SHL: {
2217 SDOperand N1 = Op.getOperand(1);
2218 unsigned N1Opc;
2219 N0 = (N0.getOpcode() != ISD::Constant
2220 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2221 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2222 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2223 N1 = (N1.getOpcode() != ISD::Constant
2224 ? DAG.getNode(N1Opc, MVT::i16, N1)
2225 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2226 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2227 DAG.getNode(Opc, MVT::i16, N0, N1));
2228 }
2229 case ISD::SRA: {
2230 SDOperand N1 = Op.getOperand(1);
2231 unsigned N1Opc;
2232 N0 = (N0.getOpcode() != ISD::Constant
2233 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2234 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2235 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2236 N1 = (N1.getOpcode() != ISD::Constant
2237 ? DAG.getNode(N1Opc, MVT::i16, N1)
2238 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2239 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2240 DAG.getNode(Opc, MVT::i16, N0, N1));
2241 }
2242 case ISD::MUL: {
2243 SDOperand N1 = Op.getOperand(1);
2244 unsigned N1Opc;
2245 N0 = (N0.getOpcode() != ISD::Constant
2246 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2247 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2248 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2249 N1 = (N1.getOpcode() != ISD::Constant
2250 ? DAG.getNode(N1Opc, MVT::i16, N1)
2251 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2252 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2253 DAG.getNode(Opc, MVT::i16, N0, N1));
2254 break;
2255 }
2256 }
2257
2258 return SDOperand();
2259}
2260
Scott Michela59d4692008-02-23 18:41:37 +00002261static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2262{
2263 MVT::ValueType VT = Op.getValueType();
2264 unsigned VecVT =
2265 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2266
2267 SDOperand Op0 = Op.getOperand(0);
2268
2269 switch (Opc) {
2270 case ISD::ZERO_EXTEND:
2271 case ISD::SIGN_EXTEND:
2272 case ISD::ANY_EXTEND: {
2273 MVT::ValueType Op0VT = Op0.getValueType();
2274 unsigned Op0VecVT =
2275 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2276
2277 assert(Op0VT == MVT::i32
2278 && "CellSPU: Zero/sign extending something other than i32");
2279
2280 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2281 ? SPUISD::ROTBYTES_RIGHT_S
2282 : SPUISD::ROTQUAD_RZ_BYTES);
2283 SDOperand PromoteScalar =
2284 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2285
2286 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2287 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2288 DAG.getNode(NewOpc, Op0VecVT,
2289 PromoteScalar,
2290 DAG.getConstant(4, MVT::i32))));
2291 }
2292
2293 case ISD::SHL: {
2294 SDOperand ShiftAmt = Op.getOperand(1);
2295 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2296 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2297 SDOperand MaskLower =
2298 DAG.getNode(SPUISD::SELB, VecVT,
2299 Op0Vec,
2300 DAG.getConstant(0, VecVT),
2301 DAG.getNode(SPUISD::FSMBI, VecVT,
2302 DAG.getConstant(0xff00ULL, MVT::i16)));
2303 SDOperand ShiftAmtBytes =
2304 DAG.getNode(ISD::SRL, ShiftAmtVT,
2305 ShiftAmt,
2306 DAG.getConstant(3, ShiftAmtVT));
2307 SDOperand ShiftAmtBits =
2308 DAG.getNode(ISD::AND, ShiftAmtVT,
2309 ShiftAmt,
2310 DAG.getConstant(7, ShiftAmtVT));
2311
2312 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2313 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2314 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2315 MaskLower, ShiftAmtBytes),
2316 ShiftAmtBits));
2317 }
2318
2319 case ISD::SRL: {
2320 unsigned VT = unsigned(Op.getValueType());
2321 SDOperand ShiftAmt = Op.getOperand(1);
2322 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2323 SDOperand ShiftAmtBytes =
2324 DAG.getNode(ISD::SRL, ShiftAmtVT,
2325 ShiftAmt,
2326 DAG.getConstant(3, ShiftAmtVT));
2327 SDOperand ShiftAmtBits =
2328 DAG.getNode(ISD::AND, ShiftAmtVT,
2329 ShiftAmt,
2330 DAG.getConstant(7, ShiftAmtVT));
2331
2332 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2333 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2334 Op0, ShiftAmtBytes),
2335 ShiftAmtBits);
2336 }
2337 }
2338
2339 return SDOperand();
2340}
2341
Scott Michel266bc8f2007-12-04 22:23:35 +00002342//! Lower byte immediate operations for v16i8 vectors:
2343static SDOperand
2344LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2345 SDOperand ConstVec;
2346 SDOperand Arg;
2347 MVT::ValueType VT = Op.getValueType();
2348
2349 ConstVec = Op.getOperand(0);
2350 Arg = Op.getOperand(1);
2351 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2352 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2353 ConstVec = ConstVec.getOperand(0);
2354 } else {
2355 ConstVec = Op.getOperand(1);
2356 Arg = Op.getOperand(0);
2357 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002358 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002359 }
2360 }
2361 }
2362
2363 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2364 uint64_t VectorBits[2];
2365 uint64_t UndefBits[2];
2366 uint64_t SplatBits, SplatUndef;
2367 int SplatSize;
2368
2369 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002370 && isConstantSplat(VectorBits, UndefBits,
2371 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2372 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002373 SDOperand tcVec[16];
2374 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2375 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2376
2377 // Turn the BUILD_VECTOR into a set of target constants:
2378 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002379 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002380
2381 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002382 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002383 }
2384 }
2385
2386 return SDOperand();
2387}
2388
2389//! Lower i32 multiplication
2390static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2391 unsigned Opc) {
2392 switch (VT) {
2393 default:
2394 cerr << "CellSPU: Unknown LowerMUL value type, got "
2395 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002396 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002397 abort();
2398 /*NOTREACHED*/
2399
2400 case MVT::i32: {
2401 SDOperand rA = Op.getOperand(0);
2402 SDOperand rB = Op.getOperand(1);
2403
2404 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002405 DAG.getNode(ISD::ADD, MVT::i32,
2406 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2407 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2408 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002409 }
2410 }
2411
2412 return SDOperand();
2413}
2414
2415//! Custom lowering for CTPOP (count population)
2416/*!
2417 Custom lowering code that counts the number ones in the input
2418 operand. SPU has such an instruction, but it counts the number of
2419 ones per byte, which then have to be accumulated.
2420*/
2421static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2422 unsigned VT = Op.getValueType();
2423 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2424
2425 switch (VT) {
2426 case MVT::i8: {
2427 SDOperand N = Op.getOperand(0);
2428 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2429
2430 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2431 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2432
2433 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2434 }
2435
2436 case MVT::i16: {
2437 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002438 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002439
Chris Lattner84bc5422007-12-31 04:13:23 +00002440 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002441
2442 SDOperand N = Op.getOperand(0);
2443 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2444 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2445 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2446
2447 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2448 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2449
2450 // CNTB_result becomes the chain to which all of the virtual registers
2451 // CNTB_reg, SUM1_reg become associated:
2452 SDOperand CNTB_result =
2453 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002454
Scott Michel266bc8f2007-12-04 22:23:35 +00002455 SDOperand CNTB_rescopy =
2456 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2457
2458 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2459
2460 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002461 DAG.getNode(ISD::ADD, MVT::i16,
2462 DAG.getNode(ISD::SRL, MVT::i16,
2463 Tmp1, Shift1),
2464 Tmp1),
2465 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002466 }
2467
2468 case MVT::i32: {
2469 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002470 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002471
Chris Lattner84bc5422007-12-31 04:13:23 +00002472 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2473 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002474
2475 SDOperand N = Op.getOperand(0);
2476 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2477 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2478 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2479 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2480
2481 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2482 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2483
2484 // CNTB_result becomes the chain to which all of the virtual registers
2485 // CNTB_reg, SUM1_reg become associated:
2486 SDOperand CNTB_result =
2487 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002488
Scott Michel266bc8f2007-12-04 22:23:35 +00002489 SDOperand CNTB_rescopy =
2490 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2491
2492 SDOperand Comp1 =
2493 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002494 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002495
2496 SDOperand Sum1 =
2497 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002498 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002499
2500 SDOperand Sum1_rescopy =
2501 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2502
2503 SDOperand Comp2 =
2504 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002505 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2506 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002507 SDOperand Sum2 =
2508 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002509 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002510
2511 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2512 }
2513
2514 case MVT::i64:
2515 break;
2516 }
2517
2518 return SDOperand();
2519}
2520
2521/// LowerOperation - Provide custom lowering hooks for some operations.
2522///
2523SDOperand
2524SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2525{
Scott Michela59d4692008-02-23 18:41:37 +00002526 unsigned Opc = (unsigned) Op.getOpcode();
2527 unsigned VT = (unsigned) Op.getValueType();
2528
2529 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002530 default: {
2531 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002532 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002533 cerr << "*Op.Val:\n";
2534 Op.Val->dump();
2535 abort();
2536 }
2537 case ISD::LOAD:
2538 case ISD::SEXTLOAD:
2539 case ISD::ZEXTLOAD:
2540 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2541 case ISD::STORE:
2542 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2543 case ISD::ConstantPool:
2544 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2545 case ISD::GlobalAddress:
2546 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2547 case ISD::JumpTable:
2548 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2549 case ISD::Constant:
2550 return LowerConstant(Op, DAG);
2551 case ISD::ConstantFP:
2552 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002553 case ISD::BRCOND:
2554 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002555 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002556 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002557 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002558 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002559 case ISD::RET:
2560 return LowerRET(Op, DAG, getTargetMachine());
2561
Scott Michela59d4692008-02-23 18:41:37 +00002562
2563 // i8, i64 math ops:
2564 case ISD::ZERO_EXTEND:
2565 case ISD::SIGN_EXTEND:
2566 case ISD::ANY_EXTEND:
Scott Michel266bc8f2007-12-04 22:23:35 +00002567 case ISD::SUB:
2568 case ISD::ROTR:
2569 case ISD::ROTL:
2570 case ISD::SRL:
2571 case ISD::SHL:
2572 case ISD::SRA:
Scott Michela59d4692008-02-23 18:41:37 +00002573 if (VT == MVT::i8)
2574 return LowerI8Math(Op, DAG, Opc);
2575 else if (VT == MVT::i64)
2576 return LowerI64Math(Op, DAG, Opc);
2577 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00002578
2579 // Vector-related lowering.
2580 case ISD::BUILD_VECTOR:
2581 return LowerBUILD_VECTOR(Op, DAG);
2582 case ISD::SCALAR_TO_VECTOR:
2583 return LowerSCALAR_TO_VECTOR(Op, DAG);
2584 case ISD::VECTOR_SHUFFLE:
2585 return LowerVECTOR_SHUFFLE(Op, DAG);
2586 case ISD::EXTRACT_VECTOR_ELT:
2587 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2588 case ISD::INSERT_VECTOR_ELT:
2589 return LowerINSERT_VECTOR_ELT(Op, DAG);
2590
2591 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2592 case ISD::AND:
2593 case ISD::OR:
2594 case ISD::XOR:
2595 return LowerByteImmed(Op, DAG);
2596
2597 // Vector and i8 multiply:
2598 case ISD::MUL:
Scott Michela59d4692008-02-23 18:41:37 +00002599 if (MVT::isVector(VT))
Scott Michel266bc8f2007-12-04 22:23:35 +00002600 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002601 else if (VT == MVT::i8)
2602 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002603 else
Scott Michela59d4692008-02-23 18:41:37 +00002604 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002605
2606 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002607 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002608 return LowerFDIVf32(Op, DAG);
2609// else if (Op.getValueType() == MVT::f64)
2610// return LowerFDIVf64(Op, DAG);
2611 else
2612 assert(0 && "Calling FDIV on unsupported MVT");
2613
2614 case ISD::CTPOP:
2615 return LowerCTPOP(Op, DAG);
2616 }
2617
2618 return SDOperand();
2619}
2620
2621//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002622// Target Optimization Hooks
2623//===----------------------------------------------------------------------===//
2624
2625SDOperand
2626SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2627{
2628#if 0
2629 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002630#endif
2631 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002632 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002633 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2634 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002635
2636 switch (N->getOpcode()) {
2637 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002638 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002639 SDOperand Op1 = N->getOperand(1);
2640
2641 if ((Op1.getOpcode() == ISD::Constant
2642 || Op1.getOpcode() == ISD::TargetConstant)
2643 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2644 SDOperand Op01 = Op0.getOperand(1);
2645 if (Op01.getOpcode() == ISD::Constant
2646 || Op01.getOpcode() == ISD::TargetConstant) {
2647 // (add <const>, (SPUindirect <arg>, <const>)) ->
2648 // (SPUindirect <arg>, <const + const>)
2649 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2650 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2651 SDOperand combinedConst =
2652 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2653 Op0.getValueType());
2654
2655 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2656 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2657 DEBUG(cerr << "With: (SPUindirect <arg>, "
2658 << CN0->getValue() + CN1->getValue() << ")\n");
2659 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2660 Op0.getOperand(0), combinedConst);
2661 }
2662 } else if ((Op0.getOpcode() == ISD::Constant
2663 || Op0.getOpcode() == ISD::TargetConstant)
2664 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2665 SDOperand Op11 = Op1.getOperand(1);
2666 if (Op11.getOpcode() == ISD::Constant
2667 || Op11.getOpcode() == ISD::TargetConstant) {
2668 // (add (SPUindirect <arg>, <const>), <const>) ->
2669 // (SPUindirect <arg>, <const + const>)
2670 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2671 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2672 SDOperand combinedConst =
2673 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2674 Op0.getValueType());
2675
2676 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2677 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2678 DEBUG(cerr << "With: (SPUindirect <arg>, "
2679 << CN0->getValue() + CN1->getValue() << ")\n");
2680
2681 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2682 Op1.getOperand(0), combinedConst);
2683 }
2684 }
Scott Michela59d4692008-02-23 18:41:37 +00002685 break;
2686 }
2687 case ISD::SIGN_EXTEND:
2688 case ISD::ZERO_EXTEND:
2689 case ISD::ANY_EXTEND: {
2690 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2691 N->getValueType(0) == Op0.getValueType()) {
2692 // (any_extend (SPUextract_elt0 <arg>)) ->
2693 // (SPUextract_elt0 <arg>)
2694 // Types must match, however...
2695 DEBUG(cerr << "Replace: ");
2696 DEBUG(N->dump(&DAG));
2697 DEBUG(cerr << "\nWith: ");
2698 DEBUG(Op0.Val->dump(&DAG));
2699 DEBUG(cerr << "\n");
2700
2701 return Op0;
2702 }
2703 break;
2704 }
2705 case SPUISD::IndirectAddr: {
2706 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2707 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2708 if (CN->getValue() == 0) {
2709 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2710 // (SPUaform <addr>, 0)
2711
2712 DEBUG(cerr << "Replace: ");
2713 DEBUG(N->dump(&DAG));
2714 DEBUG(cerr << "\nWith: ");
2715 DEBUG(Op0.Val->dump(&DAG));
2716 DEBUG(cerr << "\n");
2717
2718 return Op0;
2719 }
2720 }
2721 break;
2722 }
2723 case SPUISD::SHLQUAD_L_BITS:
2724 case SPUISD::SHLQUAD_L_BYTES:
2725 case SPUISD::VEC_SHL:
2726 case SPUISD::VEC_SRL:
2727 case SPUISD::VEC_SRA:
2728 case SPUISD::ROTQUAD_RZ_BYTES:
2729 case SPUISD::ROTQUAD_RZ_BITS: {
2730 SDOperand Op1 = N->getOperand(1);
2731
2732 if (isa<ConstantSDNode>(Op1)) {
2733 // Kill degenerate vector shifts:
2734 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2735
2736 if (CN->getValue() == 0) {
2737 Result = Op0;
2738 }
2739 }
2740 break;
2741 }
2742 case SPUISD::PROMOTE_SCALAR: {
2743 switch (Op0.getOpcode()) {
2744 default:
2745 break;
2746 case ISD::ANY_EXTEND:
2747 case ISD::ZERO_EXTEND:
2748 case ISD::SIGN_EXTEND: {
2749 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2750 // <arg>
2751 // but only if the SPUpromote_scalar and <arg> types match.
2752 SDOperand Op00 = Op0.getOperand(0);
2753 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2754 SDOperand Op000 = Op00.getOperand(0);
2755 if (Op000.getValueType() == N->getValueType(0)) {
2756 Result = Op000;
2757 }
2758 }
2759 break;
2760 }
2761 case SPUISD::EXTRACT_ELT0: {
2762 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2763 // <arg>
2764 Result = Op0.getOperand(0);
2765 break;
2766 }
2767 }
2768 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002769 }
2770 }
Scott Michel58c58182008-01-17 20:38:41 +00002771 // Otherwise, return unchanged.
Scott Michela59d4692008-02-23 18:41:37 +00002772#if 0
2773 if (Result.Val) {
2774 DEBUG(cerr << "\nReplace.SPU: ");
2775 DEBUG(N->dump(&DAG));
2776 DEBUG(cerr << "\nWith: ");
2777 DEBUG(Result.Val->dump(&DAG));
2778 DEBUG(cerr << "\n");
2779 }
2780#endif
2781
2782 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002783}
2784
2785//===----------------------------------------------------------------------===//
2786// Inline Assembly Support
2787//===----------------------------------------------------------------------===//
2788
2789/// getConstraintType - Given a constraint letter, return the type of
2790/// constraint it is for this target.
2791SPUTargetLowering::ConstraintType
2792SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2793 if (ConstraintLetter.size() == 1) {
2794 switch (ConstraintLetter[0]) {
2795 default: break;
2796 case 'b':
2797 case 'r':
2798 case 'f':
2799 case 'v':
2800 case 'y':
2801 return C_RegisterClass;
2802 }
2803 }
2804 return TargetLowering::getConstraintType(ConstraintLetter);
2805}
2806
2807std::pair<unsigned, const TargetRegisterClass*>
2808SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2809 MVT::ValueType VT) const
2810{
2811 if (Constraint.size() == 1) {
2812 // GCC RS6000 Constraint Letters
2813 switch (Constraint[0]) {
2814 case 'b': // R1-R31
2815 case 'r': // R0-R31
2816 if (VT == MVT::i64)
2817 return std::make_pair(0U, SPU::R64CRegisterClass);
2818 return std::make_pair(0U, SPU::R32CRegisterClass);
2819 case 'f':
2820 if (VT == MVT::f32)
2821 return std::make_pair(0U, SPU::R32FPRegisterClass);
2822 else if (VT == MVT::f64)
2823 return std::make_pair(0U, SPU::R64FPRegisterClass);
2824 break;
2825 case 'v':
2826 return std::make_pair(0U, SPU::GPRCRegisterClass);
2827 }
2828 }
2829
2830 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2831}
2832
Scott Michela59d4692008-02-23 18:41:37 +00002833//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002834void
2835SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002836 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002837 APInt &KnownZero,
2838 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002839 const SelectionDAG &DAG,
2840 unsigned Depth ) const {
Scott Michela59d4692008-02-23 18:41:37 +00002841 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2842
2843 switch (Op.getOpcode()) {
2844 default:
2845 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2846 break;
2847
2848#if 0
2849 case CALL:
2850 case SHUFB:
2851 case INSERT_MASK:
2852 case CNTB:
2853#endif
2854
2855 case SPUISD::PROMOTE_SCALAR: {
2856 SDOperand Op0 = Op.getOperand(0);
2857 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2858 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2859 KnownOne |= APInt(uint64_sizebits, InMask, false);
2860 break;
2861 }
2862
2863 case SPUISD::LDRESULT:
2864 case SPUISD::EXTRACT_ELT0:
2865 case SPUISD::EXTRACT_ELT0_CHAINED: {
2866 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2867 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2868 KnownOne |= APInt(uint64_sizebits, InMask, false);
2869 break;
2870 }
2871
2872#if 0
2873 case EXTRACT_I1_ZEXT:
2874 case EXTRACT_I1_SEXT:
2875 case EXTRACT_I8_ZEXT:
2876 case EXTRACT_I8_SEXT:
2877 case MPY:
2878 case MPYU:
2879 case MPYH:
2880 case MPYHH:
2881 case SHLQUAD_L_BITS:
2882 case SHLQUAD_L_BYTES:
2883 case VEC_SHL:
2884 case VEC_SRL:
2885 case VEC_SRA:
2886 case VEC_ROTL:
2887 case VEC_ROTR:
2888 case ROTQUAD_RZ_BYTES:
2889 case ROTQUAD_RZ_BITS:
2890 case ROTBYTES_RIGHT_S:
2891 case ROTBYTES_LEFT:
2892 case ROTBYTES_LEFT_CHAINED:
2893 case FSMBI:
2894 case SELB:
2895 case SFPConstant:
2896 case FPInterp:
2897 case FPRecipEst:
2898 case SEXT32TO64:
2899#endif
2900 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002901}
2902
2903// LowerAsmOperandForConstraint
2904void
2905SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2906 char ConstraintLetter,
2907 std::vector<SDOperand> &Ops,
2908 SelectionDAG &DAG) {
2909 // Default, for the time being, to the base class handler
2910 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2911}
2912
2913/// isLegalAddressImmediate - Return true if the integer value can be used
2914/// as the offset of the target addressing mode.
2915bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2916 // SPU's addresses are 256K:
2917 return (V > -(1 << 18) && V < (1 << 18) - 1);
2918}
2919
2920bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2921 return false;
2922}