blob: 6d2a9f3d30bf31e827996f7b5e8b26153402dd4b [file] [log] [blame]
Scott Michel8efdca42007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-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 Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel8efdca42007-12-04 22:23:35 +000024#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +000042 const MVT::ValueType valtype;
43 const int prefslot_byte;
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +000064 retval = valtype_map + i;
65 break;
Scott Michel8efdca42007-12-04 22:23:35 +000066 }
67 }
68
69#ifndef NDEBUG
70 if (retval == 0) {
71 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel5a6f17b2008-01-30 02:55:46 +000072 << MVT::getValueTypeString(VT)
73 << "\n";
Scott Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +000085 address, external symbol, constant pool) or an A-form
Scott Michel8efdca42007-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 Michel8efdca42007-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 Michel8efdca42007-12-04 22:23:35 +000098 || Opc == ISD::TargetJumpTable
99 || Opc == ISD::TargetConstantPool
100 || Opc == ISD::TargetExternalSymbol
Scott Micheldbac4cf2008-01-11 02:53:15 +0000101 || Opc == SPUISD::AFormAddr);
Scott Michel8efdca42007-12-04 22:23:35 +0000102 }
Scott Michel394e26d2008-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 Michel5a6f17b2008-01-30 02:55:46 +0000109 || Opc == SPUISD::LDRESULT);
Scott Michel394e26d2008-01-17 20:38:41 +0000110 }
Scott Michel8efdca42007-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 Michel438be252007-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 Michel8efdca42007-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 Michel394e26d2008-01-17 20:38:41 +0000137 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +0000138 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
139 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattner3bc08502008-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 Michel8efdca42007-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 Lattner3bc08502008-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 Michel8efdca42007-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 Begeman78125042008-02-14 18:43:04 +0000161 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-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 Michel394e26d2008-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 Michel8efdca42007-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 Lenharth0531ec52008-02-16 14:46:26 +0000184 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
185
Scott Michel8efdca42007-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 Michel97872d32008-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 Michel8efdca42007-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 Michel6baba072008-03-05 23:02:02 +0000246 // SPU has a version of select
Scott Michel8efdca42007-12-04 22:23:35 +0000247 setOperationAction(ISD::SELECT, MVT::i1, Expand);
248 setOperationAction(ISD::SELECT, MVT::i8, Expand);
Scott Michel6baba072008-03-05 23:02:02 +0000249 setOperationAction(ISD::SELECT, MVT::i16, Legal);
250 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel8efdca42007-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 Michel6baba072008-03-05 23:02:02 +0000255 setOperationAction(ISD::SETCC, MVT::i1, Expand);
256 setOperationAction(ISD::SETCC, MVT::i8, Expand);
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);
262
Scott Michel97872d32008-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 Michel8efdca42007-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 Michel754d8662007-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 Michel8efdca42007-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 Michelf9f42e62008-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 Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000381
Scott Michel8efdca42007-12-04 22:23:35 +0000382 setSetCCResultType(MVT::i32);
383 setShiftAmountType(MVT::i32);
384 setSetCCResultContents(ZeroOrOneSetCCResult);
385
386 setStackPointerRegisterToSaveRestore(SPU::R1);
387
388 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000389 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000390 setTargetDAGCombine(ISD::ZERO_EXTEND);
391 setTargetDAGCombine(ISD::SIGN_EXTEND);
392 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel8efdca42007-12-04 22:23:35 +0000393
394 computeRegisterProperties();
395}
396
397const char *
398SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
399{
400 if (node_names.empty()) {
401 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
402 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
403 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
404 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Micheldbac4cf2008-01-11 02:53:15 +0000405 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000406 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-12-04 22:23:35 +0000407 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
408 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
409 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
410 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
411 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
412 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
413 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
414 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
415 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
416 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
417 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
418 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
419 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
420 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
421 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
422 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michel97872d32008-02-23 18:41:37 +0000423 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
424 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel8efdca42007-12-04 22:23:35 +0000425 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
426 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
427 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
428 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
429 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michel97872d32008-02-23 18:41:37 +0000430 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
431 "SPUISD::ROTQUAD_RZ_BYTES";
432 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
433 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel8efdca42007-12-04 22:23:35 +0000434 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
435 "SPUISD::ROTBYTES_RIGHT_S";
436 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
437 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
438 "SPUISD::ROTBYTES_LEFT_CHAINED";
439 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
440 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel8efdca42007-12-04 22:23:35 +0000441 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
442 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
443 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
444 }
445
446 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
447
448 return ((i != node_names.end()) ? i->second : 0);
449}
450
451//===----------------------------------------------------------------------===//
452// Calling convention code:
453//===----------------------------------------------------------------------===//
454
455#include "SPUGenCallingConv.inc"
456
457//===----------------------------------------------------------------------===//
458// LowerOperation implementation
459//===----------------------------------------------------------------------===//
460
Scott Micheldbac4cf2008-01-11 02:53:15 +0000461/// Aligned load common code for CellSPU
462/*!
463 \param[in] Op The SelectionDAG load or store operand
464 \param[in] DAG The selection DAG
465 \param[in] ST CellSPU subtarget information structure
466 \param[in,out] alignment Caller initializes this to the load or store node's
467 value from getAlignment(), may be updated while generating the aligned load
468 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
469 offset (divisible by 16, modulo 16 == 0)
470 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
471 offset of the preferred slot (modulo 16 != 0)
472 \param[in,out] VT Caller initializes this value type to the the load or store
473 node's loaded or stored value type; may be updated if an i1-extended load or
474 store.
475 \param[out] was16aligned true if the base pointer had 16-byte alignment,
476 otherwise false. Can help to determine if the chunk needs to be rotated.
477
478 Both load and store lowering load a block of data aligned on a 16-byte
479 boundary. This is the common aligned load code shared between both.
480 */
481static SDOperand
482AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
483 LSBaseSDNode *LSN,
484 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner2dff5dd2008-01-12 22:54:07 +0000485 MVT::ValueType &VT, bool &was16aligned)
Scott Micheldbac4cf2008-01-11 02:53:15 +0000486{
487 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
488 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
489 SDOperand basePtr = LSN->getBasePtr();
490 SDOperand chain = LSN->getChain();
491
492 if (basePtr.getOpcode() == ISD::ADD) {
493 SDOperand Op1 = basePtr.Val->getOperand(1);
494
495 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel394e26d2008-01-17 20:38:41 +0000496 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000497
498 alignOffs = (int) CN->getValue();
499 prefSlotOffs = (int) (alignOffs & 0xf);
500
501 // Adjust the rotation amount to ensure that the final result ends up in
502 // the preferred slot:
503 prefSlotOffs -= vtm->prefslot_byte;
504 basePtr = basePtr.getOperand(0);
505
Scott Michel394e26d2008-01-17 20:38:41 +0000506 // Loading from memory, can we adjust alignment?
507 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
508 SDOperand APtr = basePtr.getOperand(0);
509 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
510 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
511 alignment = GSDN->getGlobal()->getAlignment();
512 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000513 }
514 } else {
515 alignOffs = 0;
516 prefSlotOffs = -vtm->prefslot_byte;
517 }
518 } else {
519 alignOffs = 0;
520 prefSlotOffs = -vtm->prefslot_byte;
521 }
522
523 if (alignment == 16) {
524 // Realign the base pointer as a D-Form address:
525 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel394e26d2008-01-17 20:38:41 +0000526 basePtr = DAG.getNode(ISD::ADD, PtrVT,
527 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000528 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000529 }
530
531 // Emit the vector load:
532 was16aligned = true;
533 return DAG.getLoad(MVT::v16i8, chain, basePtr,
534 LSN->getSrcValue(), LSN->getSrcValueOffset(),
535 LSN->isVolatile(), 16);
536 }
537
538 // Unaligned load or we're using the "large memory" model, which means that
539 // we have to be very pessimistic:
Scott Michel394e26d2008-01-17 20:38:41 +0000540 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000541 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000542 }
543
544 // Add the offset
Scott Michelf9f42e62008-01-29 02:16:57 +0000545 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000546 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000547 was16aligned = false;
548 return DAG.getLoad(MVT::v16i8, chain, basePtr,
549 LSN->getSrcValue(), LSN->getSrcValueOffset(),
550 LSN->isVolatile(), 16);
551}
552
Scott Michel8efdca42007-12-04 22:23:35 +0000553/// Custom lower loads for CellSPU
554/*!
555 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
556 within a 16-byte block, we have to rotate to extract the requested element.
557 */
558static SDOperand
559LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
560 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +0000561 SDOperand the_chain = LN->getChain();
Dan Gohman9a4c92c2008-01-30 00:15:11 +0000562 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel8efdca42007-12-04 22:23:35 +0000563 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000564 ISD::LoadExtType ExtType = LN->getExtensionType();
565 unsigned alignment = LN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000566 SDOperand Ops[8];
567
Scott Michel8efdca42007-12-04 22:23:35 +0000568 switch (LN->getAddressingMode()) {
569 case ISD::UNINDEXED: {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000570 int offset, rotamt;
571 bool was16aligned;
572 SDOperand result =
573 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel8efdca42007-12-04 22:23:35 +0000574
Scott Micheldbac4cf2008-01-11 02:53:15 +0000575 if (result.Val == 0)
Scott Michel8efdca42007-12-04 22:23:35 +0000576 return result;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000577
578 the_chain = result.getValue(1);
579 // Rotate the chunk if necessary
580 if (rotamt < 0)
581 rotamt += 16;
Scott Michelabc58242008-01-11 21:01:19 +0000582 if (rotamt != 0 || !was16aligned) {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000583 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
584
Scott Michel394e26d2008-01-17 20:38:41 +0000585 Ops[0] = the_chain;
586 Ops[1] = result;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000587 if (was16aligned) {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000588 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
589 } else {
Scott Michel5a6f17b2008-01-30 02:55:46 +0000590 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000591 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michelabc58242008-01-11 21:01:19 +0000592 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel5a6f17b2008-01-30 02:55:46 +0000593 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000594 }
595
596 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
597 the_chain = result.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000598 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000599
600 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
601 SDVTList scalarvts;
602 MVT::ValueType vecVT = MVT::v16i8;
603
604 // Convert the loaded v16i8 vector to the appropriate vector type
605 // specified by the operand:
606 if (OpVT == VT) {
607 if (VT != MVT::i1)
608 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
609 } else
610 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
611
612 Ops[0] = the_chain;
613 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
614 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
615 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
616 the_chain = result.getValue(1);
617 } else {
618 // Handle the sign and zero-extending loads for i1 and i8:
619 unsigned NewOpC;
620
621 if (ExtType == ISD::SEXTLOAD) {
622 NewOpC = (OpVT == MVT::i1
623 ? SPUISD::EXTRACT_I1_SEXT
624 : SPUISD::EXTRACT_I8_SEXT);
625 } else {
626 assert(ExtType == ISD::ZEXTLOAD);
627 NewOpC = (OpVT == MVT::i1
628 ? SPUISD::EXTRACT_I1_ZEXT
629 : SPUISD::EXTRACT_I8_ZEXT);
630 }
631
632 result = DAG.getNode(NewOpC, OpVT, result);
633 }
634
635 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel5a6f17b2008-01-30 02:55:46 +0000636 SDOperand retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000637 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000638 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000639 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000640
Scott Michel394e26d2008-01-17 20:38:41 +0000641 result = DAG.getNode(SPUISD::LDRESULT, retvts,
642 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000643 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000644 }
645 case ISD::PRE_INC:
646 case ISD::PRE_DEC:
647 case ISD::POST_INC:
648 case ISD::POST_DEC:
649 case ISD::LAST_INDEXED_MODE:
650 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
651 "UNINDEXED\n";
652 cerr << (unsigned) LN->getAddressingMode() << "\n";
653 abort();
654 /*NOTREACHED*/
655 }
656
657 return SDOperand();
658}
659
660/// Custom lower stores for CellSPU
661/*!
662 All CellSPU stores are aligned to 16-byte boundaries, so for elements
663 within a 16-byte block, we have to generate a shuffle to insert the
664 requested element into its place, then store the resulting block.
665 */
666static SDOperand
667LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
668 StoreSDNode *SN = cast<StoreSDNode>(Op);
669 SDOperand Value = SN->getValue();
670 MVT::ValueType VT = Value.getValueType();
Dan Gohman9a4c92c2008-01-30 00:15:11 +0000671 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel8efdca42007-12-04 22:23:35 +0000672 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000673 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000674
675 switch (SN->getAddressingMode()) {
676 case ISD::UNINDEXED: {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000677 int chunk_offset, slot_offset;
678 bool was16aligned;
Scott Michel8efdca42007-12-04 22:23:35 +0000679
680 // The vector type we really want to load from the 16-byte chunk, except
681 // in the case of MVT::i1, which has to be v16i8.
Scott Micheldbac4cf2008-01-11 02:53:15 +0000682 unsigned vecVT, stVecVT = MVT::v16i8;
683
Scott Michel8efdca42007-12-04 22:23:35 +0000684 if (StVT != MVT::i1)
685 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel8efdca42007-12-04 22:23:35 +0000686 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
687
Scott Micheldbac4cf2008-01-11 02:53:15 +0000688 SDOperand alignLoadVec =
689 AlignedLoad(Op, DAG, ST, SN, alignment,
690 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel8efdca42007-12-04 22:23:35 +0000691
Scott Micheldbac4cf2008-01-11 02:53:15 +0000692 if (alignLoadVec.Val == 0)
693 return alignLoadVec;
Scott Michel8efdca42007-12-04 22:23:35 +0000694
Scott Micheldbac4cf2008-01-11 02:53:15 +0000695 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
696 SDOperand basePtr = LN->getBasePtr();
697 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000698 SDOperand theValue = SN->getValue();
699 SDOperand result;
700
701 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000702 && (theValue.getOpcode() == ISD::AssertZext
703 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000704 // Drill down and get the value for zero- and sign-extended
705 // quantities
706 theValue = theValue.getOperand(0);
707 }
708
Scott Micheldbac4cf2008-01-11 02:53:15 +0000709 chunk_offset &= 0xf;
Scott Michel8efdca42007-12-04 22:23:35 +0000710
Scott Micheldbac4cf2008-01-11 02:53:15 +0000711 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
712 SDOperand insertEltPtr;
713 SDOperand insertEltOp;
714
715 // If the base pointer is already a D-form address, then just create
716 // a new D-form address with a slot offset and the orignal base pointer.
717 // Otherwise generate a D-form address with the slot offset relative
718 // to the stack pointer, which is always aligned.
Scott Michelabc58242008-01-11 21:01:19 +0000719 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
720 DEBUG(basePtr.Val->dump(&DAG));
721 DEBUG(cerr << "\n");
722
Scott Michelf9f42e62008-01-29 02:16:57 +0000723 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
724 (basePtr.getOpcode() == ISD::ADD
725 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michelabc58242008-01-11 21:01:19 +0000726 insertEltPtr = basePtr;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000727 } else {
Scott Michelf9f42e62008-01-29 02:16:57 +0000728 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000729 }
730
731 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel8efdca42007-12-04 22:23:35 +0000732 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000733 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
734 alignLoadVec,
735 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000736
Scott Micheldbac4cf2008-01-11 02:53:15 +0000737 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000738 LN->getSrcValue(), LN->getSrcValueOffset(),
739 LN->isVolatile(), LN->getAlignment());
740
741 return result;
742 /*UNREACHED*/
743 }
744 case ISD::PRE_INC:
745 case ISD::PRE_DEC:
746 case ISD::POST_INC:
747 case ISD::POST_DEC:
748 case ISD::LAST_INDEXED_MODE:
749 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
750 "UNINDEXED\n";
751 cerr << (unsigned) SN->getAddressingMode() << "\n";
752 abort();
753 /*NOTREACHED*/
754 }
755
756 return SDOperand();
757}
758
759/// Generate the address of a constant pool entry.
760static SDOperand
761LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
762 MVT::ValueType PtrVT = Op.getValueType();
763 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
764 Constant *C = CP->getConstVal();
765 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel8efdca42007-12-04 22:23:35 +0000766 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000767 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000768
769 if (TM.getRelocationModel() == Reloc::Static) {
770 if (!ST->usingLargeMem()) {
771 // Just return the SDOperand with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000772 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000773 } else {
Scott Michel8efdca42007-12-04 22:23:35 +0000774 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
775 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000776 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000777 }
778 }
779
780 assert(0 &&
781 "LowerConstantPool: Relocation model other than static not supported.");
782 return SDOperand();
783}
784
785static SDOperand
786LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
787 MVT::ValueType PtrVT = Op.getValueType();
788 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
789 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
790 SDOperand Zero = DAG.getConstant(0, PtrVT);
791 const TargetMachine &TM = DAG.getTarget();
792
793 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000794 if (!ST->usingLargeMem()) {
795 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
796 } else {
797 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
798 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
799 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
800 }
Scott Michel8efdca42007-12-04 22:23:35 +0000801 }
802
803 assert(0 &&
804 "LowerJumpTable: Relocation model other than static not supported.");
805 return SDOperand();
806}
807
808static SDOperand
809LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
810 MVT::ValueType PtrVT = Op.getValueType();
811 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
812 GlobalValue *GV = GSDN->getGlobal();
813 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000814 const TargetMachine &TM = DAG.getTarget();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000815 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000816
817 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000818 if (!ST->usingLargeMem()) {
819 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
820 } else {
821 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
822 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
823 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
824 }
Scott Michel8efdca42007-12-04 22:23:35 +0000825 } else {
826 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000827 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000828 abort();
829 /*NOTREACHED*/
830 }
831
832 return SDOperand();
833}
834
835//! Custom lower i64 integer constants
836/*!
837 This code inserts all of the necessary juggling that needs to occur to load
838 a 64-bit constant into a register.
839 */
840static SDOperand
841LowerConstant(SDOperand Op, SelectionDAG &DAG) {
842 unsigned VT = Op.getValueType();
843 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
844
845 if (VT == MVT::i64) {
846 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
847 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000848 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +0000849 } else {
850 cerr << "LowerConstant: unhandled constant type "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000851 << MVT::getValueTypeString(VT)
852 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000853 abort();
854 /*NOTREACHED*/
855 }
856
857 return SDOperand();
858}
859
Nate Begeman78125042008-02-14 18:43:04 +0000860//! Custom lower double precision floating point constants
Scott Michel8efdca42007-12-04 22:23:35 +0000861static SDOperand
862LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
863 unsigned VT = Op.getValueType();
864 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
865
866 assert((FP != 0) &&
Scott Michel5a6f17b2008-01-30 02:55:46 +0000867 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel8efdca42007-12-04 22:23:35 +0000868
Nate Begeman78125042008-02-14 18:43:04 +0000869 if (VT == MVT::f64) {
Scott Michel11e88bb2007-12-19 20:15:47 +0000870 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel8efdca42007-12-04 22:23:35 +0000871 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000872 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel8efdca42007-12-04 22:23:35 +0000873 }
874
875 return SDOperand();
876}
877
Scott Michel394e26d2008-01-17 20:38:41 +0000878//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
879static SDOperand
880LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
881{
882 SDOperand Cond = Op.getOperand(1);
883 MVT::ValueType CondVT = Cond.getValueType();
884 MVT::ValueType CondNVT;
885
886 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
887 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
888 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
889 Op.getOperand(0),
890 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
891 Op.getOperand(2));
892 } else
893 return SDOperand(); // Unchanged
894}
895
Scott Michel8efdca42007-12-04 22:23:35 +0000896static SDOperand
897LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
898{
899 MachineFunction &MF = DAG.getMachineFunction();
900 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000901 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +0000902 SmallVector<SDOperand, 8> ArgValues;
903 SDOperand Root = Op.getOperand(0);
904 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
905
906 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
907 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
908
909 unsigned ArgOffset = SPUFrameInfo::minStackSize();
910 unsigned ArgRegIdx = 0;
911 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
912
913 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
914
915 // Add DAG nodes to load the arguments or copy them out of registers.
916 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
917 SDOperand ArgVal;
918 bool needsLoad = false;
919 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
920 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
921
922 switch (ObjectVT) {
923 default: {
924 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000925 << MVT::getValueTypeString(ObjectVT)
Scott Michel8efdca42007-12-04 22:23:35 +0000926 << "\n";
927 abort();
928 }
929 case MVT::i8:
930 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000931 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
932 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000933 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
934 ++ArgRegIdx;
935 } else {
936 needsLoad = true;
937 }
938 break;
939 case MVT::i16:
940 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000941 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
942 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000943 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
944 ++ArgRegIdx;
945 } else {
946 needsLoad = true;
947 }
948 break;
949 case MVT::i32:
950 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000951 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
952 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000953 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
954 ++ArgRegIdx;
955 } else {
956 needsLoad = true;
957 }
958 break;
959 case MVT::i64:
960 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000961 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
962 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000963 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
964 ++ArgRegIdx;
965 } else {
966 needsLoad = true;
967 }
968 break;
969 case MVT::f32:
970 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000971 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
972 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000973 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
974 ++ArgRegIdx;
975 } else {
976 needsLoad = true;
977 }
978 break;
979 case MVT::f64:
980 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000981 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
982 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000983 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
984 ++ArgRegIdx;
985 } else {
986 needsLoad = true;
987 }
988 break;
989 case MVT::v2f64:
990 case MVT::v4f32:
Scott Michel6baba072008-03-05 23:02:02 +0000991 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +0000992 case MVT::v4i32:
993 case MVT::v8i16:
994 case MVT::v16i8:
995 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000996 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
997 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000998 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
999 ++ArgRegIdx;
1000 } else {
1001 needsLoad = true;
1002 }
1003 break;
1004 }
1005
1006 // We need to load the argument to a virtual register if we determined above
1007 // that we ran out of physical registers of the appropriate type
1008 if (needsLoad) {
Chris Lattner60069452008-02-13 07:35:30 +00001009 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1010 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1011 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +00001012 ArgOffset += StackSlotSize;
1013 }
1014
1015 ArgValues.push_back(ArgVal);
1016 }
1017
1018 // If the function takes variable number of arguments, make a frame index for
1019 // the start of the first vararg value... for expansion of llvm.va_start.
1020 if (isVarArg) {
1021 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1022 ArgOffset);
1023 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1024 // If this function is vararg, store any remaining integer argument regs to
1025 // their spots on the stack so that they may be loaded by deferencing the
1026 // result of va_next.
1027 SmallVector<SDOperand, 8> MemOps;
1028 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner1b989192007-12-31 04:13:23 +00001029 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1030 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +00001031 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1032 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1033 MemOps.push_back(Store);
1034 // Increment the address by four for the next argument to store
1035 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1036 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1037 }
1038 if (!MemOps.empty())
1039 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1040 }
1041
1042 ArgValues.push_back(Root);
1043
1044 // Return the new list of results.
1045 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1046 Op.Val->value_end());
1047 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1048}
1049
1050/// isLSAAddress - Return the immediate to use if the specified
1051/// value is representable as a LSA address.
1052static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1053 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1054 if (!C) return 0;
1055
1056 int Addr = C->getValue();
1057 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1058 (Addr << 14 >> 14) != Addr)
1059 return 0; // Top 14 bits have to be sext of immediate.
1060
1061 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1062}
1063
1064static
1065SDOperand
Scott Micheldbac4cf2008-01-11 02:53:15 +00001066LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +00001067 SDOperand Chain = Op.getOperand(0);
1068#if 0
1069 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1070 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1071#endif
1072 SDOperand Callee = Op.getOperand(4);
1073 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1074 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1075 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1076 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1077
1078 // Handy pointer type
1079 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1080
1081 // Accumulate how many bytes are to be pushed on the stack, including the
1082 // linkage area, and parameter passing area. According to the SPU ABI,
1083 // we minimally need space for [LR] and [SP]
1084 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1085
1086 // Set up a copy of the stack pointer for use loading and storing any
1087 // arguments that may not fit in the registers available for argument
1088 // passing.
1089 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1090
1091 // Figure out which arguments are going to go in registers, and which in
1092 // memory.
1093 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1094 unsigned ArgRegIdx = 0;
1095
1096 // Keep track of registers passing arguments
1097 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1098 // And the arguments passed on the stack
1099 SmallVector<SDOperand, 8> MemOpChains;
1100
1101 for (unsigned i = 0; i != NumOps; ++i) {
1102 SDOperand Arg = Op.getOperand(5+2*i);
1103
1104 // PtrOff will be used to store the current argument to the stack if a
1105 // register cannot be found for it.
1106 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1107 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1108
1109 switch (Arg.getValueType()) {
1110 default: assert(0 && "Unexpected ValueType for argument!");
1111 case MVT::i32:
1112 case MVT::i64:
1113 case MVT::i128:
1114 if (ArgRegIdx != NumArgRegs) {
1115 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1116 } else {
1117 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001118 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001119 }
1120 break;
1121 case MVT::f32:
1122 case MVT::f64:
1123 if (ArgRegIdx != NumArgRegs) {
1124 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1125 } else {
1126 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001127 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001128 }
1129 break;
1130 case MVT::v4f32:
1131 case MVT::v4i32:
1132 case MVT::v8i16:
1133 case MVT::v16i8:
1134 if (ArgRegIdx != NumArgRegs) {
1135 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1136 } else {
1137 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001138 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001139 }
1140 break;
1141 }
1142 }
1143
1144 // Update number of stack bytes actually used, insert a call sequence start
1145 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1146 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1147
1148 if (!MemOpChains.empty()) {
1149 // Adjust the stack pointer for the stack arguments.
1150 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1151 &MemOpChains[0], MemOpChains.size());
1152 }
1153
1154 // Build a sequence of copy-to-reg nodes chained together with token chain
1155 // and flag operands which copy the outgoing args into the appropriate regs.
1156 SDOperand InFlag;
1157 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1158 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1159 InFlag);
1160 InFlag = Chain.getValue(1);
1161 }
1162
1163 std::vector<MVT::ValueType> NodeTys;
1164 NodeTys.push_back(MVT::Other); // Returns a chain
1165 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1166
1167 SmallVector<SDOperand, 8> Ops;
1168 unsigned CallOpc = SPUISD::CALL;
1169
1170 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1171 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1172 // node so that legalize doesn't hack it.
1173 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1174 GlobalValue *GV = G->getGlobal();
1175 unsigned CalleeVT = Callee.getValueType();
Scott Micheldbac4cf2008-01-11 02:53:15 +00001176 SDOperand Zero = DAG.getConstant(0, PtrVT);
1177 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001178
Scott Micheldbac4cf2008-01-11 02:53:15 +00001179 if (!ST->usingLargeMem()) {
1180 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1181 // style calls, otherwise, external symbols are BRASL calls. This assumes
1182 // that declared/defined symbols are in the same compilation unit and can
1183 // be reached through PC-relative jumps.
1184 //
1185 // NOTE:
1186 // This may be an unsafe assumption for JIT and really large compilation
1187 // units.
1188 if (GV->isDeclaration()) {
1189 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1190 } else {
1191 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1192 }
Scott Michel8efdca42007-12-04 22:23:35 +00001193 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001194 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1195 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001196 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001197 }
1198 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1199 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Micheldbac4cf2008-01-11 02:53:15 +00001200 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001201 // If this is an absolute destination address that appears to be a legal
1202 // local store address, use the munged value.
1203 Callee = SDOperand(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001204 }
Scott Michel8efdca42007-12-04 22:23:35 +00001205
1206 Ops.push_back(Chain);
1207 Ops.push_back(Callee);
1208
1209 // Add argument registers to the end of the list so that they are known live
1210 // into the call.
1211 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1212 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1213 RegsToPass[i].second.getValueType()));
1214
1215 if (InFlag.Val)
1216 Ops.push_back(InFlag);
1217 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1218 InFlag = Chain.getValue(1);
1219
Evan Cheng07322bb2008-02-05 22:44:06 +00001220 Chain = DAG.getCALLSEQ_END(Chain,
1221 DAG.getConstant(NumStackBytes, PtrVT),
1222 DAG.getConstant(0, PtrVT),
1223 InFlag);
1224 if (Op.Val->getValueType(0) != MVT::Other)
1225 InFlag = Chain.getValue(1);
1226
Scott Michel8efdca42007-12-04 22:23:35 +00001227 SDOperand ResultVals[3];
1228 unsigned NumResults = 0;
1229 NodeTys.clear();
1230
1231 // If the call has results, copy the values out of the ret val registers.
1232 switch (Op.Val->getValueType(0)) {
1233 default: assert(0 && "Unexpected ret value!");
1234 case MVT::Other: break;
1235 case MVT::i32:
1236 if (Op.Val->getValueType(1) == MVT::i32) {
1237 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1238 ResultVals[0] = Chain.getValue(0);
1239 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1240 Chain.getValue(2)).getValue(1);
1241 ResultVals[1] = Chain.getValue(0);
1242 NumResults = 2;
1243 NodeTys.push_back(MVT::i32);
1244 } else {
1245 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1246 ResultVals[0] = Chain.getValue(0);
1247 NumResults = 1;
1248 }
1249 NodeTys.push_back(MVT::i32);
1250 break;
1251 case MVT::i64:
1252 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1253 ResultVals[0] = Chain.getValue(0);
1254 NumResults = 1;
1255 NodeTys.push_back(MVT::i64);
1256 break;
1257 case MVT::f32:
1258 case MVT::f64:
1259 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1260 InFlag).getValue(1);
1261 ResultVals[0] = Chain.getValue(0);
1262 NumResults = 1;
1263 NodeTys.push_back(Op.Val->getValueType(0));
1264 break;
1265 case MVT::v2f64:
1266 case MVT::v4f32:
1267 case MVT::v4i32:
1268 case MVT::v8i16:
1269 case MVT::v16i8:
1270 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1271 InFlag).getValue(1);
1272 ResultVals[0] = Chain.getValue(0);
1273 NumResults = 1;
1274 NodeTys.push_back(Op.Val->getValueType(0));
1275 break;
1276 }
1277
Scott Michel8efdca42007-12-04 22:23:35 +00001278 NodeTys.push_back(MVT::Other);
1279
1280 // If the function returns void, just return the chain.
1281 if (NumResults == 0)
1282 return Chain;
1283
1284 // Otherwise, merge everything together with a MERGE_VALUES node.
1285 ResultVals[NumResults++] = Chain;
1286 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1287 ResultVals, NumResults);
1288 return Res.getValue(Op.ResNo);
1289}
1290
1291static SDOperand
1292LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1293 SmallVector<CCValAssign, 16> RVLocs;
1294 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1295 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1296 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1297 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1298
1299 // If this is the first return lowered for this function, add the regs to the
1300 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001301 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001302 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001303 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001304 }
1305
1306 SDOperand Chain = Op.getOperand(0);
1307 SDOperand Flag;
1308
1309 // Copy the result values into the output registers.
1310 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1311 CCValAssign &VA = RVLocs[i];
1312 assert(VA.isRegLoc() && "Can only return in registers!");
1313 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1314 Flag = Chain.getValue(1);
1315 }
1316
1317 if (Flag.Val)
1318 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1319 else
1320 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1321}
1322
1323
1324//===----------------------------------------------------------------------===//
1325// Vector related lowering:
1326//===----------------------------------------------------------------------===//
1327
1328static ConstantSDNode *
1329getVecImm(SDNode *N) {
1330 SDOperand OpVal(0, 0);
1331
1332 // Check to see if this buildvec has a single non-undef value in its elements.
1333 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1334 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1335 if (OpVal.Val == 0)
1336 OpVal = N->getOperand(i);
1337 else if (OpVal != N->getOperand(i))
1338 return 0;
1339 }
1340
1341 if (OpVal.Val != 0) {
1342 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1343 return CN;
1344 }
1345 }
1346
1347 return 0; // All UNDEF: use implicit def.; not Constant node
1348}
1349
1350/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1351/// and the value fits into an unsigned 18-bit constant, and if so, return the
1352/// constant
1353SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1354 MVT::ValueType ValueType) {
1355 if (ConstantSDNode *CN = getVecImm(N)) {
1356 uint64_t Value = CN->getValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001357 if (ValueType == MVT::i64) {
1358 uint64_t UValue = CN->getValue();
1359 uint32_t upper = uint32_t(UValue >> 32);
1360 uint32_t lower = uint32_t(UValue);
1361 if (upper != lower)
1362 return SDOperand();
1363 Value = Value >> 32;
1364 }
Scott Michel8efdca42007-12-04 22:23:35 +00001365 if (Value <= 0x3ffff)
1366 return DAG.getConstant(Value, ValueType);
1367 }
1368
1369 return SDOperand();
1370}
1371
1372/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1373/// and the value fits into a signed 16-bit constant, and if so, return the
1374/// constant
1375SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1376 MVT::ValueType ValueType) {
1377 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michel6baba072008-03-05 23:02:02 +00001378 int64_t Value = CN->getSignExtended();
Scott Michelbcc7b672008-03-06 04:02:54 +00001379 if (ValueType == MVT::i64) {
1380 uint64_t UValue = CN->getValue();
1381 uint32_t upper = uint32_t(UValue >> 32);
1382 uint32_t lower = uint32_t(UValue);
1383 if (upper != lower)
1384 return SDOperand();
1385 Value = Value >> 32;
1386 }
Scott Michel6baba072008-03-05 23:02:02 +00001387 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1388 return DAG.getConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001389 }
1390 }
1391
1392 return SDOperand();
1393}
1394
1395/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1396/// and the value fits into a signed 10-bit constant, and if so, return the
1397/// constant
1398SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1399 MVT::ValueType ValueType) {
1400 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michel6baba072008-03-05 23:02:02 +00001401 int64_t Value = CN->getSignExtended();
Scott Michelbcc7b672008-03-06 04:02:54 +00001402 if (ValueType == MVT::i64) {
1403 uint64_t UValue = CN->getValue();
1404 uint32_t upper = uint32_t(UValue >> 32);
1405 uint32_t lower = uint32_t(UValue);
1406 if (upper != lower)
1407 return SDOperand();
1408 Value = Value >> 32;
1409 }
Scott Michel6baba072008-03-05 23:02:02 +00001410 if (isS10Constant(Value))
Scott Michel8efdca42007-12-04 22:23:35 +00001411 return DAG.getConstant(Value, ValueType);
1412 }
1413
1414 return SDOperand();
1415}
1416
1417/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1418/// and the value fits into a signed 8-bit constant, and if so, return the
1419/// constant.
1420///
1421/// @note: The incoming vector is v16i8 because that's the only way we can load
1422/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1423/// same value.
1424SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1425 MVT::ValueType ValueType) {
1426 if (ConstantSDNode *CN = getVecImm(N)) {
1427 int Value = (int) CN->getValue();
1428 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001429 && Value <= 0xffff /* truncated from uint64_t */
1430 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel8efdca42007-12-04 22:23:35 +00001431 return DAG.getConstant(Value & 0xff, ValueType);
1432 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001433 && (Value & 0xff) == Value)
Scott Michel8efdca42007-12-04 22:23:35 +00001434 return DAG.getConstant(Value, ValueType);
1435 }
1436
1437 return SDOperand();
1438}
1439
1440/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1441/// and the value fits into a signed 16-bit constant, and if so, return the
1442/// constant
1443SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1444 MVT::ValueType ValueType) {
1445 if (ConstantSDNode *CN = getVecImm(N)) {
1446 uint64_t Value = CN->getValue();
1447 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001448 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1449 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel8efdca42007-12-04 22:23:35 +00001450 return DAG.getConstant(Value >> 16, ValueType);
1451 }
1452
1453 return SDOperand();
1454}
1455
1456/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1457SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1458 if (ConstantSDNode *CN = getVecImm(N)) {
1459 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1460 }
1461
1462 return SDOperand();
1463}
1464
1465/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1466SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1467 if (ConstantSDNode *CN = getVecImm(N)) {
1468 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1469 }
1470
1471 return SDOperand();
1472}
1473
1474// If this is a vector of constants or undefs, get the bits. A bit in
1475// UndefBits is set if the corresponding element of the vector is an
1476// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1477// zero. Return true if this is not an array of constants, false if it is.
1478//
1479static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1480 uint64_t UndefBits[2]) {
1481 // Start with zero'd results.
1482 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1483
1484 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1485 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1486 SDOperand OpVal = BV->getOperand(i);
1487
1488 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1489 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1490
1491 uint64_t EltBits = 0;
1492 if (OpVal.getOpcode() == ISD::UNDEF) {
1493 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1494 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1495 continue;
1496 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1497 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1498 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1499 const APFloat &apf = CN->getValueAPF();
1500 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001501 ? FloatToBits(apf.convertToFloat())
1502 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001503 } else {
1504 // Nonconstant element.
1505 return true;
1506 }
1507
1508 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1509 }
1510
1511 //printf("%llx %llx %llx %llx\n",
1512 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1513 return false;
1514}
1515
1516/// If this is a splat (repetition) of a value across the whole vector, return
1517/// the smallest size that splats it. For example, "0x01010101010101..." is a
1518/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1519/// SplatSize = 1 byte.
1520static bool isConstantSplat(const uint64_t Bits128[2],
1521 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001522 int MinSplatBits,
Scott Michel8efdca42007-12-04 22:23:35 +00001523 uint64_t &SplatBits, uint64_t &SplatUndef,
1524 int &SplatSize) {
1525 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1526 // the same as the lower 64-bits, ignoring undefs.
1527 uint64_t Bits64 = Bits128[0] | Bits128[1];
1528 uint64_t Undef64 = Undef128[0] & Undef128[1];
1529 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1530 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1531 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1532 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1533
1534 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1535 if (MinSplatBits < 64) {
1536
1537 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1538 // undefs.
1539 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001540 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001541
Scott Michel5a6f17b2008-01-30 02:55:46 +00001542 // If the top 16-bits are different than the lower 16-bits, ignoring
1543 // undefs, we have an i32 splat.
1544 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1545 if (MinSplatBits < 16) {
1546 // If the top 8-bits are different than the lower 8-bits, ignoring
1547 // undefs, we have an i16 splat.
1548 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1549 // Otherwise, we have an 8-bit splat.
1550 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1551 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1552 SplatSize = 1;
1553 return true;
1554 }
1555 } else {
1556 SplatBits = Bits16;
1557 SplatUndef = Undef16;
1558 SplatSize = 2;
1559 return true;
1560 }
1561 }
1562 } else {
1563 SplatBits = Bits32;
1564 SplatUndef = Undef32;
1565 SplatSize = 4;
1566 return true;
1567 }
Scott Michel8efdca42007-12-04 22:23:35 +00001568 }
1569 } else {
1570 SplatBits = Bits128[0];
1571 SplatUndef = Undef128[0];
1572 SplatSize = 8;
1573 return true;
1574 }
1575 }
1576
1577 return false; // Can't be a splat if two pieces don't match.
1578}
1579
1580// If this is a case we can't handle, return null and let the default
1581// expansion code take care of it. If we CAN select this case, and if it
1582// selects to a single instruction, return Op. Otherwise, if we can codegen
1583// this case more efficiently than a constant pool load, lower it to the
1584// sequence of ops that should be used.
1585static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1586 MVT::ValueType VT = Op.getValueType();
1587 // If this is a vector of constants or undefs, get the bits. A bit in
1588 // UndefBits is set if the corresponding element of the vector is an
1589 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1590 // zero.
1591 uint64_t VectorBits[2];
1592 uint64_t UndefBits[2];
1593 uint64_t SplatBits, SplatUndef;
1594 int SplatSize;
1595 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1596 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001597 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel8efdca42007-12-04 22:23:35 +00001598 SplatBits, SplatUndef, SplatSize))
1599 return SDOperand(); // Not a constant vector, not a splat.
1600
1601 switch (VT) {
1602 default:
1603 case MVT::v4f32: {
1604 uint32_t Value32 = SplatBits;
1605 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001606 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001607 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1608 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1609 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001610 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001611 break;
1612 }
1613 case MVT::v2f64: {
1614 uint64_t f64val = SplatBits;
1615 assert(SplatSize == 8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001616 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel8efdca42007-12-04 22:23:35 +00001617 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1618 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1619 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001620 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001621 break;
1622 }
1623 case MVT::v16i8: {
1624 // 8-bit constants have to be expanded to 16-bits
1625 unsigned short Value16 = SplatBits | (SplatBits << 8);
1626 SDOperand Ops[8];
1627 for (int i = 0; i < 8; ++i)
1628 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1629 return DAG.getNode(ISD::BIT_CONVERT, VT,
1630 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1631 }
1632 case MVT::v8i16: {
1633 unsigned short Value16;
1634 if (SplatSize == 2)
1635 Value16 = (unsigned short) (SplatBits & 0xffff);
1636 else
1637 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1638 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1639 SDOperand Ops[8];
1640 for (int i = 0; i < 8; ++i) Ops[i] = T;
1641 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1642 }
1643 case MVT::v4i32: {
1644 unsigned int Value = SplatBits;
1645 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1646 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1647 }
1648 case MVT::v2i64: {
1649 uint64_t val = SplatBits;
1650 uint32_t upper = uint32_t(val >> 32);
1651 uint32_t lower = uint32_t(val);
1652
Scott Michelbcc7b672008-03-06 04:02:54 +00001653 if (upper == lower) {
1654 // Magic constant that can be matched by IL, ILA, et. al.
1655 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1656 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel6baba072008-03-05 23:02:02 +00001657 } else {
Scott Michel8efdca42007-12-04 22:23:35 +00001658 SDOperand LO32;
1659 SDOperand HI32;
1660 SmallVector<SDOperand, 16> ShufBytes;
1661 SDOperand Result;
1662 bool upper_special, lower_special;
1663
1664 // NOTE: This code creates common-case shuffle masks that can be easily
1665 // detected as common expressions. It is not attempting to create highly
1666 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1667
1668 // Detect if the upper or lower half is a special shuffle mask pattern:
1669 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1670 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1671
1672 // Create lower vector if not a special pattern
1673 if (!lower_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001674 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1675 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1676 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1677 LO32C, LO32C, LO32C, LO32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001678 }
1679
1680 // Create upper vector if not a special pattern
1681 if (!upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001682 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1683 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1684 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1685 HI32C, HI32C, HI32C, HI32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001686 }
1687
1688 // If either upper or lower are special, then the two input operands are
1689 // the same (basically, one of them is a "don't care")
1690 if (lower_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001691 LO32 = HI32;
Scott Michel8efdca42007-12-04 22:23:35 +00001692 if (upper_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001693 HI32 = LO32;
Scott Michel8efdca42007-12-04 22:23:35 +00001694 if (lower_special && upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001695 // Unhappy situation... both upper and lower are special, so punt with
1696 // a target constant:
Scott Michel8efdca42007-12-04 22:23:35 +00001697 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001698 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel8efdca42007-12-04 22:23:35 +00001699 Zero, Zero);
1700 }
1701
1702 for (int i = 0; i < 4; ++i) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001703 for (int j = 0; j < 4; ++j) {
1704 SDOperand V;
1705 bool process_upper, process_lower;
1706 uint64_t val = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001707
Scott Michel5a6f17b2008-01-30 02:55:46 +00001708 process_upper = (upper_special && (i & 1) == 0);
1709 process_lower = (lower_special && (i & 1) == 1);
Scott Michel8efdca42007-12-04 22:23:35 +00001710
Scott Michel5a6f17b2008-01-30 02:55:46 +00001711 if (process_upper || process_lower) {
1712 if ((process_upper && upper == 0)
1713 || (process_lower && lower == 0))
1714 val = 0x80;
1715 else if ((process_upper && upper == 0xffffffff)
1716 || (process_lower && lower == 0xffffffff))
1717 val = 0xc0;
1718 else if ((process_upper && upper == 0x80000000)
1719 || (process_lower && lower == 0x80000000))
1720 val = (j == 0 ? 0xe0 : 0x80);
1721 } else
1722 val = i * 4 + j + ((i & 1) * 16);
Scott Michel8efdca42007-12-04 22:23:35 +00001723
Scott Michel5a6f17b2008-01-30 02:55:46 +00001724 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1725 }
Scott Michel8efdca42007-12-04 22:23:35 +00001726 }
1727
1728 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001729 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1730 &ShufBytes[0], ShufBytes.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001731 }
1732 }
1733 }
1734
1735 return SDOperand();
1736}
1737
1738/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1739/// which the Cell can operate. The code inspects V3 to ascertain whether the
1740/// permutation vector, V3, is monotonically increasing with one "exception"
1741/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1742/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1743/// In either case, the net result is going to eventually invoke SHUFB to
1744/// permute/shuffle the bytes from V1 and V2.
1745/// \note
1746/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1747/// control word for byte/halfword/word insertion. This takes care of a single
1748/// element move from V2 into V1.
1749/// \note
1750/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1751static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1752 SDOperand V1 = Op.getOperand(0);
1753 SDOperand V2 = Op.getOperand(1);
1754 SDOperand PermMask = Op.getOperand(2);
1755
1756 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1757
1758 // If we have a single element being moved from V1 to V2, this can be handled
1759 // using the C*[DX] compute mask instructions, but the vector elements have
1760 // to be monotonically increasing with one exception element.
1761 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1762 unsigned EltsFromV2 = 0;
1763 unsigned V2Elt = 0;
1764 unsigned V2EltIdx0 = 0;
1765 unsigned CurrElt = 0;
1766 bool monotonic = true;
1767 if (EltVT == MVT::i8)
1768 V2EltIdx0 = 16;
1769 else if (EltVT == MVT::i16)
1770 V2EltIdx0 = 8;
1771 else if (EltVT == MVT::i32)
1772 V2EltIdx0 = 4;
1773 else
1774 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1775
1776 for (unsigned i = 0, e = PermMask.getNumOperands();
1777 EltsFromV2 <= 1 && monotonic && i != e;
1778 ++i) {
1779 unsigned SrcElt;
1780 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1781 SrcElt = 0;
1782 else
1783 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1784
1785 if (SrcElt >= V2EltIdx0) {
1786 ++EltsFromV2;
1787 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1788 } else if (CurrElt != SrcElt) {
1789 monotonic = false;
1790 }
1791
1792 ++CurrElt;
1793 }
1794
1795 if (EltsFromV2 == 1 && monotonic) {
1796 // Compute mask and shuffle
1797 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001798 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1799 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00001800 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1801 // Initialize temporary register to 0
1802 SDOperand InitTempReg =
1803 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1804 // Copy register's contents as index in INSERT_MASK:
1805 SDOperand ShufMaskOp =
1806 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001807 DAG.getTargetConstant(V2Elt, MVT::i32),
1808 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001809 // Use shuffle mask in SHUFB synthetic instruction:
1810 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1811 } else {
1812 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1813 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1814
1815 SmallVector<SDOperand, 16> ResultMask;
1816 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1817 unsigned SrcElt;
1818 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001819 SrcElt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001820 else
Scott Michel5a6f17b2008-01-30 02:55:46 +00001821 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001822
Scott Michel97872d32008-02-23 18:41:37 +00001823 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001824 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1825 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001826 }
1827 }
1828
1829 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001830 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001831 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1832 }
1833}
1834
1835static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001836 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001837
1838 if (Op0.Val->getOpcode() == ISD::Constant) {
1839 // For a constant, build the appropriate constant vector, which will
1840 // eventually simplify to a vector register load.
1841
1842 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1843 SmallVector<SDOperand, 16> ConstVecValues;
1844 MVT::ValueType VT;
1845 size_t n_copies;
1846
1847 // Create a constant vector:
1848 switch (Op.getValueType()) {
1849 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001850 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001851 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1852 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1853 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1854 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1855 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1856 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1857 }
1858
1859 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1860 for (size_t j = 0; j < n_copies; ++j)
1861 ConstVecValues.push_back(CValue);
1862
1863 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001864 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001865 } else {
1866 // Otherwise, copy the value from one register to another:
1867 switch (Op0.getValueType()) {
1868 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1869 case MVT::i8:
1870 case MVT::i16:
1871 case MVT::i32:
1872 case MVT::i64:
1873 case MVT::f32:
1874 case MVT::f64:
1875 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1876 }
1877 }
1878
1879 return SDOperand();
1880}
1881
1882static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1883 switch (Op.getValueType()) {
1884 case MVT::v4i32: {
1885 SDOperand rA = Op.getOperand(0);
1886 SDOperand rB = Op.getOperand(1);
1887 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1888 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1889 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1890 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1891
1892 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1893 break;
1894 }
1895
1896 // Multiply two v8i16 vectors (pipeline friendly version):
1897 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1898 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1899 // c) Use SELB to select upper and lower halves from the intermediate results
1900 //
1901 // NOTE: We really want to move the FSMBI to earlier to actually get the
1902 // dual-issue. This code does manage to do this, even if it's a little on
1903 // the wacky side
1904 case MVT::v8i16: {
1905 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001906 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00001907 SDOperand Chain = Op.getOperand(0);
1908 SDOperand rA = Op.getOperand(0);
1909 SDOperand rB = Op.getOperand(1);
Chris Lattner1b989192007-12-31 04:13:23 +00001910 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1911 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00001912
1913 SDOperand FSMBOp =
1914 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001915 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1916 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel8efdca42007-12-04 22:23:35 +00001917
1918 SDOperand HHProd =
1919 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001920 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00001921
1922 SDOperand HHProd_v4i32 =
1923 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001924 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001925
1926 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001927 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1928 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1929 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1930 HHProd_v4i32,
1931 DAG.getConstant(16, MVT::i16))),
1932 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001933 }
1934
1935 // This M00sE is N@stI! (apologies to Monty Python)
1936 //
1937 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1938 // is to break it all apart, sign extend, and reassemble the various
1939 // intermediate products.
1940 case MVT::v16i8: {
Scott Michel8efdca42007-12-04 22:23:35 +00001941 SDOperand rA = Op.getOperand(0);
1942 SDOperand rB = Op.getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00001943 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1944 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001945
1946 SDOperand LLProd =
1947 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001948 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1949 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00001950
1951 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1952
1953 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1954
1955 SDOperand LHProd =
1956 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001957 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel8efdca42007-12-04 22:23:35 +00001958
Scott Michel97872d32008-02-23 18:41:37 +00001959 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1960 DAG.getConstant(0x2222, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001961
Scott Michel97872d32008-02-23 18:41:37 +00001962 SDOperand LoProdParts =
1963 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1964 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1965 LLProd, LHProd, FSMBmask));
Scott Michel8efdca42007-12-04 22:23:35 +00001966
1967 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1968
1969 SDOperand LoProd =
1970 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michel97872d32008-02-23 18:41:37 +00001971 LoProdParts,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001972 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1973 LoProdMask, LoProdMask,
1974 LoProdMask, LoProdMask));
Scott Michel8efdca42007-12-04 22:23:35 +00001975
1976 SDOperand rAH =
1977 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001978 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel8efdca42007-12-04 22:23:35 +00001979
1980 SDOperand rBH =
1981 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001982 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel8efdca42007-12-04 22:23:35 +00001983
1984 SDOperand HLProd =
1985 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001986 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1987 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel8efdca42007-12-04 22:23:35 +00001988
1989 SDOperand HHProd_1 =
1990 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001991 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1992 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1993 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1994 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel8efdca42007-12-04 22:23:35 +00001995
1996 SDOperand HHProd =
Scott Michel97872d32008-02-23 18:41:37 +00001997 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1998 HLProd,
1999 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2000 FSMBmask);
Scott Michel8efdca42007-12-04 22:23:35 +00002001
2002 SDOperand HiProd =
Scott Michel97872d32008-02-23 18:41:37 +00002003 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel8efdca42007-12-04 22:23:35 +00002004
2005 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002006 DAG.getNode(ISD::OR, MVT::v4i32,
2007 LoProd, HiProd));
Scott Michel8efdca42007-12-04 22:23:35 +00002008 }
2009
2010 default:
2011 cerr << "CellSPU: Unknown vector multiplication, got "
2012 << MVT::getValueTypeString(Op.getValueType())
Scott Michel5a6f17b2008-01-30 02:55:46 +00002013 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002014 abort();
2015 /*NOTREACHED*/
2016 }
2017
2018 return SDOperand();
2019}
2020
2021static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2022 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002023 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002024
2025 SDOperand A = Op.getOperand(0);
2026 SDOperand B = Op.getOperand(1);
2027 unsigned VT = Op.getValueType();
2028
2029 unsigned VRegBR, VRegC;
2030
2031 if (VT == MVT::f32) {
Chris Lattner1b989192007-12-31 04:13:23 +00002032 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2033 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002034 } else {
Chris Lattner1b989192007-12-31 04:13:23 +00002035 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2036 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002037 }
2038 // TODO: make sure we're feeding FPInterp the right arguments
2039 // Right now: fi B, frest(B)
2040
2041 // Computes BRcpl =
2042 // (Floating Interpolate (FP Reciprocal Estimate B))
2043 SDOperand BRcpl =
2044 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002045 DAG.getNode(SPUISD::FPInterp, VT, B,
2046 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel8efdca42007-12-04 22:23:35 +00002047
2048 // Computes A * BRcpl and stores in a temporary register
2049 SDOperand AxBRcpl =
2050 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002051 DAG.getNode(ISD::FMUL, VT, A,
2052 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel8efdca42007-12-04 22:23:35 +00002053 // What's the Chain variable do? It's magic!
2054 // TODO: set Chain = Op(0).getEntryNode()
2055
2056 return DAG.getNode(ISD::FADD, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002057 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2058 DAG.getNode(ISD::FMUL, VT,
2059 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2060 DAG.getNode(ISD::FSUB, VT, A,
2061 DAG.getNode(ISD::FMUL, VT, B,
2062 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel8efdca42007-12-04 22:23:35 +00002063}
2064
Scott Michel8efdca42007-12-04 22:23:35 +00002065static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2066 unsigned VT = Op.getValueType();
2067 SDOperand N = Op.getOperand(0);
2068 SDOperand Elt = Op.getOperand(1);
2069 SDOperand ShufMask[16];
2070 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2071
2072 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2073
2074 int EltNo = (int) C->getValue();
2075
2076 // sanity checks:
2077 if (VT == MVT::i8 && EltNo >= 16)
2078 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2079 else if (VT == MVT::i16 && EltNo >= 8)
2080 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2081 else if (VT == MVT::i32 && EltNo >= 4)
2082 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2083 else if (VT == MVT::i64 && EltNo >= 2)
2084 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2085
2086 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2087 // i32 and i64: Element 0 is the preferred slot
2088 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2089 }
2090
2091 // Need to generate shuffle mask and extract:
Scott Michel4c07cbd2007-12-19 21:17:42 +00002092 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel8efdca42007-12-04 22:23:35 +00002093 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2094
2095 switch (VT) {
2096 case MVT::i8: {
2097 prefslot_begin = prefslot_end = 3;
2098 break;
2099 }
2100 case MVT::i16: {
2101 prefslot_begin = 2; prefslot_end = 3;
2102 break;
2103 }
2104 case MVT::i32: {
2105 prefslot_begin = 0; prefslot_end = 3;
2106 break;
2107 }
2108 case MVT::i64: {
2109 prefslot_begin = 0; prefslot_end = 7;
2110 break;
2111 }
2112 }
2113
Scott Michel4c07cbd2007-12-19 21:17:42 +00002114 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel5a6f17b2008-01-30 02:55:46 +00002115 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel4c07cbd2007-12-19 21:17:42 +00002116
Scott Michel8efdca42007-12-04 22:23:35 +00002117 for (int i = 0; i < 16; ++i) {
2118 // zero fill uppper part of preferred slot, don't care about the
2119 // other slots:
2120 unsigned int mask_val;
2121
2122 if (i <= prefslot_end) {
2123 mask_val =
Scott Michel5a6f17b2008-01-30 02:55:46 +00002124 ((i < prefslot_begin)
2125 ? 0x80
2126 : elt_byte + (i - prefslot_begin));
Scott Michel8efdca42007-12-04 22:23:35 +00002127
Scott Michel4c07cbd2007-12-19 21:17:42 +00002128 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002129 } else
2130 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2131 }
2132
2133 SDOperand ShufMaskVec =
2134 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002135 &ShufMask[0],
2136 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel8efdca42007-12-04 22:23:35 +00002137
2138 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002139 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2140 N, N, ShufMaskVec));
2141
Scott Michel8efdca42007-12-04 22:23:35 +00002142}
2143
2144static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2145 SDOperand VecOp = Op.getOperand(0);
2146 SDOperand ValOp = Op.getOperand(1);
2147 SDOperand IdxOp = Op.getOperand(2);
2148 MVT::ValueType VT = Op.getValueType();
2149
2150 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2151 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2152
2153 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2154 // Use $2 because it's always 16-byte aligned and it's available:
2155 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2156
2157 SDOperand result =
2158 DAG.getNode(SPUISD::SHUFB, VT,
2159 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2160 VecOp,
2161 DAG.getNode(SPUISD::INSERT_MASK, VT,
2162 DAG.getNode(ISD::ADD, PtrVT,
2163 PtrBase,
2164 DAG.getConstant(CN->getValue(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002165 PtrVT))));
Scott Michel8efdca42007-12-04 22:23:35 +00002166
2167 return result;
2168}
2169
Scott Michel97872d32008-02-23 18:41:37 +00002170static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2171{
Scott Michel8efdca42007-12-04 22:23:35 +00002172 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2173
2174 assert(Op.getValueType() == MVT::i8);
2175 switch (Opc) {
2176 default:
2177 assert(0 && "Unhandled i8 math operator");
2178 /*NOTREACHED*/
2179 break;
2180 case ISD::SUB: {
2181 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2182 // the result:
2183 SDOperand N1 = Op.getOperand(1);
2184 N0 = (N0.getOpcode() != ISD::Constant
2185 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2186 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2187 N1 = (N1.getOpcode() != ISD::Constant
2188 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2189 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2190 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2191 DAG.getNode(Opc, MVT::i16, N0, N1));
2192 }
2193 case ISD::ROTR:
2194 case ISD::ROTL: {
2195 SDOperand N1 = Op.getOperand(1);
2196 unsigned N1Opc;
2197 N0 = (N0.getOpcode() != ISD::Constant
2198 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2199 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2200 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2201 N1 = (N1.getOpcode() != ISD::Constant
2202 ? DAG.getNode(N1Opc, MVT::i16, N1)
2203 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2204 SDOperand ExpandArg =
2205 DAG.getNode(ISD::OR, MVT::i16, N0,
2206 DAG.getNode(ISD::SHL, MVT::i16,
2207 N0, DAG.getConstant(8, MVT::i16)));
2208 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2209 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2210 }
2211 case ISD::SRL:
2212 case ISD::SHL: {
2213 SDOperand N1 = Op.getOperand(1);
2214 unsigned N1Opc;
2215 N0 = (N0.getOpcode() != ISD::Constant
2216 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2217 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2218 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2219 N1 = (N1.getOpcode() != ISD::Constant
2220 ? DAG.getNode(N1Opc, MVT::i16, N1)
2221 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2222 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2223 DAG.getNode(Opc, MVT::i16, N0, N1));
2224 }
2225 case ISD::SRA: {
2226 SDOperand N1 = Op.getOperand(1);
2227 unsigned N1Opc;
2228 N0 = (N0.getOpcode() != ISD::Constant
2229 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2230 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2231 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2232 N1 = (N1.getOpcode() != ISD::Constant
2233 ? DAG.getNode(N1Opc, MVT::i16, N1)
2234 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2235 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2236 DAG.getNode(Opc, MVT::i16, N0, N1));
2237 }
2238 case ISD::MUL: {
2239 SDOperand N1 = Op.getOperand(1);
2240 unsigned N1Opc;
2241 N0 = (N0.getOpcode() != ISD::Constant
2242 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2243 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2244 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2245 N1 = (N1.getOpcode() != ISD::Constant
2246 ? DAG.getNode(N1Opc, MVT::i16, N1)
2247 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2248 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2249 DAG.getNode(Opc, MVT::i16, N0, N1));
2250 break;
2251 }
2252 }
2253
2254 return SDOperand();
2255}
2256
Scott Michel97872d32008-02-23 18:41:37 +00002257static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2258{
2259 MVT::ValueType VT = Op.getValueType();
2260 unsigned VecVT =
2261 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2262
2263 SDOperand Op0 = Op.getOperand(0);
2264
2265 switch (Opc) {
2266 case ISD::ZERO_EXTEND:
2267 case ISD::SIGN_EXTEND:
2268 case ISD::ANY_EXTEND: {
2269 MVT::ValueType Op0VT = Op0.getValueType();
2270 unsigned Op0VecVT =
2271 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2272
2273 assert(Op0VT == MVT::i32
2274 && "CellSPU: Zero/sign extending something other than i32");
2275
2276 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2277 ? SPUISD::ROTBYTES_RIGHT_S
2278 : SPUISD::ROTQUAD_RZ_BYTES);
2279 SDOperand PromoteScalar =
2280 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2281
2282 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2283 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2284 DAG.getNode(NewOpc, Op0VecVT,
2285 PromoteScalar,
2286 DAG.getConstant(4, MVT::i32))));
2287 }
2288
2289 case ISD::SHL: {
2290 SDOperand ShiftAmt = Op.getOperand(1);
2291 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2292 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2293 SDOperand MaskLower =
2294 DAG.getNode(SPUISD::SELB, VecVT,
2295 Op0Vec,
2296 DAG.getConstant(0, VecVT),
2297 DAG.getNode(SPUISD::FSMBI, VecVT,
2298 DAG.getConstant(0xff00ULL, MVT::i16)));
2299 SDOperand ShiftAmtBytes =
2300 DAG.getNode(ISD::SRL, ShiftAmtVT,
2301 ShiftAmt,
2302 DAG.getConstant(3, ShiftAmtVT));
2303 SDOperand ShiftAmtBits =
2304 DAG.getNode(ISD::AND, ShiftAmtVT,
2305 ShiftAmt,
2306 DAG.getConstant(7, ShiftAmtVT));
2307
2308 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2309 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2310 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2311 MaskLower, ShiftAmtBytes),
2312 ShiftAmtBits));
2313 }
2314
2315 case ISD::SRL: {
2316 unsigned VT = unsigned(Op.getValueType());
2317 SDOperand ShiftAmt = Op.getOperand(1);
2318 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2319 SDOperand ShiftAmtBytes =
2320 DAG.getNode(ISD::SRL, ShiftAmtVT,
2321 ShiftAmt,
2322 DAG.getConstant(3, ShiftAmtVT));
2323 SDOperand ShiftAmtBits =
2324 DAG.getNode(ISD::AND, ShiftAmtVT,
2325 ShiftAmt,
2326 DAG.getConstant(7, ShiftAmtVT));
2327
2328 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2329 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2330 Op0, ShiftAmtBytes),
2331 ShiftAmtBits);
2332 }
2333 }
2334
2335 return SDOperand();
2336}
2337
Scott Michel8efdca42007-12-04 22:23:35 +00002338//! Lower byte immediate operations for v16i8 vectors:
2339static SDOperand
2340LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2341 SDOperand ConstVec;
2342 SDOperand Arg;
2343 MVT::ValueType VT = Op.getValueType();
2344
2345 ConstVec = Op.getOperand(0);
2346 Arg = Op.getOperand(1);
2347 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2348 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2349 ConstVec = ConstVec.getOperand(0);
2350 } else {
2351 ConstVec = Op.getOperand(1);
2352 Arg = Op.getOperand(0);
2353 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002354 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002355 }
2356 }
2357 }
2358
2359 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2360 uint64_t VectorBits[2];
2361 uint64_t UndefBits[2];
2362 uint64_t SplatBits, SplatUndef;
2363 int SplatSize;
2364
2365 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002366 && isConstantSplat(VectorBits, UndefBits,
2367 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2368 SplatBits, SplatUndef, SplatSize)) {
Scott Michel8efdca42007-12-04 22:23:35 +00002369 SDOperand tcVec[16];
2370 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2371 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2372
2373 // Turn the BUILD_VECTOR into a set of target constants:
2374 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002375 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002376
2377 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002378 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002379 }
2380 }
2381
2382 return SDOperand();
2383}
2384
2385//! Lower i32 multiplication
2386static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2387 unsigned Opc) {
2388 switch (VT) {
2389 default:
2390 cerr << "CellSPU: Unknown LowerMUL value type, got "
2391 << MVT::getValueTypeString(Op.getValueType())
Scott Michel5a6f17b2008-01-30 02:55:46 +00002392 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002393 abort();
2394 /*NOTREACHED*/
2395
2396 case MVT::i32: {
2397 SDOperand rA = Op.getOperand(0);
2398 SDOperand rB = Op.getOperand(1);
2399
2400 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002401 DAG.getNode(ISD::ADD, MVT::i32,
2402 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2403 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2404 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00002405 }
2406 }
2407
2408 return SDOperand();
2409}
2410
2411//! Custom lowering for CTPOP (count population)
2412/*!
2413 Custom lowering code that counts the number ones in the input
2414 operand. SPU has such an instruction, but it counts the number of
2415 ones per byte, which then have to be accumulated.
2416*/
2417static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2418 unsigned VT = Op.getValueType();
2419 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2420
2421 switch (VT) {
2422 case MVT::i8: {
2423 SDOperand N = Op.getOperand(0);
2424 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2425
2426 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2427 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2428
2429 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2430 }
2431
2432 case MVT::i16: {
2433 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002434 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002435
Chris Lattner1b989192007-12-31 04:13:23 +00002436 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002437
2438 SDOperand N = Op.getOperand(0);
2439 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2440 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2441 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2442
2443 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2444 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2445
2446 // CNTB_result becomes the chain to which all of the virtual registers
2447 // CNTB_reg, SUM1_reg become associated:
2448 SDOperand CNTB_result =
2449 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel5a6f17b2008-01-30 02:55:46 +00002450
Scott Michel8efdca42007-12-04 22:23:35 +00002451 SDOperand CNTB_rescopy =
2452 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2453
2454 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2455
2456 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002457 DAG.getNode(ISD::ADD, MVT::i16,
2458 DAG.getNode(ISD::SRL, MVT::i16,
2459 Tmp1, Shift1),
2460 Tmp1),
2461 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002462 }
2463
2464 case MVT::i32: {
2465 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002466 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002467
Chris Lattner1b989192007-12-31 04:13:23 +00002468 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2469 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002470
2471 SDOperand N = Op.getOperand(0);
2472 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2473 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2474 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2475 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2476
2477 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2478 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2479
2480 // CNTB_result becomes the chain to which all of the virtual registers
2481 // CNTB_reg, SUM1_reg become associated:
2482 SDOperand CNTB_result =
2483 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel5a6f17b2008-01-30 02:55:46 +00002484
Scott Michel8efdca42007-12-04 22:23:35 +00002485 SDOperand CNTB_rescopy =
2486 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2487
2488 SDOperand Comp1 =
2489 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002490 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002491
2492 SDOperand Sum1 =
2493 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002494 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002495
2496 SDOperand Sum1_rescopy =
2497 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2498
2499 SDOperand Comp2 =
2500 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002501 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2502 Shift2);
Scott Michel8efdca42007-12-04 22:23:35 +00002503 SDOperand Sum2 =
2504 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002505 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002506
2507 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2508 }
2509
2510 case MVT::i64:
2511 break;
2512 }
2513
2514 return SDOperand();
2515}
2516
2517/// LowerOperation - Provide custom lowering hooks for some operations.
2518///
2519SDOperand
2520SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2521{
Scott Michel97872d32008-02-23 18:41:37 +00002522 unsigned Opc = (unsigned) Op.getOpcode();
2523 unsigned VT = (unsigned) Op.getValueType();
2524
2525 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002526 default: {
2527 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002528 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002529 cerr << "*Op.Val:\n";
2530 Op.Val->dump();
2531 abort();
2532 }
2533 case ISD::LOAD:
2534 case ISD::SEXTLOAD:
2535 case ISD::ZEXTLOAD:
2536 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2537 case ISD::STORE:
2538 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2539 case ISD::ConstantPool:
2540 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2541 case ISD::GlobalAddress:
2542 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2543 case ISD::JumpTable:
2544 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2545 case ISD::Constant:
2546 return LowerConstant(Op, DAG);
2547 case ISD::ConstantFP:
2548 return LowerConstantFP(Op, DAG);
Scott Michel394e26d2008-01-17 20:38:41 +00002549 case ISD::BRCOND:
2550 return LowerBRCOND(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002551 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002552 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002553 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002554 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002555 case ISD::RET:
2556 return LowerRET(Op, DAG, getTargetMachine());
2557
Scott Michel97872d32008-02-23 18:41:37 +00002558
2559 // i8, i64 math ops:
2560 case ISD::ZERO_EXTEND:
2561 case ISD::SIGN_EXTEND:
2562 case ISD::ANY_EXTEND:
Scott Michel8efdca42007-12-04 22:23:35 +00002563 case ISD::SUB:
2564 case ISD::ROTR:
2565 case ISD::ROTL:
2566 case ISD::SRL:
2567 case ISD::SHL:
2568 case ISD::SRA:
Scott Michel97872d32008-02-23 18:41:37 +00002569 if (VT == MVT::i8)
2570 return LowerI8Math(Op, DAG, Opc);
2571 else if (VT == MVT::i64)
2572 return LowerI64Math(Op, DAG, Opc);
2573 break;
Scott Michel8efdca42007-12-04 22:23:35 +00002574
2575 // Vector-related lowering.
2576 case ISD::BUILD_VECTOR:
2577 return LowerBUILD_VECTOR(Op, DAG);
2578 case ISD::SCALAR_TO_VECTOR:
2579 return LowerSCALAR_TO_VECTOR(Op, DAG);
2580 case ISD::VECTOR_SHUFFLE:
2581 return LowerVECTOR_SHUFFLE(Op, DAG);
2582 case ISD::EXTRACT_VECTOR_ELT:
2583 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2584 case ISD::INSERT_VECTOR_ELT:
2585 return LowerINSERT_VECTOR_ELT(Op, DAG);
2586
2587 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2588 case ISD::AND:
2589 case ISD::OR:
2590 case ISD::XOR:
2591 return LowerByteImmed(Op, DAG);
2592
2593 // Vector and i8 multiply:
2594 case ISD::MUL:
Scott Michel97872d32008-02-23 18:41:37 +00002595 if (MVT::isVector(VT))
Scott Michel8efdca42007-12-04 22:23:35 +00002596 return LowerVectorMUL(Op, DAG);
Scott Michel97872d32008-02-23 18:41:37 +00002597 else if (VT == MVT::i8)
2598 return LowerI8Math(Op, DAG, Opc);
Scott Michel8efdca42007-12-04 22:23:35 +00002599 else
Scott Michel97872d32008-02-23 18:41:37 +00002600 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel8efdca42007-12-04 22:23:35 +00002601
2602 case ISD::FDIV:
Scott Michel97872d32008-02-23 18:41:37 +00002603 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel8efdca42007-12-04 22:23:35 +00002604 return LowerFDIVf32(Op, DAG);
2605// else if (Op.getValueType() == MVT::f64)
2606// return LowerFDIVf64(Op, DAG);
2607 else
2608 assert(0 && "Calling FDIV on unsupported MVT");
2609
2610 case ISD::CTPOP:
2611 return LowerCTPOP(Op, DAG);
2612 }
2613
2614 return SDOperand();
2615}
2616
2617//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002618// Target Optimization Hooks
2619//===----------------------------------------------------------------------===//
2620
2621SDOperand
2622SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2623{
2624#if 0
2625 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002626#endif
2627 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002628 SelectionDAG &DAG = DCI.DAG;
Scott Michel97872d32008-02-23 18:41:37 +00002629 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2630 SDOperand Result; // Initially, NULL result
Scott Michel8efdca42007-12-04 22:23:35 +00002631
2632 switch (N->getOpcode()) {
2633 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002634 case ISD::ADD: {
Scott Michelf9f42e62008-01-29 02:16:57 +00002635 SDOperand Op1 = N->getOperand(1);
2636
2637 if ((Op1.getOpcode() == ISD::Constant
2638 || Op1.getOpcode() == ISD::TargetConstant)
2639 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2640 SDOperand Op01 = Op0.getOperand(1);
2641 if (Op01.getOpcode() == ISD::Constant
2642 || Op01.getOpcode() == ISD::TargetConstant) {
2643 // (add <const>, (SPUindirect <arg>, <const>)) ->
2644 // (SPUindirect <arg>, <const + const>)
2645 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2646 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2647 SDOperand combinedConst =
2648 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2649 Op0.getValueType());
2650
2651 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2652 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2653 DEBUG(cerr << "With: (SPUindirect <arg>, "
2654 << CN0->getValue() + CN1->getValue() << ")\n");
2655 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2656 Op0.getOperand(0), combinedConst);
2657 }
2658 } else if ((Op0.getOpcode() == ISD::Constant
2659 || Op0.getOpcode() == ISD::TargetConstant)
2660 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2661 SDOperand Op11 = Op1.getOperand(1);
2662 if (Op11.getOpcode() == ISD::Constant
2663 || Op11.getOpcode() == ISD::TargetConstant) {
2664 // (add (SPUindirect <arg>, <const>), <const>) ->
2665 // (SPUindirect <arg>, <const + const>)
2666 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2667 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2668 SDOperand combinedConst =
2669 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2670 Op0.getValueType());
2671
2672 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2673 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2674 DEBUG(cerr << "With: (SPUindirect <arg>, "
2675 << CN0->getValue() + CN1->getValue() << ")\n");
2676
2677 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2678 Op1.getOperand(0), combinedConst);
2679 }
2680 }
Scott Michel97872d32008-02-23 18:41:37 +00002681 break;
2682 }
2683 case ISD::SIGN_EXTEND:
2684 case ISD::ZERO_EXTEND:
2685 case ISD::ANY_EXTEND: {
2686 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2687 N->getValueType(0) == Op0.getValueType()) {
2688 // (any_extend (SPUextract_elt0 <arg>)) ->
2689 // (SPUextract_elt0 <arg>)
2690 // Types must match, however...
2691 DEBUG(cerr << "Replace: ");
2692 DEBUG(N->dump(&DAG));
2693 DEBUG(cerr << "\nWith: ");
2694 DEBUG(Op0.Val->dump(&DAG));
2695 DEBUG(cerr << "\n");
2696
2697 return Op0;
2698 }
2699 break;
2700 }
2701 case SPUISD::IndirectAddr: {
2702 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2703 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2704 if (CN->getValue() == 0) {
2705 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2706 // (SPUaform <addr>, 0)
2707
2708 DEBUG(cerr << "Replace: ");
2709 DEBUG(N->dump(&DAG));
2710 DEBUG(cerr << "\nWith: ");
2711 DEBUG(Op0.Val->dump(&DAG));
2712 DEBUG(cerr << "\n");
2713
2714 return Op0;
2715 }
2716 }
2717 break;
2718 }
2719 case SPUISD::SHLQUAD_L_BITS:
2720 case SPUISD::SHLQUAD_L_BYTES:
2721 case SPUISD::VEC_SHL:
2722 case SPUISD::VEC_SRL:
2723 case SPUISD::VEC_SRA:
2724 case SPUISD::ROTQUAD_RZ_BYTES:
2725 case SPUISD::ROTQUAD_RZ_BITS: {
2726 SDOperand Op1 = N->getOperand(1);
2727
2728 if (isa<ConstantSDNode>(Op1)) {
2729 // Kill degenerate vector shifts:
2730 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2731
2732 if (CN->getValue() == 0) {
2733 Result = Op0;
2734 }
2735 }
2736 break;
2737 }
2738 case SPUISD::PROMOTE_SCALAR: {
2739 switch (Op0.getOpcode()) {
2740 default:
2741 break;
2742 case ISD::ANY_EXTEND:
2743 case ISD::ZERO_EXTEND:
2744 case ISD::SIGN_EXTEND: {
2745 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2746 // <arg>
2747 // but only if the SPUpromote_scalar and <arg> types match.
2748 SDOperand Op00 = Op0.getOperand(0);
2749 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2750 SDOperand Op000 = Op00.getOperand(0);
2751 if (Op000.getValueType() == N->getValueType(0)) {
2752 Result = Op000;
2753 }
2754 }
2755 break;
2756 }
2757 case SPUISD::EXTRACT_ELT0: {
2758 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2759 // <arg>
2760 Result = Op0.getOperand(0);
2761 break;
2762 }
2763 }
2764 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002765 }
2766 }
Scott Michel394e26d2008-01-17 20:38:41 +00002767 // Otherwise, return unchanged.
Scott Michel97872d32008-02-23 18:41:37 +00002768#if 0
2769 if (Result.Val) {
2770 DEBUG(cerr << "\nReplace.SPU: ");
2771 DEBUG(N->dump(&DAG));
2772 DEBUG(cerr << "\nWith: ");
2773 DEBUG(Result.Val->dump(&DAG));
2774 DEBUG(cerr << "\n");
2775 }
2776#endif
2777
2778 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002779}
2780
2781//===----------------------------------------------------------------------===//
2782// Inline Assembly Support
2783//===----------------------------------------------------------------------===//
2784
2785/// getConstraintType - Given a constraint letter, return the type of
2786/// constraint it is for this target.
2787SPUTargetLowering::ConstraintType
2788SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2789 if (ConstraintLetter.size() == 1) {
2790 switch (ConstraintLetter[0]) {
2791 default: break;
2792 case 'b':
2793 case 'r':
2794 case 'f':
2795 case 'v':
2796 case 'y':
2797 return C_RegisterClass;
2798 }
2799 }
2800 return TargetLowering::getConstraintType(ConstraintLetter);
2801}
2802
2803std::pair<unsigned, const TargetRegisterClass*>
2804SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2805 MVT::ValueType VT) const
2806{
2807 if (Constraint.size() == 1) {
2808 // GCC RS6000 Constraint Letters
2809 switch (Constraint[0]) {
2810 case 'b': // R1-R31
2811 case 'r': // R0-R31
2812 if (VT == MVT::i64)
2813 return std::make_pair(0U, SPU::R64CRegisterClass);
2814 return std::make_pair(0U, SPU::R32CRegisterClass);
2815 case 'f':
2816 if (VT == MVT::f32)
2817 return std::make_pair(0U, SPU::R32FPRegisterClass);
2818 else if (VT == MVT::f64)
2819 return std::make_pair(0U, SPU::R64FPRegisterClass);
2820 break;
2821 case 'v':
2822 return std::make_pair(0U, SPU::GPRCRegisterClass);
2823 }
2824 }
2825
2826 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2827}
2828
Scott Michel97872d32008-02-23 18:41:37 +00002829//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002830void
2831SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002832 const APInt &Mask,
Dan Gohman229fa052008-02-13 00:35:47 +00002833 APInt &KnownZero,
2834 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002835 const SelectionDAG &DAG,
2836 unsigned Depth ) const {
Scott Michel97872d32008-02-23 18:41:37 +00002837 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2838
2839 switch (Op.getOpcode()) {
2840 default:
2841 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2842 break;
2843
2844#if 0
2845 case CALL:
2846 case SHUFB:
2847 case INSERT_MASK:
2848 case CNTB:
2849#endif
2850
2851 case SPUISD::PROMOTE_SCALAR: {
2852 SDOperand Op0 = Op.getOperand(0);
2853 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2854 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2855 KnownOne |= APInt(uint64_sizebits, InMask, false);
2856 break;
2857 }
2858
2859 case SPUISD::LDRESULT:
2860 case SPUISD::EXTRACT_ELT0:
2861 case SPUISD::EXTRACT_ELT0_CHAINED: {
2862 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2863 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2864 KnownOne |= APInt(uint64_sizebits, InMask, false);
2865 break;
2866 }
2867
2868#if 0
2869 case EXTRACT_I1_ZEXT:
2870 case EXTRACT_I1_SEXT:
2871 case EXTRACT_I8_ZEXT:
2872 case EXTRACT_I8_SEXT:
2873 case MPY:
2874 case MPYU:
2875 case MPYH:
2876 case MPYHH:
2877 case SHLQUAD_L_BITS:
2878 case SHLQUAD_L_BYTES:
2879 case VEC_SHL:
2880 case VEC_SRL:
2881 case VEC_SRA:
2882 case VEC_ROTL:
2883 case VEC_ROTR:
2884 case ROTQUAD_RZ_BYTES:
2885 case ROTQUAD_RZ_BITS:
2886 case ROTBYTES_RIGHT_S:
2887 case ROTBYTES_LEFT:
2888 case ROTBYTES_LEFT_CHAINED:
2889 case FSMBI:
2890 case SELB:
2891 case SFPConstant:
2892 case FPInterp:
2893 case FPRecipEst:
2894 case SEXT32TO64:
2895#endif
2896 }
Scott Michel8efdca42007-12-04 22:23:35 +00002897}
2898
2899// LowerAsmOperandForConstraint
2900void
2901SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2902 char ConstraintLetter,
2903 std::vector<SDOperand> &Ops,
2904 SelectionDAG &DAG) {
2905 // Default, for the time being, to the base class handler
2906 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2907}
2908
2909/// isLegalAddressImmediate - Return true if the integer value can be used
2910/// as the offset of the target addressing mode.
2911bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2912 // SPU's addresses are 256K:
2913 return (V > -(1 << 18) && V < (1 << 18) - 1);
2914}
2915
2916bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2917 return false;
2918}