blob: ca5638cc691390b2bb38da4033c4fae06745bb33 [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:
Scott Michel438be252007-12-17 22:32:34 +0000125 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
126 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
127 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
128 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
129 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
130 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel8efdca42007-12-04 22:23:35 +0000131 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
132
133 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel394e26d2008-01-17 20:38:41 +0000134 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +0000135 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
136 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattner3bc08502008-01-17 19:59:44 +0000137 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
138 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
139 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
140 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000142
143 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
144 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
145 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattner3bc08502008-01-17 19:59:44 +0000146 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
147 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
148 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
149 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
151
Scott Michel8efdca42007-12-04 22:23:35 +0000152 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
153 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
154 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
155
156 // SPU constant load actions are custom lowered:
157 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begeman78125042008-02-14 18:43:04 +0000158 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000159 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
160
161 // SPU's loads and stores have to be custom lowered:
162 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
163 ++sctype) {
164 setOperationAction(ISD::LOAD, sctype, Custom);
165 setOperationAction(ISD::STORE, sctype, Custom);
166 }
167
Scott Michel394e26d2008-01-17 20:38:41 +0000168 // Custom lower BRCOND for i1, i8 to "promote" the result to
169 // i32 and i16, respectively.
170 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000171
172 // Expand the jumptable branches
173 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
174 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
175 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
176
177 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000178 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
179
Scott Michel8efdca42007-12-04 22:23:35 +0000180 // PowerPC has no SREM/UREM instructions
181 setOperationAction(ISD::SREM, MVT::i32, Expand);
182 setOperationAction(ISD::UREM, MVT::i32, Expand);
183 setOperationAction(ISD::SREM, MVT::i64, Expand);
184 setOperationAction(ISD::UREM, MVT::i64, Expand);
185
186 // We don't support sin/cos/sqrt/fmod
187 setOperationAction(ISD::FSIN , MVT::f64, Expand);
188 setOperationAction(ISD::FCOS , MVT::f64, Expand);
189 setOperationAction(ISD::FREM , MVT::f64, Expand);
190 setOperationAction(ISD::FSIN , MVT::f32, Expand);
191 setOperationAction(ISD::FCOS , MVT::f32, Expand);
192 setOperationAction(ISD::FREM , MVT::f32, Expand);
193
194 // If we're enabling GP optimizations, use hardware square root
195 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
196 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
197
198 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
199 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
200
201 // SPU can do rotate right and left, so legalize it... but customize for i8
202 // because instructions don't exist.
203 setOperationAction(ISD::ROTR, MVT::i32, Legal);
204 setOperationAction(ISD::ROTR, MVT::i16, Legal);
205 setOperationAction(ISD::ROTR, MVT::i8, Custom);
206 setOperationAction(ISD::ROTL, MVT::i32, Legal);
207 setOperationAction(ISD::ROTL, MVT::i16, Legal);
208 setOperationAction(ISD::ROTL, MVT::i8, Custom);
209 // SPU has no native version of shift left/right for i8
210 setOperationAction(ISD::SHL, MVT::i8, Custom);
211 setOperationAction(ISD::SRL, MVT::i8, Custom);
212 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel97872d32008-02-23 18:41:37 +0000213 // And SPU needs custom lowering for shift left/right for i64
214 setOperationAction(ISD::SHL, MVT::i64, Custom);
215 setOperationAction(ISD::SRL, MVT::i64, Custom);
216 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000217
218 // Custom lower i32 multiplications
219 setOperationAction(ISD::MUL, MVT::i32, Custom);
220
221 // Need to custom handle (some) common i8 math ops
222 setOperationAction(ISD::SUB, MVT::i8, Custom);
223 setOperationAction(ISD::MUL, MVT::i8, Custom);
224
225 // SPU does not have BSWAP. It does have i32 support CTLZ.
226 // CTPOP has to be custom lowered.
227 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
228 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
229
230 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
231 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
232 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
233 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
234
235 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
236 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
237
238 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
239
Scott Michel978b96f2008-03-10 23:49:09 +0000240 // SPU has a version of select that implements (a&~c)|(b|c), just like
241 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000242 setOperationAction(ISD::SELECT, MVT::i1, Promote);
243 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000244 setOperationAction(ISD::SELECT, MVT::i16, Legal);
245 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000246 setOperationAction(ISD::SELECT, MVT::i64, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000247
Scott Michel53ab7792008-03-10 16:58:52 +0000248 setOperationAction(ISD::SETCC, MVT::i1, Promote);
249 setOperationAction(ISD::SETCC, MVT::i8, Legal);
250 setOperationAction(ISD::SETCC, MVT::i16, Legal);
251 setOperationAction(ISD::SETCC, MVT::i32, Legal);
252 setOperationAction(ISD::SETCC, MVT::i64, Expand);
Scott Michel6baba072008-03-05 23:02:02 +0000253
Scott Michel97872d32008-02-23 18:41:37 +0000254 // Zero extension and sign extension for i64 have to be
255 // custom legalized
256 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
257 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
258 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000259
260 // SPU has a legal FP -> signed INT instruction
261 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
262 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
263 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
264 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
265
266 // FDIV on SPU requires custom lowering
267 setOperationAction(ISD::FDIV, MVT::f32, Custom);
268 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
269
270 // SPU has [U|S]INT_TO_FP
271 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
272 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
273 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
274 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
275 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
276 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
277 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
278 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
279
Scott Michel754d8662007-12-20 00:44:13 +0000280 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
281 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
282 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
283 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000284
285 // We cannot sextinreg(i1). Expand to shifts.
286 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
287
288 // Support label based line numbers.
289 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
290 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
291
292 // We want to legalize GlobalAddress and ConstantPool nodes into the
293 // appropriate instructions to materialize the address.
Scott Michelf9f42e62008-01-29 02:16:57 +0000294 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
295 ++sctype) {
296 setOperationAction(ISD::GlobalAddress, sctype, Custom);
297 setOperationAction(ISD::ConstantPool, sctype, Custom);
298 setOperationAction(ISD::JumpTable, sctype, Custom);
299 }
Scott Michel8efdca42007-12-04 22:23:35 +0000300
301 // RET must be custom lowered, to meet ABI requirements
302 setOperationAction(ISD::RET, MVT::Other, Custom);
303
304 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
305 setOperationAction(ISD::VASTART , MVT::Other, Custom);
306
307 // Use the default implementation.
308 setOperationAction(ISD::VAARG , MVT::Other, Expand);
309 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
310 setOperationAction(ISD::VAEND , MVT::Other, Expand);
311 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
312 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
313 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
314 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
315
316 // Cell SPU has instructions for converting between i64 and fp.
317 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
318 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
319
320 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
321 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
322
323 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
324 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
325
326 // First set operation action for all vector types to expand. Then we
327 // will selectively turn on ones that can be effectively codegen'd.
328 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
329 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
330 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
331 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
332 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
333 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
334
335 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
336 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
337 // add/sub are legal for all supported vector VT's.
338 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
339 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
340 // mul has to be custom lowered.
341 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
342
343 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
344 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
345 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
346 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
347 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
348 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
349
350 // These operations need to be expanded:
351 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
352 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
353 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
354 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
355 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
356
357 // Custom lower build_vector, constant pool spills, insert and
358 // extract vector elements:
359 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
360 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
361 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
362 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
363 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
364 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
365 }
366
367 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
368 setOperationAction(ISD::AND, MVT::v16i8, Custom);
369 setOperationAction(ISD::OR, MVT::v16i8, Custom);
370 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
371 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000372
Scott Michel8efdca42007-12-04 22:23:35 +0000373 setShiftAmountType(MVT::i32);
374 setSetCCResultContents(ZeroOrOneSetCCResult);
375
376 setStackPointerRegisterToSaveRestore(SPU::R1);
377
378 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000379 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000380 setTargetDAGCombine(ISD::ZERO_EXTEND);
381 setTargetDAGCombine(ISD::SIGN_EXTEND);
382 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel8efdca42007-12-04 22:23:35 +0000383
384 computeRegisterProperties();
385}
386
387const char *
388SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
389{
390 if (node_names.empty()) {
391 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
392 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
393 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
394 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Micheldbac4cf2008-01-11 02:53:15 +0000395 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000396 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-12-04 22:23:35 +0000397 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
398 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
399 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
400 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
401 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
402 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
403 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
404 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
405 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
406 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
407 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
408 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
409 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
410 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
411 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
412 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michel97872d32008-02-23 18:41:37 +0000413 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
414 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel8efdca42007-12-04 22:23:35 +0000415 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
416 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
417 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
418 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
419 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michel97872d32008-02-23 18:41:37 +0000420 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
421 "SPUISD::ROTQUAD_RZ_BYTES";
422 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
423 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel8efdca42007-12-04 22:23:35 +0000424 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
425 "SPUISD::ROTBYTES_RIGHT_S";
426 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
427 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
428 "SPUISD::ROTBYTES_LEFT_CHAINED";
429 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
430 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel8efdca42007-12-04 22:23:35 +0000431 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
432 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
433 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
434 }
435
436 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
437
438 return ((i != node_names.end()) ? i->second : 0);
439}
440
Scott Michel53ab7792008-03-10 16:58:52 +0000441MVT::ValueType
442SPUTargetLowering::getSetCCResultType(const SDOperand &Op) const {
Scott Michel978b96f2008-03-10 23:49:09 +0000443 MVT::ValueType VT = Op.getValueType();
444 if (MVT::isInteger(VT))
445 return VT;
446 else
447 return MVT::i32;
Scott Michel53ab7792008-03-10 16:58:52 +0000448}
449
Scott Michel8efdca42007-12-04 22:23:35 +0000450//===----------------------------------------------------------------------===//
451// Calling convention code:
452//===----------------------------------------------------------------------===//
453
454#include "SPUGenCallingConv.inc"
455
456//===----------------------------------------------------------------------===//
457// LowerOperation implementation
458//===----------------------------------------------------------------------===//
459
Scott Micheldbac4cf2008-01-11 02:53:15 +0000460/// Aligned load common code for CellSPU
461/*!
462 \param[in] Op The SelectionDAG load or store operand
463 \param[in] DAG The selection DAG
464 \param[in] ST CellSPU subtarget information structure
465 \param[in,out] alignment Caller initializes this to the load or store node's
466 value from getAlignment(), may be updated while generating the aligned load
467 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
468 offset (divisible by 16, modulo 16 == 0)
469 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
470 offset of the preferred slot (modulo 16 != 0)
471 \param[in,out] VT Caller initializes this value type to the the load or store
472 node's loaded or stored value type; may be updated if an i1-extended load or
473 store.
474 \param[out] was16aligned true if the base pointer had 16-byte alignment,
475 otherwise false. Can help to determine if the chunk needs to be rotated.
476
477 Both load and store lowering load a block of data aligned on a 16-byte
478 boundary. This is the common aligned load code shared between both.
479 */
480static SDOperand
481AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
482 LSBaseSDNode *LSN,
483 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner2dff5dd2008-01-12 22:54:07 +0000484 MVT::ValueType &VT, bool &was16aligned)
Scott Micheldbac4cf2008-01-11 02:53:15 +0000485{
486 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
487 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
488 SDOperand basePtr = LSN->getBasePtr();
489 SDOperand chain = LSN->getChain();
490
491 if (basePtr.getOpcode() == ISD::ADD) {
492 SDOperand Op1 = basePtr.Val->getOperand(1);
493
494 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel394e26d2008-01-17 20:38:41 +0000495 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000496
497 alignOffs = (int) CN->getValue();
498 prefSlotOffs = (int) (alignOffs & 0xf);
499
500 // Adjust the rotation amount to ensure that the final result ends up in
501 // the preferred slot:
502 prefSlotOffs -= vtm->prefslot_byte;
503 basePtr = basePtr.getOperand(0);
504
Scott Michel394e26d2008-01-17 20:38:41 +0000505 // Loading from memory, can we adjust alignment?
506 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
507 SDOperand APtr = basePtr.getOperand(0);
508 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
509 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
510 alignment = GSDN->getGlobal()->getAlignment();
511 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000512 }
513 } else {
514 alignOffs = 0;
515 prefSlotOffs = -vtm->prefslot_byte;
516 }
517 } else {
518 alignOffs = 0;
519 prefSlotOffs = -vtm->prefslot_byte;
520 }
521
522 if (alignment == 16) {
523 // Realign the base pointer as a D-Form address:
524 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel394e26d2008-01-17 20:38:41 +0000525 basePtr = DAG.getNode(ISD::ADD, PtrVT,
526 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000527 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000528 }
529
530 // Emit the vector load:
531 was16aligned = true;
532 return DAG.getLoad(MVT::v16i8, chain, basePtr,
533 LSN->getSrcValue(), LSN->getSrcValueOffset(),
534 LSN->isVolatile(), 16);
535 }
536
537 // Unaligned load or we're using the "large memory" model, which means that
538 // we have to be very pessimistic:
Scott Michel394e26d2008-01-17 20:38:41 +0000539 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000540 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000541 }
542
543 // Add the offset
Scott Michelf9f42e62008-01-29 02:16:57 +0000544 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000545 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000546 was16aligned = false;
547 return DAG.getLoad(MVT::v16i8, chain, basePtr,
548 LSN->getSrcValue(), LSN->getSrcValueOffset(),
549 LSN->isVolatile(), 16);
550}
551
Scott Michel8efdca42007-12-04 22:23:35 +0000552/// Custom lower loads for CellSPU
553/*!
554 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
555 within a 16-byte block, we have to rotate to extract the requested element.
556 */
557static SDOperand
558LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
559 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +0000560 SDOperand the_chain = LN->getChain();
Dan Gohman9a4c92c2008-01-30 00:15:11 +0000561 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel8efdca42007-12-04 22:23:35 +0000562 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000563 ISD::LoadExtType ExtType = LN->getExtensionType();
564 unsigned alignment = LN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000565 SDOperand Ops[8];
566
Scott Michel8efdca42007-12-04 22:23:35 +0000567 switch (LN->getAddressingMode()) {
568 case ISD::UNINDEXED: {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000569 int offset, rotamt;
570 bool was16aligned;
571 SDOperand result =
572 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel8efdca42007-12-04 22:23:35 +0000573
Scott Micheldbac4cf2008-01-11 02:53:15 +0000574 if (result.Val == 0)
Scott Michel8efdca42007-12-04 22:23:35 +0000575 return result;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000576
577 the_chain = result.getValue(1);
578 // Rotate the chunk if necessary
579 if (rotamt < 0)
580 rotamt += 16;
Scott Michelabc58242008-01-11 21:01:19 +0000581 if (rotamt != 0 || !was16aligned) {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000582 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
583
Scott Michel394e26d2008-01-17 20:38:41 +0000584 Ops[0] = the_chain;
585 Ops[1] = result;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000586 if (was16aligned) {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000587 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
588 } else {
Scott Michel5a6f17b2008-01-30 02:55:46 +0000589 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000590 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michelabc58242008-01-11 21:01:19 +0000591 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel5a6f17b2008-01-30 02:55:46 +0000592 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000593 }
594
595 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
596 the_chain = result.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000597 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000598
599 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
600 SDVTList scalarvts;
601 MVT::ValueType vecVT = MVT::v16i8;
602
603 // Convert the loaded v16i8 vector to the appropriate vector type
604 // specified by the operand:
605 if (OpVT == VT) {
606 if (VT != MVT::i1)
607 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
608 } else
609 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
610
611 Ops[0] = the_chain;
612 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
613 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
614 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
615 the_chain = result.getValue(1);
616 } else {
617 // Handle the sign and zero-extending loads for i1 and i8:
618 unsigned NewOpC;
619
620 if (ExtType == ISD::SEXTLOAD) {
621 NewOpC = (OpVT == MVT::i1
622 ? SPUISD::EXTRACT_I1_SEXT
623 : SPUISD::EXTRACT_I8_SEXT);
624 } else {
625 assert(ExtType == ISD::ZEXTLOAD);
626 NewOpC = (OpVT == MVT::i1
627 ? SPUISD::EXTRACT_I1_ZEXT
628 : SPUISD::EXTRACT_I8_ZEXT);
629 }
630
631 result = DAG.getNode(NewOpC, OpVT, result);
632 }
633
634 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel5a6f17b2008-01-30 02:55:46 +0000635 SDOperand retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000636 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000637 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000638 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000639
Scott Michel394e26d2008-01-17 20:38:41 +0000640 result = DAG.getNode(SPUISD::LDRESULT, retvts,
641 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000642 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000643 }
644 case ISD::PRE_INC:
645 case ISD::PRE_DEC:
646 case ISD::POST_INC:
647 case ISD::POST_DEC:
648 case ISD::LAST_INDEXED_MODE:
649 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
650 "UNINDEXED\n";
651 cerr << (unsigned) LN->getAddressingMode() << "\n";
652 abort();
653 /*NOTREACHED*/
654 }
655
656 return SDOperand();
657}
658
659/// Custom lower stores for CellSPU
660/*!
661 All CellSPU stores are aligned to 16-byte boundaries, so for elements
662 within a 16-byte block, we have to generate a shuffle to insert the
663 requested element into its place, then store the resulting block.
664 */
665static SDOperand
666LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
667 StoreSDNode *SN = cast<StoreSDNode>(Op);
668 SDOperand Value = SN->getValue();
669 MVT::ValueType VT = Value.getValueType();
Dan Gohman9a4c92c2008-01-30 00:15:11 +0000670 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel8efdca42007-12-04 22:23:35 +0000671 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000672 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000673
674 switch (SN->getAddressingMode()) {
675 case ISD::UNINDEXED: {
Scott Micheldbac4cf2008-01-11 02:53:15 +0000676 int chunk_offset, slot_offset;
677 bool was16aligned;
Scott Michel8efdca42007-12-04 22:23:35 +0000678
679 // The vector type we really want to load from the 16-byte chunk, except
680 // in the case of MVT::i1, which has to be v16i8.
Scott Micheldbac4cf2008-01-11 02:53:15 +0000681 unsigned vecVT, stVecVT = MVT::v16i8;
682
Scott Michel8efdca42007-12-04 22:23:35 +0000683 if (StVT != MVT::i1)
684 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel8efdca42007-12-04 22:23:35 +0000685 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
686
Scott Micheldbac4cf2008-01-11 02:53:15 +0000687 SDOperand alignLoadVec =
688 AlignedLoad(Op, DAG, ST, SN, alignment,
689 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel8efdca42007-12-04 22:23:35 +0000690
Scott Micheldbac4cf2008-01-11 02:53:15 +0000691 if (alignLoadVec.Val == 0)
692 return alignLoadVec;
Scott Michel8efdca42007-12-04 22:23:35 +0000693
Scott Micheldbac4cf2008-01-11 02:53:15 +0000694 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
695 SDOperand basePtr = LN->getBasePtr();
696 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000697 SDOperand theValue = SN->getValue();
698 SDOperand result;
699
700 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000701 && (theValue.getOpcode() == ISD::AssertZext
702 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000703 // Drill down and get the value for zero- and sign-extended
704 // quantities
705 theValue = theValue.getOperand(0);
706 }
707
Scott Micheldbac4cf2008-01-11 02:53:15 +0000708 chunk_offset &= 0xf;
Scott Michel8efdca42007-12-04 22:23:35 +0000709
Scott Micheldbac4cf2008-01-11 02:53:15 +0000710 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
711 SDOperand insertEltPtr;
712 SDOperand insertEltOp;
713
714 // If the base pointer is already a D-form address, then just create
715 // a new D-form address with a slot offset and the orignal base pointer.
716 // Otherwise generate a D-form address with the slot offset relative
717 // to the stack pointer, which is always aligned.
Scott Michelabc58242008-01-11 21:01:19 +0000718 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
719 DEBUG(basePtr.Val->dump(&DAG));
720 DEBUG(cerr << "\n");
721
Scott Michelf9f42e62008-01-29 02:16:57 +0000722 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
723 (basePtr.getOpcode() == ISD::ADD
724 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michelabc58242008-01-11 21:01:19 +0000725 insertEltPtr = basePtr;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000726 } else {
Scott Michelf9f42e62008-01-29 02:16:57 +0000727 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000728 }
729
730 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel8efdca42007-12-04 22:23:35 +0000731 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000732 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
733 alignLoadVec,
734 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000735
Scott Micheldbac4cf2008-01-11 02:53:15 +0000736 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000737 LN->getSrcValue(), LN->getSrcValueOffset(),
738 LN->isVolatile(), LN->getAlignment());
739
740 return result;
741 /*UNREACHED*/
742 }
743 case ISD::PRE_INC:
744 case ISD::PRE_DEC:
745 case ISD::POST_INC:
746 case ISD::POST_DEC:
747 case ISD::LAST_INDEXED_MODE:
748 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
749 "UNINDEXED\n";
750 cerr << (unsigned) SN->getAddressingMode() << "\n";
751 abort();
752 /*NOTREACHED*/
753 }
754
755 return SDOperand();
756}
757
758/// Generate the address of a constant pool entry.
759static SDOperand
760LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
761 MVT::ValueType PtrVT = Op.getValueType();
762 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
763 Constant *C = CP->getConstVal();
764 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel8efdca42007-12-04 22:23:35 +0000765 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000766 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000767
768 if (TM.getRelocationModel() == Reloc::Static) {
769 if (!ST->usingLargeMem()) {
770 // Just return the SDOperand with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000771 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000772 } else {
Scott Michel8efdca42007-12-04 22:23:35 +0000773 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
774 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000775 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000776 }
777 }
778
779 assert(0 &&
780 "LowerConstantPool: Relocation model other than static not supported.");
781 return SDOperand();
782}
783
784static SDOperand
785LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
786 MVT::ValueType PtrVT = Op.getValueType();
787 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
788 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
789 SDOperand Zero = DAG.getConstant(0, PtrVT);
790 const TargetMachine &TM = DAG.getTarget();
791
792 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000793 if (!ST->usingLargeMem()) {
794 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
795 } else {
796 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
797 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
798 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
799 }
Scott Michel8efdca42007-12-04 22:23:35 +0000800 }
801
802 assert(0 &&
803 "LowerJumpTable: Relocation model other than static not supported.");
804 return SDOperand();
805}
806
807static SDOperand
808LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
809 MVT::ValueType PtrVT = Op.getValueType();
810 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
811 GlobalValue *GV = GSDN->getGlobal();
812 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000813 const TargetMachine &TM = DAG.getTarget();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000814 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000815
816 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000817 if (!ST->usingLargeMem()) {
818 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
819 } else {
820 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
821 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
822 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
823 }
Scott Michel8efdca42007-12-04 22:23:35 +0000824 } else {
825 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000826 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000827 abort();
828 /*NOTREACHED*/
829 }
830
831 return SDOperand();
832}
833
834//! Custom lower i64 integer constants
835/*!
836 This code inserts all of the necessary juggling that needs to occur to load
837 a 64-bit constant into a register.
838 */
839static SDOperand
840LowerConstant(SDOperand Op, SelectionDAG &DAG) {
841 unsigned VT = Op.getValueType();
842 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
843
844 if (VT == MVT::i64) {
845 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
846 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000847 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +0000848 } else {
849 cerr << "LowerConstant: unhandled constant type "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000850 << MVT::getValueTypeString(VT)
851 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000852 abort();
853 /*NOTREACHED*/
854 }
855
856 return SDOperand();
857}
858
Nate Begeman78125042008-02-14 18:43:04 +0000859//! Custom lower double precision floating point constants
Scott Michel8efdca42007-12-04 22:23:35 +0000860static SDOperand
861LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
862 unsigned VT = Op.getValueType();
863 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
864
865 assert((FP != 0) &&
Scott Michel5a6f17b2008-01-30 02:55:46 +0000866 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel8efdca42007-12-04 22:23:35 +0000867
Nate Begeman78125042008-02-14 18:43:04 +0000868 if (VT == MVT::f64) {
Scott Michel11e88bb2007-12-19 20:15:47 +0000869 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel8efdca42007-12-04 22:23:35 +0000870 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000871 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel8efdca42007-12-04 22:23:35 +0000872 }
873
874 return SDOperand();
875}
876
Scott Michel394e26d2008-01-17 20:38:41 +0000877//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
878static SDOperand
879LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
880{
881 SDOperand Cond = Op.getOperand(1);
882 MVT::ValueType CondVT = Cond.getValueType();
883 MVT::ValueType CondNVT;
884
885 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
886 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
887 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
888 Op.getOperand(0),
889 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
890 Op.getOperand(2));
891 } else
892 return SDOperand(); // Unchanged
893}
894
Scott Michel8efdca42007-12-04 22:23:35 +0000895static SDOperand
896LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
897{
898 MachineFunction &MF = DAG.getMachineFunction();
899 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000900 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +0000901 SmallVector<SDOperand, 8> ArgValues;
902 SDOperand Root = Op.getOperand(0);
903 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
904
905 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
906 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
907
908 unsigned ArgOffset = SPUFrameInfo::minStackSize();
909 unsigned ArgRegIdx = 0;
910 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
911
912 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
913
914 // Add DAG nodes to load the arguments or copy them out of registers.
915 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
916 SDOperand ArgVal;
917 bool needsLoad = false;
918 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
919 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
920
921 switch (ObjectVT) {
922 default: {
923 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000924 << MVT::getValueTypeString(ObjectVT)
Scott Michel8efdca42007-12-04 22:23:35 +0000925 << "\n";
926 abort();
927 }
928 case MVT::i8:
929 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000930 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
931 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000932 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
933 ++ArgRegIdx;
934 } else {
935 needsLoad = true;
936 }
937 break;
938 case MVT::i16:
939 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000940 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
941 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000942 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
943 ++ArgRegIdx;
944 } else {
945 needsLoad = true;
946 }
947 break;
948 case MVT::i32:
949 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000950 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
951 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000952 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
953 ++ArgRegIdx;
954 } else {
955 needsLoad = true;
956 }
957 break;
958 case MVT::i64:
959 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000960 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
961 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000962 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
963 ++ArgRegIdx;
964 } else {
965 needsLoad = true;
966 }
967 break;
968 case MVT::f32:
969 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000970 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
971 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000972 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
973 ++ArgRegIdx;
974 } else {
975 needsLoad = true;
976 }
977 break;
978 case MVT::f64:
979 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000980 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
981 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000982 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
983 ++ArgRegIdx;
984 } else {
985 needsLoad = true;
986 }
987 break;
988 case MVT::v2f64:
989 case MVT::v4f32:
Scott Michel6baba072008-03-05 23:02:02 +0000990 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +0000991 case MVT::v4i32:
992 case MVT::v8i16:
993 case MVT::v16i8:
994 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner1b989192007-12-31 04:13:23 +0000995 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
996 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +0000997 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
998 ++ArgRegIdx;
999 } else {
1000 needsLoad = true;
1001 }
1002 break;
1003 }
1004
1005 // We need to load the argument to a virtual register if we determined above
1006 // that we ran out of physical registers of the appropriate type
1007 if (needsLoad) {
Chris Lattner60069452008-02-13 07:35:30 +00001008 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1009 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1010 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +00001011 ArgOffset += StackSlotSize;
1012 }
1013
1014 ArgValues.push_back(ArgVal);
1015 }
1016
1017 // If the function takes variable number of arguments, make a frame index for
1018 // the start of the first vararg value... for expansion of llvm.va_start.
1019 if (isVarArg) {
1020 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1021 ArgOffset);
1022 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1023 // If this function is vararg, store any remaining integer argument regs to
1024 // their spots on the stack so that they may be loaded by deferencing the
1025 // result of va_next.
1026 SmallVector<SDOperand, 8> MemOps;
1027 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner1b989192007-12-31 04:13:23 +00001028 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1029 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel8efdca42007-12-04 22:23:35 +00001030 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1031 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1032 MemOps.push_back(Store);
1033 // Increment the address by four for the next argument to store
1034 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1035 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1036 }
1037 if (!MemOps.empty())
1038 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1039 }
1040
1041 ArgValues.push_back(Root);
1042
1043 // Return the new list of results.
1044 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1045 Op.Val->value_end());
1046 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1047}
1048
1049/// isLSAAddress - Return the immediate to use if the specified
1050/// value is representable as a LSA address.
1051static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1052 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1053 if (!C) return 0;
1054
1055 int Addr = C->getValue();
1056 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1057 (Addr << 14 >> 14) != Addr)
1058 return 0; // Top 14 bits have to be sext of immediate.
1059
1060 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1061}
1062
1063static
1064SDOperand
Scott Micheldbac4cf2008-01-11 02:53:15 +00001065LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +00001066 SDOperand Chain = Op.getOperand(0);
1067#if 0
1068 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1069 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1070#endif
1071 SDOperand Callee = Op.getOperand(4);
1072 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1073 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1074 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1075 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1076
1077 // Handy pointer type
1078 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1079
1080 // Accumulate how many bytes are to be pushed on the stack, including the
1081 // linkage area, and parameter passing area. According to the SPU ABI,
1082 // we minimally need space for [LR] and [SP]
1083 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1084
1085 // Set up a copy of the stack pointer for use loading and storing any
1086 // arguments that may not fit in the registers available for argument
1087 // passing.
1088 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1089
1090 // Figure out which arguments are going to go in registers, and which in
1091 // memory.
1092 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1093 unsigned ArgRegIdx = 0;
1094
1095 // Keep track of registers passing arguments
1096 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1097 // And the arguments passed on the stack
1098 SmallVector<SDOperand, 8> MemOpChains;
1099
1100 for (unsigned i = 0; i != NumOps; ++i) {
1101 SDOperand Arg = Op.getOperand(5+2*i);
1102
1103 // PtrOff will be used to store the current argument to the stack if a
1104 // register cannot be found for it.
1105 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1106 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1107
1108 switch (Arg.getValueType()) {
1109 default: assert(0 && "Unexpected ValueType for argument!");
1110 case MVT::i32:
1111 case MVT::i64:
1112 case MVT::i128:
1113 if (ArgRegIdx != NumArgRegs) {
1114 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1115 } else {
1116 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001117 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001118 }
1119 break;
1120 case MVT::f32:
1121 case MVT::f64:
1122 if (ArgRegIdx != NumArgRegs) {
1123 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1124 } else {
1125 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001126 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001127 }
1128 break;
1129 case MVT::v4f32:
1130 case MVT::v4i32:
1131 case MVT::v8i16:
1132 case MVT::v16i8:
1133 if (ArgRegIdx != NumArgRegs) {
1134 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1135 } else {
1136 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001137 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001138 }
1139 break;
1140 }
1141 }
1142
1143 // Update number of stack bytes actually used, insert a call sequence start
1144 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1145 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1146
1147 if (!MemOpChains.empty()) {
1148 // Adjust the stack pointer for the stack arguments.
1149 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1150 &MemOpChains[0], MemOpChains.size());
1151 }
1152
1153 // Build a sequence of copy-to-reg nodes chained together with token chain
1154 // and flag operands which copy the outgoing args into the appropriate regs.
1155 SDOperand InFlag;
1156 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1157 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1158 InFlag);
1159 InFlag = Chain.getValue(1);
1160 }
1161
1162 std::vector<MVT::ValueType> NodeTys;
1163 NodeTys.push_back(MVT::Other); // Returns a chain
1164 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1165
1166 SmallVector<SDOperand, 8> Ops;
1167 unsigned CallOpc = SPUISD::CALL;
1168
1169 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1170 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1171 // node so that legalize doesn't hack it.
1172 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1173 GlobalValue *GV = G->getGlobal();
1174 unsigned CalleeVT = Callee.getValueType();
Scott Micheldbac4cf2008-01-11 02:53:15 +00001175 SDOperand Zero = DAG.getConstant(0, PtrVT);
1176 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001177
Scott Micheldbac4cf2008-01-11 02:53:15 +00001178 if (!ST->usingLargeMem()) {
1179 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1180 // style calls, otherwise, external symbols are BRASL calls. This assumes
1181 // that declared/defined symbols are in the same compilation unit and can
1182 // be reached through PC-relative jumps.
1183 //
1184 // NOTE:
1185 // This may be an unsafe assumption for JIT and really large compilation
1186 // units.
1187 if (GV->isDeclaration()) {
1188 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1189 } else {
1190 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1191 }
Scott Michel8efdca42007-12-04 22:23:35 +00001192 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001193 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1194 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001195 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001196 }
1197 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1198 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Micheldbac4cf2008-01-11 02:53:15 +00001199 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001200 // If this is an absolute destination address that appears to be a legal
1201 // local store address, use the munged value.
1202 Callee = SDOperand(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001203 }
Scott Michel8efdca42007-12-04 22:23:35 +00001204
1205 Ops.push_back(Chain);
1206 Ops.push_back(Callee);
1207
1208 // Add argument registers to the end of the list so that they are known live
1209 // into the call.
1210 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1211 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1212 RegsToPass[i].second.getValueType()));
1213
1214 if (InFlag.Val)
1215 Ops.push_back(InFlag);
1216 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1217 InFlag = Chain.getValue(1);
1218
Evan Cheng07322bb2008-02-05 22:44:06 +00001219 Chain = DAG.getCALLSEQ_END(Chain,
1220 DAG.getConstant(NumStackBytes, PtrVT),
1221 DAG.getConstant(0, PtrVT),
1222 InFlag);
1223 if (Op.Val->getValueType(0) != MVT::Other)
1224 InFlag = Chain.getValue(1);
1225
Scott Michel8efdca42007-12-04 22:23:35 +00001226 SDOperand ResultVals[3];
1227 unsigned NumResults = 0;
1228 NodeTys.clear();
1229
1230 // If the call has results, copy the values out of the ret val registers.
1231 switch (Op.Val->getValueType(0)) {
1232 default: assert(0 && "Unexpected ret value!");
1233 case MVT::Other: break;
1234 case MVT::i32:
1235 if (Op.Val->getValueType(1) == MVT::i32) {
1236 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1237 ResultVals[0] = Chain.getValue(0);
1238 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1239 Chain.getValue(2)).getValue(1);
1240 ResultVals[1] = Chain.getValue(0);
1241 NumResults = 2;
1242 NodeTys.push_back(MVT::i32);
1243 } else {
1244 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1245 ResultVals[0] = Chain.getValue(0);
1246 NumResults = 1;
1247 }
1248 NodeTys.push_back(MVT::i32);
1249 break;
1250 case MVT::i64:
1251 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1252 ResultVals[0] = Chain.getValue(0);
1253 NumResults = 1;
1254 NodeTys.push_back(MVT::i64);
1255 break;
1256 case MVT::f32:
1257 case MVT::f64:
1258 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1259 InFlag).getValue(1);
1260 ResultVals[0] = Chain.getValue(0);
1261 NumResults = 1;
1262 NodeTys.push_back(Op.Val->getValueType(0));
1263 break;
1264 case MVT::v2f64:
1265 case MVT::v4f32:
1266 case MVT::v4i32:
1267 case MVT::v8i16:
1268 case MVT::v16i8:
1269 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1270 InFlag).getValue(1);
1271 ResultVals[0] = Chain.getValue(0);
1272 NumResults = 1;
1273 NodeTys.push_back(Op.Val->getValueType(0));
1274 break;
1275 }
1276
Scott Michel8efdca42007-12-04 22:23:35 +00001277 NodeTys.push_back(MVT::Other);
1278
1279 // If the function returns void, just return the chain.
1280 if (NumResults == 0)
1281 return Chain;
1282
1283 // Otherwise, merge everything together with a MERGE_VALUES node.
1284 ResultVals[NumResults++] = Chain;
1285 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1286 ResultVals, NumResults);
1287 return Res.getValue(Op.ResNo);
1288}
1289
1290static SDOperand
1291LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1292 SmallVector<CCValAssign, 16> RVLocs;
1293 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1294 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1295 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1296 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1297
1298 // If this is the first return lowered for this function, add the regs to the
1299 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001300 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001301 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001302 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001303 }
1304
1305 SDOperand Chain = Op.getOperand(0);
1306 SDOperand Flag;
1307
1308 // Copy the result values into the output registers.
1309 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1310 CCValAssign &VA = RVLocs[i];
1311 assert(VA.isRegLoc() && "Can only return in registers!");
1312 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1313 Flag = Chain.getValue(1);
1314 }
1315
1316 if (Flag.Val)
1317 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1318 else
1319 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1320}
1321
1322
1323//===----------------------------------------------------------------------===//
1324// Vector related lowering:
1325//===----------------------------------------------------------------------===//
1326
1327static ConstantSDNode *
1328getVecImm(SDNode *N) {
1329 SDOperand OpVal(0, 0);
1330
1331 // Check to see if this buildvec has a single non-undef value in its elements.
1332 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1333 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1334 if (OpVal.Val == 0)
1335 OpVal = N->getOperand(i);
1336 else if (OpVal != N->getOperand(i))
1337 return 0;
1338 }
1339
1340 if (OpVal.Val != 0) {
1341 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1342 return CN;
1343 }
1344 }
1345
1346 return 0; // All UNDEF: use implicit def.; not Constant node
1347}
1348
1349/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1350/// and the value fits into an unsigned 18-bit constant, and if so, return the
1351/// constant
1352SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1353 MVT::ValueType ValueType) {
1354 if (ConstantSDNode *CN = getVecImm(N)) {
1355 uint64_t Value = CN->getValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001356 if (ValueType == MVT::i64) {
1357 uint64_t UValue = CN->getValue();
1358 uint32_t upper = uint32_t(UValue >> 32);
1359 uint32_t lower = uint32_t(UValue);
1360 if (upper != lower)
1361 return SDOperand();
1362 Value = Value >> 32;
1363 }
Scott Michel8efdca42007-12-04 22:23:35 +00001364 if (Value <= 0x3ffff)
1365 return DAG.getConstant(Value, ValueType);
1366 }
1367
1368 return SDOperand();
1369}
1370
1371/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1372/// and the value fits into a signed 16-bit constant, and if so, return the
1373/// constant
1374SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1375 MVT::ValueType ValueType) {
1376 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michel6baba072008-03-05 23:02:02 +00001377 int64_t Value = CN->getSignExtended();
Scott Michelbcc7b672008-03-06 04:02:54 +00001378 if (ValueType == MVT::i64) {
1379 uint64_t UValue = CN->getValue();
1380 uint32_t upper = uint32_t(UValue >> 32);
1381 uint32_t lower = uint32_t(UValue);
1382 if (upper != lower)
1383 return SDOperand();
1384 Value = Value >> 32;
1385 }
Scott Michel6baba072008-03-05 23:02:02 +00001386 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1387 return DAG.getConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001388 }
1389 }
1390
1391 return SDOperand();
1392}
1393
1394/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1395/// and the value fits into a signed 10-bit constant, and if so, return the
1396/// constant
1397SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1398 MVT::ValueType ValueType) {
1399 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michel6baba072008-03-05 23:02:02 +00001400 int64_t Value = CN->getSignExtended();
Scott Michelbcc7b672008-03-06 04:02:54 +00001401 if (ValueType == MVT::i64) {
1402 uint64_t UValue = CN->getValue();
1403 uint32_t upper = uint32_t(UValue >> 32);
1404 uint32_t lower = uint32_t(UValue);
1405 if (upper != lower)
1406 return SDOperand();
1407 Value = Value >> 32;
1408 }
Scott Michel6baba072008-03-05 23:02:02 +00001409 if (isS10Constant(Value))
Scott Michel8efdca42007-12-04 22:23:35 +00001410 return DAG.getConstant(Value, ValueType);
1411 }
1412
1413 return SDOperand();
1414}
1415
1416/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1417/// and the value fits into a signed 8-bit constant, and if so, return the
1418/// constant.
1419///
1420/// @note: The incoming vector is v16i8 because that's the only way we can load
1421/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1422/// same value.
1423SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1424 MVT::ValueType ValueType) {
1425 if (ConstantSDNode *CN = getVecImm(N)) {
1426 int Value = (int) CN->getValue();
1427 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001428 && Value <= 0xffff /* truncated from uint64_t */
1429 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel8efdca42007-12-04 22:23:35 +00001430 return DAG.getConstant(Value & 0xff, ValueType);
1431 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001432 && (Value & 0xff) == Value)
Scott Michel8efdca42007-12-04 22:23:35 +00001433 return DAG.getConstant(Value, ValueType);
1434 }
1435
1436 return SDOperand();
1437}
1438
1439/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1440/// and the value fits into a signed 16-bit constant, and if so, return the
1441/// constant
1442SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1443 MVT::ValueType ValueType) {
1444 if (ConstantSDNode *CN = getVecImm(N)) {
1445 uint64_t Value = CN->getValue();
1446 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001447 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1448 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel8efdca42007-12-04 22:23:35 +00001449 return DAG.getConstant(Value >> 16, ValueType);
1450 }
1451
1452 return SDOperand();
1453}
1454
1455/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1456SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1457 if (ConstantSDNode *CN = getVecImm(N)) {
1458 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1459 }
1460
1461 return SDOperand();
1462}
1463
1464/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1465SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1466 if (ConstantSDNode *CN = getVecImm(N)) {
1467 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1468 }
1469
1470 return SDOperand();
1471}
1472
1473// If this is a vector of constants or undefs, get the bits. A bit in
1474// UndefBits is set if the corresponding element of the vector is an
1475// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1476// zero. Return true if this is not an array of constants, false if it is.
1477//
1478static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1479 uint64_t UndefBits[2]) {
1480 // Start with zero'd results.
1481 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1482
1483 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1484 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1485 SDOperand OpVal = BV->getOperand(i);
1486
1487 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1488 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1489
1490 uint64_t EltBits = 0;
1491 if (OpVal.getOpcode() == ISD::UNDEF) {
1492 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1493 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1494 continue;
1495 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1496 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1497 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1498 const APFloat &apf = CN->getValueAPF();
1499 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001500 ? FloatToBits(apf.convertToFloat())
1501 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001502 } else {
1503 // Nonconstant element.
1504 return true;
1505 }
1506
1507 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1508 }
1509
1510 //printf("%llx %llx %llx %llx\n",
1511 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1512 return false;
1513}
1514
1515/// If this is a splat (repetition) of a value across the whole vector, return
1516/// the smallest size that splats it. For example, "0x01010101010101..." is a
1517/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1518/// SplatSize = 1 byte.
1519static bool isConstantSplat(const uint64_t Bits128[2],
1520 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001521 int MinSplatBits,
Scott Michel8efdca42007-12-04 22:23:35 +00001522 uint64_t &SplatBits, uint64_t &SplatUndef,
1523 int &SplatSize) {
1524 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1525 // the same as the lower 64-bits, ignoring undefs.
1526 uint64_t Bits64 = Bits128[0] | Bits128[1];
1527 uint64_t Undef64 = Undef128[0] & Undef128[1];
1528 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1529 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1530 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1531 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1532
1533 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1534 if (MinSplatBits < 64) {
1535
1536 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1537 // undefs.
1538 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001539 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001540
Scott Michel5a6f17b2008-01-30 02:55:46 +00001541 // If the top 16-bits are different than the lower 16-bits, ignoring
1542 // undefs, we have an i32 splat.
1543 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1544 if (MinSplatBits < 16) {
1545 // If the top 8-bits are different than the lower 8-bits, ignoring
1546 // undefs, we have an i16 splat.
1547 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1548 // Otherwise, we have an 8-bit splat.
1549 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1550 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1551 SplatSize = 1;
1552 return true;
1553 }
1554 } else {
1555 SplatBits = Bits16;
1556 SplatUndef = Undef16;
1557 SplatSize = 2;
1558 return true;
1559 }
1560 }
1561 } else {
1562 SplatBits = Bits32;
1563 SplatUndef = Undef32;
1564 SplatSize = 4;
1565 return true;
1566 }
Scott Michel8efdca42007-12-04 22:23:35 +00001567 }
1568 } else {
1569 SplatBits = Bits128[0];
1570 SplatUndef = Undef128[0];
1571 SplatSize = 8;
1572 return true;
1573 }
1574 }
1575
1576 return false; // Can't be a splat if two pieces don't match.
1577}
1578
1579// If this is a case we can't handle, return null and let the default
1580// expansion code take care of it. If we CAN select this case, and if it
1581// selects to a single instruction, return Op. Otherwise, if we can codegen
1582// this case more efficiently than a constant pool load, lower it to the
1583// sequence of ops that should be used.
1584static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1585 MVT::ValueType VT = Op.getValueType();
1586 // If this is a vector of constants or undefs, get the bits. A bit in
1587 // UndefBits is set if the corresponding element of the vector is an
1588 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1589 // zero.
1590 uint64_t VectorBits[2];
1591 uint64_t UndefBits[2];
1592 uint64_t SplatBits, SplatUndef;
1593 int SplatSize;
1594 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1595 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001596 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel8efdca42007-12-04 22:23:35 +00001597 SplatBits, SplatUndef, SplatSize))
1598 return SDOperand(); // Not a constant vector, not a splat.
1599
1600 switch (VT) {
1601 default:
1602 case MVT::v4f32: {
1603 uint32_t Value32 = SplatBits;
1604 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001605 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001606 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1607 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1608 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001609 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001610 break;
1611 }
1612 case MVT::v2f64: {
1613 uint64_t f64val = SplatBits;
1614 assert(SplatSize == 8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001615 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel8efdca42007-12-04 22:23:35 +00001616 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1617 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1618 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001619 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001620 break;
1621 }
1622 case MVT::v16i8: {
1623 // 8-bit constants have to be expanded to 16-bits
1624 unsigned short Value16 = SplatBits | (SplatBits << 8);
1625 SDOperand Ops[8];
1626 for (int i = 0; i < 8; ++i)
1627 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1628 return DAG.getNode(ISD::BIT_CONVERT, VT,
1629 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1630 }
1631 case MVT::v8i16: {
1632 unsigned short Value16;
1633 if (SplatSize == 2)
1634 Value16 = (unsigned short) (SplatBits & 0xffff);
1635 else
1636 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1637 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1638 SDOperand Ops[8];
1639 for (int i = 0; i < 8; ++i) Ops[i] = T;
1640 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1641 }
1642 case MVT::v4i32: {
1643 unsigned int Value = SplatBits;
1644 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1645 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1646 }
1647 case MVT::v2i64: {
1648 uint64_t val = SplatBits;
1649 uint32_t upper = uint32_t(val >> 32);
1650 uint32_t lower = uint32_t(val);
1651
Scott Michelbcc7b672008-03-06 04:02:54 +00001652 if (upper == lower) {
1653 // Magic constant that can be matched by IL, ILA, et. al.
1654 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1655 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel6baba072008-03-05 23:02:02 +00001656 } else {
Scott Michel8efdca42007-12-04 22:23:35 +00001657 SDOperand LO32;
1658 SDOperand HI32;
1659 SmallVector<SDOperand, 16> ShufBytes;
1660 SDOperand Result;
1661 bool upper_special, lower_special;
1662
1663 // NOTE: This code creates common-case shuffle masks that can be easily
1664 // detected as common expressions. It is not attempting to create highly
1665 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1666
1667 // Detect if the upper or lower half is a special shuffle mask pattern:
1668 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1669 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1670
1671 // Create lower vector if not a special pattern
1672 if (!lower_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001673 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1674 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1675 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1676 LO32C, LO32C, LO32C, LO32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001677 }
1678
1679 // Create upper vector if not a special pattern
1680 if (!upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001681 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1682 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1683 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1684 HI32C, HI32C, HI32C, HI32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001685 }
1686
1687 // If either upper or lower are special, then the two input operands are
1688 // the same (basically, one of them is a "don't care")
1689 if (lower_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001690 LO32 = HI32;
Scott Michel8efdca42007-12-04 22:23:35 +00001691 if (upper_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001692 HI32 = LO32;
Scott Michel8efdca42007-12-04 22:23:35 +00001693 if (lower_special && upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001694 // Unhappy situation... both upper and lower are special, so punt with
1695 // a target constant:
Scott Michel8efdca42007-12-04 22:23:35 +00001696 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001697 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel8efdca42007-12-04 22:23:35 +00001698 Zero, Zero);
1699 }
1700
1701 for (int i = 0; i < 4; ++i) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001702 for (int j = 0; j < 4; ++j) {
1703 SDOperand V;
1704 bool process_upper, process_lower;
1705 uint64_t val = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001706
Scott Michel5a6f17b2008-01-30 02:55:46 +00001707 process_upper = (upper_special && (i & 1) == 0);
1708 process_lower = (lower_special && (i & 1) == 1);
Scott Michel8efdca42007-12-04 22:23:35 +00001709
Scott Michel5a6f17b2008-01-30 02:55:46 +00001710 if (process_upper || process_lower) {
1711 if ((process_upper && upper == 0)
1712 || (process_lower && lower == 0))
1713 val = 0x80;
1714 else if ((process_upper && upper == 0xffffffff)
1715 || (process_lower && lower == 0xffffffff))
1716 val = 0xc0;
1717 else if ((process_upper && upper == 0x80000000)
1718 || (process_lower && lower == 0x80000000))
1719 val = (j == 0 ? 0xe0 : 0x80);
1720 } else
1721 val = i * 4 + j + ((i & 1) * 16);
Scott Michel8efdca42007-12-04 22:23:35 +00001722
Scott Michel5a6f17b2008-01-30 02:55:46 +00001723 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1724 }
Scott Michel8efdca42007-12-04 22:23:35 +00001725 }
1726
1727 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001728 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1729 &ShufBytes[0], ShufBytes.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001730 }
1731 }
1732 }
1733
1734 return SDOperand();
1735}
1736
1737/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1738/// which the Cell can operate. The code inspects V3 to ascertain whether the
1739/// permutation vector, V3, is monotonically increasing with one "exception"
1740/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1741/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1742/// In either case, the net result is going to eventually invoke SHUFB to
1743/// permute/shuffle the bytes from V1 and V2.
1744/// \note
1745/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1746/// control word for byte/halfword/word insertion. This takes care of a single
1747/// element move from V2 into V1.
1748/// \note
1749/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1750static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1751 SDOperand V1 = Op.getOperand(0);
1752 SDOperand V2 = Op.getOperand(1);
1753 SDOperand PermMask = Op.getOperand(2);
1754
1755 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1756
1757 // If we have a single element being moved from V1 to V2, this can be handled
1758 // using the C*[DX] compute mask instructions, but the vector elements have
1759 // to be monotonically increasing with one exception element.
1760 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1761 unsigned EltsFromV2 = 0;
1762 unsigned V2Elt = 0;
1763 unsigned V2EltIdx0 = 0;
1764 unsigned CurrElt = 0;
1765 bool monotonic = true;
1766 if (EltVT == MVT::i8)
1767 V2EltIdx0 = 16;
1768 else if (EltVT == MVT::i16)
1769 V2EltIdx0 = 8;
1770 else if (EltVT == MVT::i32)
1771 V2EltIdx0 = 4;
1772 else
1773 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1774
1775 for (unsigned i = 0, e = PermMask.getNumOperands();
1776 EltsFromV2 <= 1 && monotonic && i != e;
1777 ++i) {
1778 unsigned SrcElt;
1779 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1780 SrcElt = 0;
1781 else
1782 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1783
1784 if (SrcElt >= V2EltIdx0) {
1785 ++EltsFromV2;
1786 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1787 } else if (CurrElt != SrcElt) {
1788 monotonic = false;
1789 }
1790
1791 ++CurrElt;
1792 }
1793
1794 if (EltsFromV2 == 1 && monotonic) {
1795 // Compute mask and shuffle
1796 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001797 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1798 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00001799 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1800 // Initialize temporary register to 0
1801 SDOperand InitTempReg =
1802 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1803 // Copy register's contents as index in INSERT_MASK:
1804 SDOperand ShufMaskOp =
1805 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001806 DAG.getTargetConstant(V2Elt, MVT::i32),
1807 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001808 // Use shuffle mask in SHUFB synthetic instruction:
1809 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1810 } else {
1811 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1812 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1813
1814 SmallVector<SDOperand, 16> ResultMask;
1815 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1816 unsigned SrcElt;
1817 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001818 SrcElt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001819 else
Scott Michel5a6f17b2008-01-30 02:55:46 +00001820 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001821
Scott Michel97872d32008-02-23 18:41:37 +00001822 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001823 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1824 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001825 }
1826 }
1827
1828 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001829 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001830 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1831 }
1832}
1833
1834static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001835 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001836
1837 if (Op0.Val->getOpcode() == ISD::Constant) {
1838 // For a constant, build the appropriate constant vector, which will
1839 // eventually simplify to a vector register load.
1840
1841 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1842 SmallVector<SDOperand, 16> ConstVecValues;
1843 MVT::ValueType VT;
1844 size_t n_copies;
1845
1846 // Create a constant vector:
1847 switch (Op.getValueType()) {
1848 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001849 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001850 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1851 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1852 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1853 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1854 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1855 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1856 }
1857
1858 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1859 for (size_t j = 0; j < n_copies; ++j)
1860 ConstVecValues.push_back(CValue);
1861
1862 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001863 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001864 } else {
1865 // Otherwise, copy the value from one register to another:
1866 switch (Op0.getValueType()) {
1867 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1868 case MVT::i8:
1869 case MVT::i16:
1870 case MVT::i32:
1871 case MVT::i64:
1872 case MVT::f32:
1873 case MVT::f64:
1874 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1875 }
1876 }
1877
1878 return SDOperand();
1879}
1880
1881static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1882 switch (Op.getValueType()) {
1883 case MVT::v4i32: {
1884 SDOperand rA = Op.getOperand(0);
1885 SDOperand rB = Op.getOperand(1);
1886 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1887 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1888 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1889 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1890
1891 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1892 break;
1893 }
1894
1895 // Multiply two v8i16 vectors (pipeline friendly version):
1896 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1897 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1898 // c) Use SELB to select upper and lower halves from the intermediate results
1899 //
1900 // NOTE: We really want to move the FSMBI to earlier to actually get the
1901 // dual-issue. This code does manage to do this, even if it's a little on
1902 // the wacky side
1903 case MVT::v8i16: {
1904 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001905 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00001906 SDOperand Chain = Op.getOperand(0);
1907 SDOperand rA = Op.getOperand(0);
1908 SDOperand rB = Op.getOperand(1);
Chris Lattner1b989192007-12-31 04:13:23 +00001909 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1910 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00001911
1912 SDOperand FSMBOp =
1913 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001914 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1915 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel8efdca42007-12-04 22:23:35 +00001916
1917 SDOperand HHProd =
1918 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001919 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00001920
1921 SDOperand HHProd_v4i32 =
1922 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001923 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001924
1925 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001926 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1927 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1928 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1929 HHProd_v4i32,
1930 DAG.getConstant(16, MVT::i16))),
1931 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001932 }
1933
1934 // This M00sE is N@stI! (apologies to Monty Python)
1935 //
1936 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1937 // is to break it all apart, sign extend, and reassemble the various
1938 // intermediate products.
1939 case MVT::v16i8: {
Scott Michel8efdca42007-12-04 22:23:35 +00001940 SDOperand rA = Op.getOperand(0);
1941 SDOperand rB = Op.getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00001942 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1943 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001944
1945 SDOperand LLProd =
1946 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001947 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1948 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00001949
1950 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1951
1952 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1953
1954 SDOperand LHProd =
1955 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001956 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel8efdca42007-12-04 22:23:35 +00001957
Scott Michel97872d32008-02-23 18:41:37 +00001958 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1959 DAG.getConstant(0x2222, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001960
Scott Michel97872d32008-02-23 18:41:37 +00001961 SDOperand LoProdParts =
1962 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1963 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1964 LLProd, LHProd, FSMBmask));
Scott Michel8efdca42007-12-04 22:23:35 +00001965
1966 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1967
1968 SDOperand LoProd =
1969 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michel97872d32008-02-23 18:41:37 +00001970 LoProdParts,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001971 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1972 LoProdMask, LoProdMask,
1973 LoProdMask, LoProdMask));
Scott Michel8efdca42007-12-04 22:23:35 +00001974
1975 SDOperand rAH =
1976 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001977 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel8efdca42007-12-04 22:23:35 +00001978
1979 SDOperand rBH =
1980 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001981 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel8efdca42007-12-04 22:23:35 +00001982
1983 SDOperand HLProd =
1984 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001985 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1986 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel8efdca42007-12-04 22:23:35 +00001987
1988 SDOperand HHProd_1 =
1989 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001990 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1991 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1992 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1993 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel8efdca42007-12-04 22:23:35 +00001994
1995 SDOperand HHProd =
Scott Michel97872d32008-02-23 18:41:37 +00001996 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1997 HLProd,
1998 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
1999 FSMBmask);
Scott Michel8efdca42007-12-04 22:23:35 +00002000
2001 SDOperand HiProd =
Scott Michel97872d32008-02-23 18:41:37 +00002002 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel8efdca42007-12-04 22:23:35 +00002003
2004 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002005 DAG.getNode(ISD::OR, MVT::v4i32,
2006 LoProd, HiProd));
Scott Michel8efdca42007-12-04 22:23:35 +00002007 }
2008
2009 default:
2010 cerr << "CellSPU: Unknown vector multiplication, got "
2011 << MVT::getValueTypeString(Op.getValueType())
Scott Michel5a6f17b2008-01-30 02:55:46 +00002012 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002013 abort();
2014 /*NOTREACHED*/
2015 }
2016
2017 return SDOperand();
2018}
2019
2020static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2021 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002022 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002023
2024 SDOperand A = Op.getOperand(0);
2025 SDOperand B = Op.getOperand(1);
2026 unsigned VT = Op.getValueType();
2027
2028 unsigned VRegBR, VRegC;
2029
2030 if (VT == MVT::f32) {
Chris Lattner1b989192007-12-31 04:13:23 +00002031 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2032 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002033 } else {
Chris Lattner1b989192007-12-31 04:13:23 +00002034 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2035 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002036 }
2037 // TODO: make sure we're feeding FPInterp the right arguments
2038 // Right now: fi B, frest(B)
2039
2040 // Computes BRcpl =
2041 // (Floating Interpolate (FP Reciprocal Estimate B))
2042 SDOperand BRcpl =
2043 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002044 DAG.getNode(SPUISD::FPInterp, VT, B,
2045 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel8efdca42007-12-04 22:23:35 +00002046
2047 // Computes A * BRcpl and stores in a temporary register
2048 SDOperand AxBRcpl =
2049 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002050 DAG.getNode(ISD::FMUL, VT, A,
2051 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel8efdca42007-12-04 22:23:35 +00002052 // What's the Chain variable do? It's magic!
2053 // TODO: set Chain = Op(0).getEntryNode()
2054
2055 return DAG.getNode(ISD::FADD, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002056 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2057 DAG.getNode(ISD::FMUL, VT,
2058 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2059 DAG.getNode(ISD::FSUB, VT, A,
2060 DAG.getNode(ISD::FMUL, VT, B,
2061 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel8efdca42007-12-04 22:23:35 +00002062}
2063
Scott Michel8efdca42007-12-04 22:23:35 +00002064static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2065 unsigned VT = Op.getValueType();
2066 SDOperand N = Op.getOperand(0);
2067 SDOperand Elt = Op.getOperand(1);
2068 SDOperand ShufMask[16];
2069 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2070
2071 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2072
2073 int EltNo = (int) C->getValue();
2074
2075 // sanity checks:
2076 if (VT == MVT::i8 && EltNo >= 16)
2077 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2078 else if (VT == MVT::i16 && EltNo >= 8)
2079 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2080 else if (VT == MVT::i32 && EltNo >= 4)
2081 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2082 else if (VT == MVT::i64 && EltNo >= 2)
2083 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2084
2085 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2086 // i32 and i64: Element 0 is the preferred slot
2087 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2088 }
2089
2090 // Need to generate shuffle mask and extract:
Scott Michel4c07cbd2007-12-19 21:17:42 +00002091 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel8efdca42007-12-04 22:23:35 +00002092 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2093
2094 switch (VT) {
2095 case MVT::i8: {
2096 prefslot_begin = prefslot_end = 3;
2097 break;
2098 }
2099 case MVT::i16: {
2100 prefslot_begin = 2; prefslot_end = 3;
2101 break;
2102 }
2103 case MVT::i32: {
2104 prefslot_begin = 0; prefslot_end = 3;
2105 break;
2106 }
2107 case MVT::i64: {
2108 prefslot_begin = 0; prefslot_end = 7;
2109 break;
2110 }
2111 }
2112
Scott Michel4c07cbd2007-12-19 21:17:42 +00002113 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel5a6f17b2008-01-30 02:55:46 +00002114 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel4c07cbd2007-12-19 21:17:42 +00002115
Scott Michel8efdca42007-12-04 22:23:35 +00002116 for (int i = 0; i < 16; ++i) {
2117 // zero fill uppper part of preferred slot, don't care about the
2118 // other slots:
2119 unsigned int mask_val;
2120
2121 if (i <= prefslot_end) {
2122 mask_val =
Scott Michel5a6f17b2008-01-30 02:55:46 +00002123 ((i < prefslot_begin)
2124 ? 0x80
2125 : elt_byte + (i - prefslot_begin));
Scott Michel8efdca42007-12-04 22:23:35 +00002126
Scott Michel4c07cbd2007-12-19 21:17:42 +00002127 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002128 } else
2129 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2130 }
2131
2132 SDOperand ShufMaskVec =
2133 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002134 &ShufMask[0],
2135 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel8efdca42007-12-04 22:23:35 +00002136
2137 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002138 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2139 N, N, ShufMaskVec));
2140
Scott Michel8efdca42007-12-04 22:23:35 +00002141}
2142
2143static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2144 SDOperand VecOp = Op.getOperand(0);
2145 SDOperand ValOp = Op.getOperand(1);
2146 SDOperand IdxOp = Op.getOperand(2);
2147 MVT::ValueType VT = Op.getValueType();
2148
2149 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2150 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2151
2152 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2153 // Use $2 because it's always 16-byte aligned and it's available:
2154 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2155
2156 SDOperand result =
2157 DAG.getNode(SPUISD::SHUFB, VT,
2158 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2159 VecOp,
2160 DAG.getNode(SPUISD::INSERT_MASK, VT,
2161 DAG.getNode(ISD::ADD, PtrVT,
2162 PtrBase,
2163 DAG.getConstant(CN->getValue(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002164 PtrVT))));
Scott Michel8efdca42007-12-04 22:23:35 +00002165
2166 return result;
2167}
2168
Scott Michel97872d32008-02-23 18:41:37 +00002169static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2170{
Scott Michel8efdca42007-12-04 22:23:35 +00002171 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2172
2173 assert(Op.getValueType() == MVT::i8);
2174 switch (Opc) {
2175 default:
2176 assert(0 && "Unhandled i8 math operator");
2177 /*NOTREACHED*/
2178 break;
2179 case ISD::SUB: {
2180 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2181 // the result:
2182 SDOperand N1 = Op.getOperand(1);
2183 N0 = (N0.getOpcode() != ISD::Constant
2184 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2185 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2186 N1 = (N1.getOpcode() != ISD::Constant
2187 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2188 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2189 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2190 DAG.getNode(Opc, MVT::i16, N0, N1));
2191 }
2192 case ISD::ROTR:
2193 case ISD::ROTL: {
2194 SDOperand N1 = Op.getOperand(1);
2195 unsigned N1Opc;
2196 N0 = (N0.getOpcode() != ISD::Constant
2197 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2198 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2199 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2200 N1 = (N1.getOpcode() != ISD::Constant
2201 ? DAG.getNode(N1Opc, MVT::i16, N1)
2202 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2203 SDOperand ExpandArg =
2204 DAG.getNode(ISD::OR, MVT::i16, N0,
2205 DAG.getNode(ISD::SHL, MVT::i16,
2206 N0, DAG.getConstant(8, MVT::i16)));
2207 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2208 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2209 }
2210 case ISD::SRL:
2211 case ISD::SHL: {
2212 SDOperand N1 = Op.getOperand(1);
2213 unsigned N1Opc;
2214 N0 = (N0.getOpcode() != ISD::Constant
2215 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2216 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2217 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2218 N1 = (N1.getOpcode() != ISD::Constant
2219 ? DAG.getNode(N1Opc, MVT::i16, N1)
2220 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2221 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2222 DAG.getNode(Opc, MVT::i16, N0, N1));
2223 }
2224 case ISD::SRA: {
2225 SDOperand N1 = Op.getOperand(1);
2226 unsigned N1Opc;
2227 N0 = (N0.getOpcode() != ISD::Constant
2228 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2229 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2230 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2231 N1 = (N1.getOpcode() != ISD::Constant
2232 ? DAG.getNode(N1Opc, MVT::i16, N1)
2233 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2234 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2235 DAG.getNode(Opc, MVT::i16, N0, N1));
2236 }
2237 case ISD::MUL: {
2238 SDOperand N1 = Op.getOperand(1);
2239 unsigned N1Opc;
2240 N0 = (N0.getOpcode() != ISD::Constant
2241 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2242 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2243 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2244 N1 = (N1.getOpcode() != ISD::Constant
2245 ? DAG.getNode(N1Opc, MVT::i16, N1)
2246 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2247 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2248 DAG.getNode(Opc, MVT::i16, N0, N1));
2249 break;
2250 }
2251 }
2252
2253 return SDOperand();
2254}
2255
Scott Michel97872d32008-02-23 18:41:37 +00002256static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2257{
2258 MVT::ValueType VT = Op.getValueType();
2259 unsigned VecVT =
2260 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2261
2262 SDOperand Op0 = Op.getOperand(0);
2263
2264 switch (Opc) {
2265 case ISD::ZERO_EXTEND:
2266 case ISD::SIGN_EXTEND:
2267 case ISD::ANY_EXTEND: {
2268 MVT::ValueType Op0VT = Op0.getValueType();
2269 unsigned Op0VecVT =
2270 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2271
2272 assert(Op0VT == MVT::i32
2273 && "CellSPU: Zero/sign extending something other than i32");
2274
2275 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2276 ? SPUISD::ROTBYTES_RIGHT_S
2277 : SPUISD::ROTQUAD_RZ_BYTES);
2278 SDOperand PromoteScalar =
2279 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2280
2281 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2282 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2283 DAG.getNode(NewOpc, Op0VecVT,
2284 PromoteScalar,
2285 DAG.getConstant(4, MVT::i32))));
2286 }
2287
2288 case ISD::SHL: {
2289 SDOperand ShiftAmt = Op.getOperand(1);
2290 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2291 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2292 SDOperand MaskLower =
2293 DAG.getNode(SPUISD::SELB, VecVT,
2294 Op0Vec,
2295 DAG.getConstant(0, VecVT),
2296 DAG.getNode(SPUISD::FSMBI, VecVT,
2297 DAG.getConstant(0xff00ULL, MVT::i16)));
2298 SDOperand ShiftAmtBytes =
2299 DAG.getNode(ISD::SRL, ShiftAmtVT,
2300 ShiftAmt,
2301 DAG.getConstant(3, ShiftAmtVT));
2302 SDOperand ShiftAmtBits =
2303 DAG.getNode(ISD::AND, ShiftAmtVT,
2304 ShiftAmt,
2305 DAG.getConstant(7, ShiftAmtVT));
2306
2307 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2308 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2309 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2310 MaskLower, ShiftAmtBytes),
2311 ShiftAmtBits));
2312 }
2313
2314 case ISD::SRL: {
2315 unsigned VT = unsigned(Op.getValueType());
2316 SDOperand ShiftAmt = Op.getOperand(1);
2317 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2318 SDOperand ShiftAmtBytes =
2319 DAG.getNode(ISD::SRL, ShiftAmtVT,
2320 ShiftAmt,
2321 DAG.getConstant(3, ShiftAmtVT));
2322 SDOperand ShiftAmtBits =
2323 DAG.getNode(ISD::AND, ShiftAmtVT,
2324 ShiftAmt,
2325 DAG.getConstant(7, ShiftAmtVT));
2326
2327 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2328 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2329 Op0, ShiftAmtBytes),
2330 ShiftAmtBits);
2331 }
2332 }
2333
2334 return SDOperand();
2335}
2336
Scott Michel8efdca42007-12-04 22:23:35 +00002337//! Lower byte immediate operations for v16i8 vectors:
2338static SDOperand
2339LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2340 SDOperand ConstVec;
2341 SDOperand Arg;
2342 MVT::ValueType VT = Op.getValueType();
2343
2344 ConstVec = Op.getOperand(0);
2345 Arg = Op.getOperand(1);
2346 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2347 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2348 ConstVec = ConstVec.getOperand(0);
2349 } else {
2350 ConstVec = Op.getOperand(1);
2351 Arg = Op.getOperand(0);
2352 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002353 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002354 }
2355 }
2356 }
2357
2358 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2359 uint64_t VectorBits[2];
2360 uint64_t UndefBits[2];
2361 uint64_t SplatBits, SplatUndef;
2362 int SplatSize;
2363
2364 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002365 && isConstantSplat(VectorBits, UndefBits,
2366 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2367 SplatBits, SplatUndef, SplatSize)) {
Scott Michel8efdca42007-12-04 22:23:35 +00002368 SDOperand tcVec[16];
2369 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2370 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2371
2372 // Turn the BUILD_VECTOR into a set of target constants:
2373 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002374 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002375
2376 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002377 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002378 }
2379 }
2380
2381 return SDOperand();
2382}
2383
2384//! Lower i32 multiplication
2385static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2386 unsigned Opc) {
2387 switch (VT) {
2388 default:
2389 cerr << "CellSPU: Unknown LowerMUL value type, got "
2390 << MVT::getValueTypeString(Op.getValueType())
Scott Michel5a6f17b2008-01-30 02:55:46 +00002391 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002392 abort();
2393 /*NOTREACHED*/
2394
2395 case MVT::i32: {
2396 SDOperand rA = Op.getOperand(0);
2397 SDOperand rB = Op.getOperand(1);
2398
2399 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002400 DAG.getNode(ISD::ADD, MVT::i32,
2401 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2402 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2403 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel8efdca42007-12-04 22:23:35 +00002404 }
2405 }
2406
2407 return SDOperand();
2408}
2409
2410//! Custom lowering for CTPOP (count population)
2411/*!
2412 Custom lowering code that counts the number ones in the input
2413 operand. SPU has such an instruction, but it counts the number of
2414 ones per byte, which then have to be accumulated.
2415*/
2416static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2417 unsigned VT = Op.getValueType();
2418 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2419
2420 switch (VT) {
2421 case MVT::i8: {
2422 SDOperand N = Op.getOperand(0);
2423 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2424
2425 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2426 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2427
2428 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2429 }
2430
2431 case MVT::i16: {
2432 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002433 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002434
Chris Lattner1b989192007-12-31 04:13:23 +00002435 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002436
2437 SDOperand N = Op.getOperand(0);
2438 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2439 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2440 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2441
2442 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2443 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2444
2445 // CNTB_result becomes the chain to which all of the virtual registers
2446 // CNTB_reg, SUM1_reg become associated:
2447 SDOperand CNTB_result =
2448 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel5a6f17b2008-01-30 02:55:46 +00002449
Scott Michel8efdca42007-12-04 22:23:35 +00002450 SDOperand CNTB_rescopy =
2451 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2452
2453 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2454
2455 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002456 DAG.getNode(ISD::ADD, MVT::i16,
2457 DAG.getNode(ISD::SRL, MVT::i16,
2458 Tmp1, Shift1),
2459 Tmp1),
2460 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002461 }
2462
2463 case MVT::i32: {
2464 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002465 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002466
Chris Lattner1b989192007-12-31 04:13:23 +00002467 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2468 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002469
2470 SDOperand N = Op.getOperand(0);
2471 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2472 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2473 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2474 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2475
2476 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2477 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2478
2479 // CNTB_result becomes the chain to which all of the virtual registers
2480 // CNTB_reg, SUM1_reg become associated:
2481 SDOperand CNTB_result =
2482 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel5a6f17b2008-01-30 02:55:46 +00002483
Scott Michel8efdca42007-12-04 22:23:35 +00002484 SDOperand CNTB_rescopy =
2485 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2486
2487 SDOperand Comp1 =
2488 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002489 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002490
2491 SDOperand Sum1 =
2492 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002493 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002494
2495 SDOperand Sum1_rescopy =
2496 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2497
2498 SDOperand Comp2 =
2499 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002500 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2501 Shift2);
Scott Michel8efdca42007-12-04 22:23:35 +00002502 SDOperand Sum2 =
2503 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002504 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002505
2506 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2507 }
2508
2509 case MVT::i64:
2510 break;
2511 }
2512
2513 return SDOperand();
2514}
2515
2516/// LowerOperation - Provide custom lowering hooks for some operations.
2517///
2518SDOperand
2519SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2520{
Scott Michel97872d32008-02-23 18:41:37 +00002521 unsigned Opc = (unsigned) Op.getOpcode();
2522 unsigned VT = (unsigned) Op.getValueType();
2523
2524 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002525 default: {
2526 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002527 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +00002528 cerr << "*Op.Val:\n";
2529 Op.Val->dump();
2530 abort();
2531 }
2532 case ISD::LOAD:
2533 case ISD::SEXTLOAD:
2534 case ISD::ZEXTLOAD:
2535 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2536 case ISD::STORE:
2537 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2538 case ISD::ConstantPool:
2539 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2540 case ISD::GlobalAddress:
2541 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2542 case ISD::JumpTable:
2543 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2544 case ISD::Constant:
2545 return LowerConstant(Op, DAG);
2546 case ISD::ConstantFP:
2547 return LowerConstantFP(Op, DAG);
Scott Michel394e26d2008-01-17 20:38:41 +00002548 case ISD::BRCOND:
2549 return LowerBRCOND(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002550 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002551 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002552 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002553 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002554 case ISD::RET:
2555 return LowerRET(Op, DAG, getTargetMachine());
2556
Scott Michel97872d32008-02-23 18:41:37 +00002557
2558 // i8, i64 math ops:
2559 case ISD::ZERO_EXTEND:
2560 case ISD::SIGN_EXTEND:
2561 case ISD::ANY_EXTEND:
Scott Michel8efdca42007-12-04 22:23:35 +00002562 case ISD::SUB:
2563 case ISD::ROTR:
2564 case ISD::ROTL:
2565 case ISD::SRL:
2566 case ISD::SHL:
2567 case ISD::SRA:
Scott Michel97872d32008-02-23 18:41:37 +00002568 if (VT == MVT::i8)
2569 return LowerI8Math(Op, DAG, Opc);
2570 else if (VT == MVT::i64)
2571 return LowerI64Math(Op, DAG, Opc);
2572 break;
Scott Michel8efdca42007-12-04 22:23:35 +00002573
2574 // Vector-related lowering.
2575 case ISD::BUILD_VECTOR:
2576 return LowerBUILD_VECTOR(Op, DAG);
2577 case ISD::SCALAR_TO_VECTOR:
2578 return LowerSCALAR_TO_VECTOR(Op, DAG);
2579 case ISD::VECTOR_SHUFFLE:
2580 return LowerVECTOR_SHUFFLE(Op, DAG);
2581 case ISD::EXTRACT_VECTOR_ELT:
2582 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2583 case ISD::INSERT_VECTOR_ELT:
2584 return LowerINSERT_VECTOR_ELT(Op, DAG);
2585
2586 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2587 case ISD::AND:
2588 case ISD::OR:
2589 case ISD::XOR:
2590 return LowerByteImmed(Op, DAG);
2591
2592 // Vector and i8 multiply:
2593 case ISD::MUL:
Scott Michel97872d32008-02-23 18:41:37 +00002594 if (MVT::isVector(VT))
Scott Michel8efdca42007-12-04 22:23:35 +00002595 return LowerVectorMUL(Op, DAG);
Scott Michel97872d32008-02-23 18:41:37 +00002596 else if (VT == MVT::i8)
2597 return LowerI8Math(Op, DAG, Opc);
Scott Michel8efdca42007-12-04 22:23:35 +00002598 else
Scott Michel97872d32008-02-23 18:41:37 +00002599 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel8efdca42007-12-04 22:23:35 +00002600
2601 case ISD::FDIV:
Scott Michel97872d32008-02-23 18:41:37 +00002602 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel8efdca42007-12-04 22:23:35 +00002603 return LowerFDIVf32(Op, DAG);
2604// else if (Op.getValueType() == MVT::f64)
2605// return LowerFDIVf64(Op, DAG);
2606 else
2607 assert(0 && "Calling FDIV on unsupported MVT");
2608
2609 case ISD::CTPOP:
2610 return LowerCTPOP(Op, DAG);
2611 }
2612
2613 return SDOperand();
2614}
2615
2616//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002617// Target Optimization Hooks
2618//===----------------------------------------------------------------------===//
2619
2620SDOperand
2621SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2622{
2623#if 0
2624 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002625#endif
2626 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002627 SelectionDAG &DAG = DCI.DAG;
Scott Michel97872d32008-02-23 18:41:37 +00002628 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2629 SDOperand Result; // Initially, NULL result
Scott Michel8efdca42007-12-04 22:23:35 +00002630
2631 switch (N->getOpcode()) {
2632 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002633 case ISD::ADD: {
Scott Michelf9f42e62008-01-29 02:16:57 +00002634 SDOperand Op1 = N->getOperand(1);
2635
2636 if ((Op1.getOpcode() == ISD::Constant
2637 || Op1.getOpcode() == ISD::TargetConstant)
2638 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2639 SDOperand Op01 = Op0.getOperand(1);
2640 if (Op01.getOpcode() == ISD::Constant
2641 || Op01.getOpcode() == ISD::TargetConstant) {
2642 // (add <const>, (SPUindirect <arg>, <const>)) ->
2643 // (SPUindirect <arg>, <const + const>)
2644 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2645 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2646 SDOperand combinedConst =
2647 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2648 Op0.getValueType());
2649
2650 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2651 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2652 DEBUG(cerr << "With: (SPUindirect <arg>, "
2653 << CN0->getValue() + CN1->getValue() << ")\n");
2654 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2655 Op0.getOperand(0), combinedConst);
2656 }
2657 } else if ((Op0.getOpcode() == ISD::Constant
2658 || Op0.getOpcode() == ISD::TargetConstant)
2659 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2660 SDOperand Op11 = Op1.getOperand(1);
2661 if (Op11.getOpcode() == ISD::Constant
2662 || Op11.getOpcode() == ISD::TargetConstant) {
2663 // (add (SPUindirect <arg>, <const>), <const>) ->
2664 // (SPUindirect <arg>, <const + const>)
2665 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2666 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2667 SDOperand combinedConst =
2668 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2669 Op0.getValueType());
2670
2671 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2672 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2673 DEBUG(cerr << "With: (SPUindirect <arg>, "
2674 << CN0->getValue() + CN1->getValue() << ")\n");
2675
2676 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2677 Op1.getOperand(0), combinedConst);
2678 }
2679 }
Scott Michel97872d32008-02-23 18:41:37 +00002680 break;
2681 }
2682 case ISD::SIGN_EXTEND:
2683 case ISD::ZERO_EXTEND:
2684 case ISD::ANY_EXTEND: {
2685 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2686 N->getValueType(0) == Op0.getValueType()) {
2687 // (any_extend (SPUextract_elt0 <arg>)) ->
2688 // (SPUextract_elt0 <arg>)
2689 // Types must match, however...
2690 DEBUG(cerr << "Replace: ");
2691 DEBUG(N->dump(&DAG));
2692 DEBUG(cerr << "\nWith: ");
2693 DEBUG(Op0.Val->dump(&DAG));
2694 DEBUG(cerr << "\n");
2695
2696 return Op0;
2697 }
2698 break;
2699 }
2700 case SPUISD::IndirectAddr: {
2701 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2702 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2703 if (CN->getValue() == 0) {
2704 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2705 // (SPUaform <addr>, 0)
2706
2707 DEBUG(cerr << "Replace: ");
2708 DEBUG(N->dump(&DAG));
2709 DEBUG(cerr << "\nWith: ");
2710 DEBUG(Op0.Val->dump(&DAG));
2711 DEBUG(cerr << "\n");
2712
2713 return Op0;
2714 }
2715 }
2716 break;
2717 }
2718 case SPUISD::SHLQUAD_L_BITS:
2719 case SPUISD::SHLQUAD_L_BYTES:
2720 case SPUISD::VEC_SHL:
2721 case SPUISD::VEC_SRL:
2722 case SPUISD::VEC_SRA:
2723 case SPUISD::ROTQUAD_RZ_BYTES:
2724 case SPUISD::ROTQUAD_RZ_BITS: {
2725 SDOperand Op1 = N->getOperand(1);
2726
2727 if (isa<ConstantSDNode>(Op1)) {
2728 // Kill degenerate vector shifts:
2729 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2730
2731 if (CN->getValue() == 0) {
2732 Result = Op0;
2733 }
2734 }
2735 break;
2736 }
2737 case SPUISD::PROMOTE_SCALAR: {
2738 switch (Op0.getOpcode()) {
2739 default:
2740 break;
2741 case ISD::ANY_EXTEND:
2742 case ISD::ZERO_EXTEND:
2743 case ISD::SIGN_EXTEND: {
2744 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2745 // <arg>
2746 // but only if the SPUpromote_scalar and <arg> types match.
2747 SDOperand Op00 = Op0.getOperand(0);
2748 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2749 SDOperand Op000 = Op00.getOperand(0);
2750 if (Op000.getValueType() == N->getValueType(0)) {
2751 Result = Op000;
2752 }
2753 }
2754 break;
2755 }
2756 case SPUISD::EXTRACT_ELT0: {
2757 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2758 // <arg>
2759 Result = Op0.getOperand(0);
2760 break;
2761 }
2762 }
2763 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002764 }
2765 }
Scott Michel394e26d2008-01-17 20:38:41 +00002766 // Otherwise, return unchanged.
Scott Michel97872d32008-02-23 18:41:37 +00002767#if 0
2768 if (Result.Val) {
2769 DEBUG(cerr << "\nReplace.SPU: ");
2770 DEBUG(N->dump(&DAG));
2771 DEBUG(cerr << "\nWith: ");
2772 DEBUG(Result.Val->dump(&DAG));
2773 DEBUG(cerr << "\n");
2774 }
2775#endif
2776
2777 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002778}
2779
2780//===----------------------------------------------------------------------===//
2781// Inline Assembly Support
2782//===----------------------------------------------------------------------===//
2783
2784/// getConstraintType - Given a constraint letter, return the type of
2785/// constraint it is for this target.
2786SPUTargetLowering::ConstraintType
2787SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2788 if (ConstraintLetter.size() == 1) {
2789 switch (ConstraintLetter[0]) {
2790 default: break;
2791 case 'b':
2792 case 'r':
2793 case 'f':
2794 case 'v':
2795 case 'y':
2796 return C_RegisterClass;
2797 }
2798 }
2799 return TargetLowering::getConstraintType(ConstraintLetter);
2800}
2801
2802std::pair<unsigned, const TargetRegisterClass*>
2803SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2804 MVT::ValueType VT) const
2805{
2806 if (Constraint.size() == 1) {
2807 // GCC RS6000 Constraint Letters
2808 switch (Constraint[0]) {
2809 case 'b': // R1-R31
2810 case 'r': // R0-R31
2811 if (VT == MVT::i64)
2812 return std::make_pair(0U, SPU::R64CRegisterClass);
2813 return std::make_pair(0U, SPU::R32CRegisterClass);
2814 case 'f':
2815 if (VT == MVT::f32)
2816 return std::make_pair(0U, SPU::R32FPRegisterClass);
2817 else if (VT == MVT::f64)
2818 return std::make_pair(0U, SPU::R64FPRegisterClass);
2819 break;
2820 case 'v':
2821 return std::make_pair(0U, SPU::GPRCRegisterClass);
2822 }
2823 }
2824
2825 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2826}
2827
Scott Michel97872d32008-02-23 18:41:37 +00002828//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002829void
2830SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002831 const APInt &Mask,
Dan Gohman229fa052008-02-13 00:35:47 +00002832 APInt &KnownZero,
2833 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002834 const SelectionDAG &DAG,
2835 unsigned Depth ) const {
Scott Michel97872d32008-02-23 18:41:37 +00002836 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2837
2838 switch (Op.getOpcode()) {
2839 default:
2840 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2841 break;
2842
2843#if 0
2844 case CALL:
2845 case SHUFB:
2846 case INSERT_MASK:
2847 case CNTB:
2848#endif
2849
2850 case SPUISD::PROMOTE_SCALAR: {
2851 SDOperand Op0 = Op.getOperand(0);
2852 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2853 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2854 KnownOne |= APInt(uint64_sizebits, InMask, false);
2855 break;
2856 }
2857
2858 case SPUISD::LDRESULT:
2859 case SPUISD::EXTRACT_ELT0:
2860 case SPUISD::EXTRACT_ELT0_CHAINED: {
2861 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2862 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2863 KnownOne |= APInt(uint64_sizebits, InMask, false);
2864 break;
2865 }
2866
2867#if 0
2868 case EXTRACT_I1_ZEXT:
2869 case EXTRACT_I1_SEXT:
2870 case EXTRACT_I8_ZEXT:
2871 case EXTRACT_I8_SEXT:
2872 case MPY:
2873 case MPYU:
2874 case MPYH:
2875 case MPYHH:
2876 case SHLQUAD_L_BITS:
2877 case SHLQUAD_L_BYTES:
2878 case VEC_SHL:
2879 case VEC_SRL:
2880 case VEC_SRA:
2881 case VEC_ROTL:
2882 case VEC_ROTR:
2883 case ROTQUAD_RZ_BYTES:
2884 case ROTQUAD_RZ_BITS:
2885 case ROTBYTES_RIGHT_S:
2886 case ROTBYTES_LEFT:
2887 case ROTBYTES_LEFT_CHAINED:
2888 case FSMBI:
2889 case SELB:
2890 case SFPConstant:
2891 case FPInterp:
2892 case FPRecipEst:
2893 case SEXT32TO64:
2894#endif
2895 }
Scott Michel8efdca42007-12-04 22:23:35 +00002896}
2897
Scott Michel8efdca42007-12-04 22:23:35 +00002898/// isLegalAddressImmediate - Return true if the integer value can be used
2899/// as the offset of the target addressing mode.
2900bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2901 // SPU's addresses are 256K:
2902 return (V > -(1 << 18) && V < (1 << 18) - 1);
2903}
2904
2905bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2906 return false;
2907}