blob: 99243d3a62b2f82146ce4c97ed1ea2d59a53aa36 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
17#include "llvm/ADT/VectorExtras.h"
18#include "llvm/Analysis/ScalarEvolutionExpressions.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000024#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/Constants.h"
26#include "llvm/Function.h"
27#include "llvm/Intrinsics.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Target/TargetOptions.h"
31
32#include <map>
33
34using namespace llvm;
35
36// Used in getTargetNodeName() below
37namespace {
38 std::map<unsigned, const char *> node_names;
39
40 //! MVT::ValueType mapping to useful data for Cell SPU
41 struct valtype_map_s {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000042 const MVT::ValueType valtype;
43 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000044 };
45
46 const valtype_map_s valtype_map[] = {
47 { MVT::i1, 3 },
48 { MVT::i8, 3 },
49 { MVT::i16, 2 },
50 { MVT::i32, 0 },
51 { MVT::f32, 0 },
52 { MVT::i64, 0 },
53 { MVT::f64, 0 },
54 { MVT::i128, 0 }
55 };
56
57 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
58
59 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) {
60 const valtype_map_s *retval = 0;
61
62 for (size_t i = 0; i < n_valtype_map; ++i) {
63 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000064 retval = valtype_map + i;
65 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000066 }
67 }
68
69#ifndef NDEBUG
70 if (retval == 0) {
71 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel7f9ba9b2008-01-30 02:55:46 +000072 << MVT::getValueTypeString(VT)
73 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000074 abort();
75 }
76#endif
77
78 return retval;
79 }
80
81 //! Predicate that returns true if operand is a memory target
82 /*!
83 \arg Op Operand to test
84 \return true if the operand is a memory target (i.e., global
Scott Michel9de5d0d2008-01-11 02:53:15 +000085 address, external symbol, constant pool) or an A-form
Scott Michel266bc8f2007-12-04 22:23:35 +000086 address.
87 */
88 bool isMemoryOperand(const SDOperand &Op)
89 {
90 const unsigned Opc = Op.getOpcode();
91 return (Opc == ISD::GlobalAddress
92 || Opc == ISD::GlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000093 || Opc == ISD::JumpTable
94 || Opc == ISD::ConstantPool
95 || Opc == ISD::ExternalSymbol
96 || Opc == ISD::TargetGlobalAddress
97 || Opc == ISD::TargetGlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000098 || Opc == ISD::TargetJumpTable
99 || Opc == ISD::TargetConstantPool
100 || Opc == ISD::TargetExternalSymbol
Scott Michel9de5d0d2008-01-11 02:53:15 +0000101 || Opc == SPUISD::AFormAddr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000102 }
Scott Michel58c58182008-01-17 20:38:41 +0000103
104 //! Predicate that returns true if the operand is an indirect target
105 bool isIndirectOperand(const SDOperand &Op)
106 {
107 const unsigned Opc = Op.getOpcode();
108 return (Opc == ISD::Register
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000109 || Opc == SPUISD::LDRESULT);
Scott Michel58c58182008-01-17 20:38:41 +0000110 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000111}
112
113SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
114 : TargetLowering(TM),
115 SPUTM(TM)
116{
117 // Fold away setcc operations if possible.
118 setPow2DivIsCheap();
119
120 // Use _setjmp/_longjmp instead of setjmp/longjmp.
121 setUseUnderscoreSetJmp(true);
122 setUseUnderscoreLongJmp(true);
123
124 // Set up the SPU's register classes:
125 // NOTE: i8 register class is not registered because we cannot determine when
126 // we need to zero or sign extend for custom-lowered loads and stores.
Scott Michel504c3692007-12-17 22:32:34 +0000127 // NOTE: Ignore the previous note. For now. :-)
128 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
129 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
130 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
131 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
132 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
133 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000134 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
135
136 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000137 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000138 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
139 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000140 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
142 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
143 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
144 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000145
146 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
147 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
148 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000149 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
151 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
152 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
153 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
154
Scott Michel266bc8f2007-12-04 22:23:35 +0000155 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
156 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
157 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
158
159 // SPU constant load actions are custom lowered:
160 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000161 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000162 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
163
164 // SPU's loads and stores have to be custom lowered:
165 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
166 ++sctype) {
167 setOperationAction(ISD::LOAD, sctype, Custom);
168 setOperationAction(ISD::STORE, sctype, Custom);
169 }
170
Scott Michel58c58182008-01-17 20:38:41 +0000171 // Custom lower BRCOND for i1, i8 to "promote" the result to
172 // i32 and i16, respectively.
173 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000174
175 // Expand the jumptable branches
176 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
177 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
178 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
179
180 // SPU has no intrinsics for these particular operations:
181 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
182 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
183 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000184 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
185
Scott Michel266bc8f2007-12-04 22:23:35 +0000186 // PowerPC has no SREM/UREM instructions
187 setOperationAction(ISD::SREM, MVT::i32, Expand);
188 setOperationAction(ISD::UREM, MVT::i32, Expand);
189 setOperationAction(ISD::SREM, MVT::i64, Expand);
190 setOperationAction(ISD::UREM, MVT::i64, Expand);
191
192 // We don't support sin/cos/sqrt/fmod
193 setOperationAction(ISD::FSIN , MVT::f64, Expand);
194 setOperationAction(ISD::FCOS , MVT::f64, Expand);
195 setOperationAction(ISD::FREM , MVT::f64, Expand);
196 setOperationAction(ISD::FSIN , MVT::f32, Expand);
197 setOperationAction(ISD::FCOS , MVT::f32, Expand);
198 setOperationAction(ISD::FREM , MVT::f32, Expand);
199
200 // If we're enabling GP optimizations, use hardware square root
201 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
202 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
203
204 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
205 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
206
207 // SPU can do rotate right and left, so legalize it... but customize for i8
208 // because instructions don't exist.
209 setOperationAction(ISD::ROTR, MVT::i32, Legal);
210 setOperationAction(ISD::ROTR, MVT::i16, Legal);
211 setOperationAction(ISD::ROTR, MVT::i8, Custom);
212 setOperationAction(ISD::ROTL, MVT::i32, Legal);
213 setOperationAction(ISD::ROTL, MVT::i16, Legal);
214 setOperationAction(ISD::ROTL, MVT::i8, Custom);
215 // SPU has no native version of shift left/right for i8
216 setOperationAction(ISD::SHL, MVT::i8, Custom);
217 setOperationAction(ISD::SRL, MVT::i8, Custom);
218 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000219 // And SPU needs custom lowering for shift left/right for i64
220 setOperationAction(ISD::SHL, MVT::i64, Custom);
221 setOperationAction(ISD::SRL, MVT::i64, Custom);
222 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000223
224 // Custom lower i32 multiplications
225 setOperationAction(ISD::MUL, MVT::i32, Custom);
226
227 // Need to custom handle (some) common i8 math ops
228 setOperationAction(ISD::SUB, MVT::i8, Custom);
229 setOperationAction(ISD::MUL, MVT::i8, Custom);
230
231 // SPU does not have BSWAP. It does have i32 support CTLZ.
232 // CTPOP has to be custom lowered.
233 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
234 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
235
236 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
237 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
238 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
239 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
240
241 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
242 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
243
244 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
245
246 // SPU does not have select or setcc
247 setOperationAction(ISD::SELECT, MVT::i1, Expand);
248 setOperationAction(ISD::SELECT, MVT::i8, Expand);
249 setOperationAction(ISD::SELECT, MVT::i16, Expand);
250 setOperationAction(ISD::SELECT, MVT::i32, Expand);
251 setOperationAction(ISD::SELECT, MVT::i64, Expand);
252 setOperationAction(ISD::SELECT, MVT::f32, Expand);
253 setOperationAction(ISD::SELECT, MVT::f64, Expand);
254
Scott Michela59d4692008-02-23 18:41:37 +0000255 // Zero extension and sign extension for i64 have to be
256 // custom legalized
257 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
258 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
259 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000260
261 // SPU has a legal FP -> signed INT instruction
262 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
263 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
264 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
265 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
266
267 // FDIV on SPU requires custom lowering
268 setOperationAction(ISD::FDIV, MVT::f32, Custom);
269 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
270
271 // SPU has [U|S]INT_TO_FP
272 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
273 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
274 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
275 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
276 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
277 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
278 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
279 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
280
Scott Michel86c041f2007-12-20 00:44:13 +0000281 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
282 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
283 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
284 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000285
286 // We cannot sextinreg(i1). Expand to shifts.
287 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
288
289 // Support label based line numbers.
290 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
291 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
292
293 // We want to legalize GlobalAddress and ConstantPool nodes into the
294 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000295 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
296 ++sctype) {
297 setOperationAction(ISD::GlobalAddress, sctype, Custom);
298 setOperationAction(ISD::ConstantPool, sctype, Custom);
299 setOperationAction(ISD::JumpTable, sctype, Custom);
300 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000301
302 // RET must be custom lowered, to meet ABI requirements
303 setOperationAction(ISD::RET, MVT::Other, Custom);
304
305 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
306 setOperationAction(ISD::VASTART , MVT::Other, Custom);
307
308 // Use the default implementation.
309 setOperationAction(ISD::VAARG , MVT::Other, Expand);
310 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
311 setOperationAction(ISD::VAEND , MVT::Other, Expand);
312 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
313 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
314 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
315 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
316
317 // Cell SPU has instructions for converting between i64 and fp.
318 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
319 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
320
321 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
322 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
323
324 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
325 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
326
327 // First set operation action for all vector types to expand. Then we
328 // will selectively turn on ones that can be effectively codegen'd.
329 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
330 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
331 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
332 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
333 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
334 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
335
336 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
337 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
338 // add/sub are legal for all supported vector VT's.
339 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
340 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
341 // mul has to be custom lowered.
342 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
343
344 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
345 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
346 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
347 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
348 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
349 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
350
351 // These operations need to be expanded:
352 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
353 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
354 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
355 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
356 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
357
358 // Custom lower build_vector, constant pool spills, insert and
359 // extract vector elements:
360 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
361 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
362 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
363 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
364 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
365 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
366 }
367
368 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
369 setOperationAction(ISD::AND, MVT::v16i8, Custom);
370 setOperationAction(ISD::OR, MVT::v16i8, Custom);
371 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
372 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000373
Scott Michel266bc8f2007-12-04 22:23:35 +0000374 setSetCCResultType(MVT::i32);
375 setShiftAmountType(MVT::i32);
376 setSetCCResultContents(ZeroOrOneSetCCResult);
377
378 setStackPointerRegisterToSaveRestore(SPU::R1);
379
380 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000381 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000382 setTargetDAGCombine(ISD::ZERO_EXTEND);
383 setTargetDAGCombine(ISD::SIGN_EXTEND);
384 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel266bc8f2007-12-04 22:23:35 +0000385
386 computeRegisterProperties();
387}
388
389const char *
390SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
391{
392 if (node_names.empty()) {
393 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
394 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
395 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
396 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000397 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000398 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000399 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
400 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
401 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
402 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
403 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
404 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
405 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
406 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
407 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
408 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
409 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
410 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
411 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
412 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
413 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
414 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michela59d4692008-02-23 18:41:37 +0000415 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
416 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000417 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
418 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
419 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
420 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
421 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michela59d4692008-02-23 18:41:37 +0000422 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
423 "SPUISD::ROTQUAD_RZ_BYTES";
424 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
425 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel266bc8f2007-12-04 22:23:35 +0000426 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
427 "SPUISD::ROTBYTES_RIGHT_S";
428 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
429 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
430 "SPUISD::ROTBYTES_LEFT_CHAINED";
431 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
432 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel266bc8f2007-12-04 22:23:35 +0000433 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
434 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
435 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
436 }
437
438 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
439
440 return ((i != node_names.end()) ? i->second : 0);
441}
442
443//===----------------------------------------------------------------------===//
444// Calling convention code:
445//===----------------------------------------------------------------------===//
446
447#include "SPUGenCallingConv.inc"
448
449//===----------------------------------------------------------------------===//
450// LowerOperation implementation
451//===----------------------------------------------------------------------===//
452
Scott Michel9de5d0d2008-01-11 02:53:15 +0000453/// Aligned load common code for CellSPU
454/*!
455 \param[in] Op The SelectionDAG load or store operand
456 \param[in] DAG The selection DAG
457 \param[in] ST CellSPU subtarget information structure
458 \param[in,out] alignment Caller initializes this to the load or store node's
459 value from getAlignment(), may be updated while generating the aligned load
460 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
461 offset (divisible by 16, modulo 16 == 0)
462 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
463 offset of the preferred slot (modulo 16 != 0)
464 \param[in,out] VT Caller initializes this value type to the the load or store
465 node's loaded or stored value type; may be updated if an i1-extended load or
466 store.
467 \param[out] was16aligned true if the base pointer had 16-byte alignment,
468 otherwise false. Can help to determine if the chunk needs to be rotated.
469
470 Both load and store lowering load a block of data aligned on a 16-byte
471 boundary. This is the common aligned load code shared between both.
472 */
473static SDOperand
474AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
475 LSBaseSDNode *LSN,
476 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000477 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000478{
479 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
480 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
481 SDOperand basePtr = LSN->getBasePtr();
482 SDOperand chain = LSN->getChain();
483
484 if (basePtr.getOpcode() == ISD::ADD) {
485 SDOperand Op1 = basePtr.Val->getOperand(1);
486
487 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000488 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000489
490 alignOffs = (int) CN->getValue();
491 prefSlotOffs = (int) (alignOffs & 0xf);
492
493 // Adjust the rotation amount to ensure that the final result ends up in
494 // the preferred slot:
495 prefSlotOffs -= vtm->prefslot_byte;
496 basePtr = basePtr.getOperand(0);
497
Scott Michel58c58182008-01-17 20:38:41 +0000498 // Loading from memory, can we adjust alignment?
499 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
500 SDOperand APtr = basePtr.getOperand(0);
501 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
502 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
503 alignment = GSDN->getGlobal()->getAlignment();
504 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000505 }
506 } else {
507 alignOffs = 0;
508 prefSlotOffs = -vtm->prefslot_byte;
509 }
510 } else {
511 alignOffs = 0;
512 prefSlotOffs = -vtm->prefslot_byte;
513 }
514
515 if (alignment == 16) {
516 // Realign the base pointer as a D-Form address:
517 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000518 basePtr = DAG.getNode(ISD::ADD, PtrVT,
519 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000520 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000521 }
522
523 // Emit the vector load:
524 was16aligned = true;
525 return DAG.getLoad(MVT::v16i8, chain, basePtr,
526 LSN->getSrcValue(), LSN->getSrcValueOffset(),
527 LSN->isVolatile(), 16);
528 }
529
530 // Unaligned load or we're using the "large memory" model, which means that
531 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000532 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000533 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000534 }
535
536 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000537 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000538 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000539 was16aligned = false;
540 return DAG.getLoad(MVT::v16i8, chain, basePtr,
541 LSN->getSrcValue(), LSN->getSrcValueOffset(),
542 LSN->isVolatile(), 16);
543}
544
Scott Michel266bc8f2007-12-04 22:23:35 +0000545/// Custom lower loads for CellSPU
546/*!
547 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
548 within a 16-byte block, we have to rotate to extract the requested element.
549 */
550static SDOperand
551LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
552 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000553 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000554 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000555 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000556 ISD::LoadExtType ExtType = LN->getExtensionType();
557 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000558 SDOperand Ops[8];
559
Scott Michel266bc8f2007-12-04 22:23:35 +0000560 switch (LN->getAddressingMode()) {
561 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000562 int offset, rotamt;
563 bool was16aligned;
564 SDOperand result =
565 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000566
Scott Michel9de5d0d2008-01-11 02:53:15 +0000567 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000568 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000569
570 the_chain = result.getValue(1);
571 // Rotate the chunk if necessary
572 if (rotamt < 0)
573 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000574 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000575 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
576
Scott Michel58c58182008-01-17 20:38:41 +0000577 Ops[0] = the_chain;
578 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000579 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000580 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
581 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000582 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000583 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000584 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000585 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000586 }
587
588 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
589 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000590 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000591
592 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
593 SDVTList scalarvts;
594 MVT::ValueType vecVT = MVT::v16i8;
595
596 // Convert the loaded v16i8 vector to the appropriate vector type
597 // specified by the operand:
598 if (OpVT == VT) {
599 if (VT != MVT::i1)
600 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
601 } else
602 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
603
604 Ops[0] = the_chain;
605 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
606 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
607 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
608 the_chain = result.getValue(1);
609 } else {
610 // Handle the sign and zero-extending loads for i1 and i8:
611 unsigned NewOpC;
612
613 if (ExtType == ISD::SEXTLOAD) {
614 NewOpC = (OpVT == MVT::i1
615 ? SPUISD::EXTRACT_I1_SEXT
616 : SPUISD::EXTRACT_I8_SEXT);
617 } else {
618 assert(ExtType == ISD::ZEXTLOAD);
619 NewOpC = (OpVT == MVT::i1
620 ? SPUISD::EXTRACT_I1_ZEXT
621 : SPUISD::EXTRACT_I8_ZEXT);
622 }
623
624 result = DAG.getNode(NewOpC, OpVT, result);
625 }
626
627 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000628 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000629 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000630 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000631 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000632
Scott Michel58c58182008-01-17 20:38:41 +0000633 result = DAG.getNode(SPUISD::LDRESULT, retvts,
634 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000635 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000636 }
637 case ISD::PRE_INC:
638 case ISD::PRE_DEC:
639 case ISD::POST_INC:
640 case ISD::POST_DEC:
641 case ISD::LAST_INDEXED_MODE:
642 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
643 "UNINDEXED\n";
644 cerr << (unsigned) LN->getAddressingMode() << "\n";
645 abort();
646 /*NOTREACHED*/
647 }
648
649 return SDOperand();
650}
651
652/// Custom lower stores for CellSPU
653/*!
654 All CellSPU stores are aligned to 16-byte boundaries, so for elements
655 within a 16-byte block, we have to generate a shuffle to insert the
656 requested element into its place, then store the resulting block.
657 */
658static SDOperand
659LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
660 StoreSDNode *SN = cast<StoreSDNode>(Op);
661 SDOperand Value = SN->getValue();
662 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000663 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000664 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000665 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000666
667 switch (SN->getAddressingMode()) {
668 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000669 int chunk_offset, slot_offset;
670 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000671
672 // The vector type we really want to load from the 16-byte chunk, except
673 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000674 unsigned vecVT, stVecVT = MVT::v16i8;
675
Scott Michel266bc8f2007-12-04 22:23:35 +0000676 if (StVT != MVT::i1)
677 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000678 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
679
Scott Michel9de5d0d2008-01-11 02:53:15 +0000680 SDOperand alignLoadVec =
681 AlignedLoad(Op, DAG, ST, SN, alignment,
682 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000683
Scott Michel9de5d0d2008-01-11 02:53:15 +0000684 if (alignLoadVec.Val == 0)
685 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000686
Scott Michel9de5d0d2008-01-11 02:53:15 +0000687 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
688 SDOperand basePtr = LN->getBasePtr();
689 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000690 SDOperand theValue = SN->getValue();
691 SDOperand result;
692
693 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000694 && (theValue.getOpcode() == ISD::AssertZext
695 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000696 // Drill down and get the value for zero- and sign-extended
697 // quantities
698 theValue = theValue.getOperand(0);
699 }
700
Scott Michel9de5d0d2008-01-11 02:53:15 +0000701 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000702
Scott Michel9de5d0d2008-01-11 02:53:15 +0000703 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
704 SDOperand insertEltPtr;
705 SDOperand insertEltOp;
706
707 // If the base pointer is already a D-form address, then just create
708 // a new D-form address with a slot offset and the orignal base pointer.
709 // Otherwise generate a D-form address with the slot offset relative
710 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000711 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
712 DEBUG(basePtr.Val->dump(&DAG));
713 DEBUG(cerr << "\n");
714
Scott Michel053c1da2008-01-29 02:16:57 +0000715 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
716 (basePtr.getOpcode() == ISD::ADD
717 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000718 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000719 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000720 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000721 }
722
723 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000724 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000725 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
726 alignLoadVec,
727 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000728
Scott Michel9de5d0d2008-01-11 02:53:15 +0000729 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000730 LN->getSrcValue(), LN->getSrcValueOffset(),
731 LN->isVolatile(), LN->getAlignment());
732
733 return result;
734 /*UNREACHED*/
735 }
736 case ISD::PRE_INC:
737 case ISD::PRE_DEC:
738 case ISD::POST_INC:
739 case ISD::POST_DEC:
740 case ISD::LAST_INDEXED_MODE:
741 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
742 "UNINDEXED\n";
743 cerr << (unsigned) SN->getAddressingMode() << "\n";
744 abort();
745 /*NOTREACHED*/
746 }
747
748 return SDOperand();
749}
750
751/// Generate the address of a constant pool entry.
752static SDOperand
753LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
754 MVT::ValueType PtrVT = Op.getValueType();
755 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
756 Constant *C = CP->getConstVal();
757 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000758 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000759 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000760
761 if (TM.getRelocationModel() == Reloc::Static) {
762 if (!ST->usingLargeMem()) {
763 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000764 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000765 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000766 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
767 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000768 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000769 }
770 }
771
772 assert(0 &&
773 "LowerConstantPool: Relocation model other than static not supported.");
774 return SDOperand();
775}
776
777static SDOperand
778LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
779 MVT::ValueType PtrVT = Op.getValueType();
780 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
781 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
782 SDOperand Zero = DAG.getConstant(0, PtrVT);
783 const TargetMachine &TM = DAG.getTarget();
784
785 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000786 if (!ST->usingLargeMem()) {
787 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
788 } else {
789 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
790 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
791 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
792 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000793 }
794
795 assert(0 &&
796 "LowerJumpTable: Relocation model other than static not supported.");
797 return SDOperand();
798}
799
800static SDOperand
801LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
802 MVT::ValueType PtrVT = Op.getValueType();
803 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
804 GlobalValue *GV = GSDN->getGlobal();
805 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000806 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000807 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000808
809 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000810 if (!ST->usingLargeMem()) {
811 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
812 } else {
813 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
814 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
815 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
816 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000817 } else {
818 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000819 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000820 abort();
821 /*NOTREACHED*/
822 }
823
824 return SDOperand();
825}
826
827//! Custom lower i64 integer constants
828/*!
829 This code inserts all of the necessary juggling that needs to occur to load
830 a 64-bit constant into a register.
831 */
832static SDOperand
833LowerConstant(SDOperand Op, SelectionDAG &DAG) {
834 unsigned VT = Op.getValueType();
835 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
836
837 if (VT == MVT::i64) {
838 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
839 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000840 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000841
842 } else {
843 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000844 << MVT::getValueTypeString(VT)
845 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000846 abort();
847 /*NOTREACHED*/
848 }
849
850 return SDOperand();
851}
852
Nate Begemanccef5802008-02-14 18:43:04 +0000853//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000854static SDOperand
855LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
856 unsigned VT = Op.getValueType();
857 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
858
859 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000860 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000861
Nate Begemanccef5802008-02-14 18:43:04 +0000862 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000863 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000864 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000865 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000866 }
867
868 return SDOperand();
869}
870
Scott Michel58c58182008-01-17 20:38:41 +0000871//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
872static SDOperand
873LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
874{
875 SDOperand Cond = Op.getOperand(1);
876 MVT::ValueType CondVT = Cond.getValueType();
877 MVT::ValueType CondNVT;
878
879 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
880 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
881 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
882 Op.getOperand(0),
883 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
884 Op.getOperand(2));
885 } else
886 return SDOperand(); // Unchanged
887}
888
Scott Michel266bc8f2007-12-04 22:23:35 +0000889static SDOperand
890LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
891{
892 MachineFunction &MF = DAG.getMachineFunction();
893 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000894 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000895 SmallVector<SDOperand, 8> ArgValues;
896 SDOperand Root = Op.getOperand(0);
897 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
898
899 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
900 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
901
902 unsigned ArgOffset = SPUFrameInfo::minStackSize();
903 unsigned ArgRegIdx = 0;
904 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
905
906 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
907
908 // Add DAG nodes to load the arguments or copy them out of registers.
909 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
910 SDOperand ArgVal;
911 bool needsLoad = false;
912 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
913 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
914
915 switch (ObjectVT) {
916 default: {
917 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000918 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000919 << "\n";
920 abort();
921 }
922 case MVT::i8:
923 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000924 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
925 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000926 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
927 ++ArgRegIdx;
928 } else {
929 needsLoad = true;
930 }
931 break;
932 case MVT::i16:
933 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000934 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
935 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000936 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
937 ++ArgRegIdx;
938 } else {
939 needsLoad = true;
940 }
941 break;
942 case MVT::i32:
943 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000944 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
945 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000946 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
947 ++ArgRegIdx;
948 } else {
949 needsLoad = true;
950 }
951 break;
952 case MVT::i64:
953 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000954 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
955 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000956 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
957 ++ArgRegIdx;
958 } else {
959 needsLoad = true;
960 }
961 break;
962 case MVT::f32:
963 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000964 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
965 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000966 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
967 ++ArgRegIdx;
968 } else {
969 needsLoad = true;
970 }
971 break;
972 case MVT::f64:
973 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000974 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
975 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000976 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
977 ++ArgRegIdx;
978 } else {
979 needsLoad = true;
980 }
981 break;
982 case MVT::v2f64:
983 case MVT::v4f32:
984 case MVT::v4i32:
985 case MVT::v8i16:
986 case MVT::v16i8:
987 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000988 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
989 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000990 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
991 ++ArgRegIdx;
992 } else {
993 needsLoad = true;
994 }
995 break;
996 }
997
998 // We need to load the argument to a virtual register if we determined above
999 // that we ran out of physical registers of the appropriate type
1000 if (needsLoad) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001001 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1002 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1003 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001004 ArgOffset += StackSlotSize;
1005 }
1006
1007 ArgValues.push_back(ArgVal);
1008 }
1009
1010 // If the function takes variable number of arguments, make a frame index for
1011 // the start of the first vararg value... for expansion of llvm.va_start.
1012 if (isVarArg) {
1013 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1014 ArgOffset);
1015 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1016 // If this function is vararg, store any remaining integer argument regs to
1017 // their spots on the stack so that they may be loaded by deferencing the
1018 // result of va_next.
1019 SmallVector<SDOperand, 8> MemOps;
1020 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001021 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1022 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001023 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1024 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1025 MemOps.push_back(Store);
1026 // Increment the address by four for the next argument to store
1027 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1028 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1029 }
1030 if (!MemOps.empty())
1031 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1032 }
1033
1034 ArgValues.push_back(Root);
1035
1036 // Return the new list of results.
1037 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1038 Op.Val->value_end());
1039 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1040}
1041
1042/// isLSAAddress - Return the immediate to use if the specified
1043/// value is representable as a LSA address.
1044static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1045 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1046 if (!C) return 0;
1047
1048 int Addr = C->getValue();
1049 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1050 (Addr << 14 >> 14) != Addr)
1051 return 0; // Top 14 bits have to be sext of immediate.
1052
1053 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1054}
1055
1056static
1057SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001058LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001059 SDOperand Chain = Op.getOperand(0);
1060#if 0
1061 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1062 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1063#endif
1064 SDOperand Callee = Op.getOperand(4);
1065 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1066 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1067 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1068 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1069
1070 // Handy pointer type
1071 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1072
1073 // Accumulate how many bytes are to be pushed on the stack, including the
1074 // linkage area, and parameter passing area. According to the SPU ABI,
1075 // we minimally need space for [LR] and [SP]
1076 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1077
1078 // Set up a copy of the stack pointer for use loading and storing any
1079 // arguments that may not fit in the registers available for argument
1080 // passing.
1081 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1082
1083 // Figure out which arguments are going to go in registers, and which in
1084 // memory.
1085 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1086 unsigned ArgRegIdx = 0;
1087
1088 // Keep track of registers passing arguments
1089 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1090 // And the arguments passed on the stack
1091 SmallVector<SDOperand, 8> MemOpChains;
1092
1093 for (unsigned i = 0; i != NumOps; ++i) {
1094 SDOperand Arg = Op.getOperand(5+2*i);
1095
1096 // PtrOff will be used to store the current argument to the stack if a
1097 // register cannot be found for it.
1098 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1099 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1100
1101 switch (Arg.getValueType()) {
1102 default: assert(0 && "Unexpected ValueType for argument!");
1103 case MVT::i32:
1104 case MVT::i64:
1105 case MVT::i128:
1106 if (ArgRegIdx != NumArgRegs) {
1107 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1108 } else {
1109 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001110 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001111 }
1112 break;
1113 case MVT::f32:
1114 case MVT::f64:
1115 if (ArgRegIdx != NumArgRegs) {
1116 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1117 } else {
1118 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001119 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001120 }
1121 break;
1122 case MVT::v4f32:
1123 case MVT::v4i32:
1124 case MVT::v8i16:
1125 case MVT::v16i8:
1126 if (ArgRegIdx != NumArgRegs) {
1127 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1128 } else {
1129 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001130 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001131 }
1132 break;
1133 }
1134 }
1135
1136 // Update number of stack bytes actually used, insert a call sequence start
1137 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1138 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1139
1140 if (!MemOpChains.empty()) {
1141 // Adjust the stack pointer for the stack arguments.
1142 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1143 &MemOpChains[0], MemOpChains.size());
1144 }
1145
1146 // Build a sequence of copy-to-reg nodes chained together with token chain
1147 // and flag operands which copy the outgoing args into the appropriate regs.
1148 SDOperand InFlag;
1149 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1150 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1151 InFlag);
1152 InFlag = Chain.getValue(1);
1153 }
1154
1155 std::vector<MVT::ValueType> NodeTys;
1156 NodeTys.push_back(MVT::Other); // Returns a chain
1157 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1158
1159 SmallVector<SDOperand, 8> Ops;
1160 unsigned CallOpc = SPUISD::CALL;
1161
1162 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1163 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1164 // node so that legalize doesn't hack it.
1165 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1166 GlobalValue *GV = G->getGlobal();
1167 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001168 SDOperand Zero = DAG.getConstant(0, PtrVT);
1169 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001170
Scott Michel9de5d0d2008-01-11 02:53:15 +00001171 if (!ST->usingLargeMem()) {
1172 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1173 // style calls, otherwise, external symbols are BRASL calls. This assumes
1174 // that declared/defined symbols are in the same compilation unit and can
1175 // be reached through PC-relative jumps.
1176 //
1177 // NOTE:
1178 // This may be an unsafe assumption for JIT and really large compilation
1179 // units.
1180 if (GV->isDeclaration()) {
1181 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1182 } else {
1183 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1184 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001185 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001186 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1187 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001188 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001189 }
1190 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1191 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001192 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001193 // If this is an absolute destination address that appears to be a legal
1194 // local store address, use the munged value.
1195 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001196 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001197
1198 Ops.push_back(Chain);
1199 Ops.push_back(Callee);
1200
1201 // Add argument registers to the end of the list so that they are known live
1202 // into the call.
1203 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1204 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1205 RegsToPass[i].second.getValueType()));
1206
1207 if (InFlag.Val)
1208 Ops.push_back(InFlag);
1209 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1210 InFlag = Chain.getValue(1);
1211
Evan Chengebaaa912008-02-05 22:44:06 +00001212 Chain = DAG.getCALLSEQ_END(Chain,
1213 DAG.getConstant(NumStackBytes, PtrVT),
1214 DAG.getConstant(0, PtrVT),
1215 InFlag);
1216 if (Op.Val->getValueType(0) != MVT::Other)
1217 InFlag = Chain.getValue(1);
1218
Scott Michel266bc8f2007-12-04 22:23:35 +00001219 SDOperand ResultVals[3];
1220 unsigned NumResults = 0;
1221 NodeTys.clear();
1222
1223 // If the call has results, copy the values out of the ret val registers.
1224 switch (Op.Val->getValueType(0)) {
1225 default: assert(0 && "Unexpected ret value!");
1226 case MVT::Other: break;
1227 case MVT::i32:
1228 if (Op.Val->getValueType(1) == MVT::i32) {
1229 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1230 ResultVals[0] = Chain.getValue(0);
1231 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1232 Chain.getValue(2)).getValue(1);
1233 ResultVals[1] = Chain.getValue(0);
1234 NumResults = 2;
1235 NodeTys.push_back(MVT::i32);
1236 } else {
1237 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1238 ResultVals[0] = Chain.getValue(0);
1239 NumResults = 1;
1240 }
1241 NodeTys.push_back(MVT::i32);
1242 break;
1243 case MVT::i64:
1244 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1245 ResultVals[0] = Chain.getValue(0);
1246 NumResults = 1;
1247 NodeTys.push_back(MVT::i64);
1248 break;
1249 case MVT::f32:
1250 case MVT::f64:
1251 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1252 InFlag).getValue(1);
1253 ResultVals[0] = Chain.getValue(0);
1254 NumResults = 1;
1255 NodeTys.push_back(Op.Val->getValueType(0));
1256 break;
1257 case MVT::v2f64:
1258 case MVT::v4f32:
1259 case MVT::v4i32:
1260 case MVT::v8i16:
1261 case MVT::v16i8:
1262 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1263 InFlag).getValue(1);
1264 ResultVals[0] = Chain.getValue(0);
1265 NumResults = 1;
1266 NodeTys.push_back(Op.Val->getValueType(0));
1267 break;
1268 }
1269
Scott Michel266bc8f2007-12-04 22:23:35 +00001270 NodeTys.push_back(MVT::Other);
1271
1272 // If the function returns void, just return the chain.
1273 if (NumResults == 0)
1274 return Chain;
1275
1276 // Otherwise, merge everything together with a MERGE_VALUES node.
1277 ResultVals[NumResults++] = Chain;
1278 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1279 ResultVals, NumResults);
1280 return Res.getValue(Op.ResNo);
1281}
1282
1283static SDOperand
1284LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1285 SmallVector<CCValAssign, 16> RVLocs;
1286 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1287 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1288 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1289 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1290
1291 // If this is the first return lowered for this function, add the regs to the
1292 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001293 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001294 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001295 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001296 }
1297
1298 SDOperand Chain = Op.getOperand(0);
1299 SDOperand Flag;
1300
1301 // Copy the result values into the output registers.
1302 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1303 CCValAssign &VA = RVLocs[i];
1304 assert(VA.isRegLoc() && "Can only return in registers!");
1305 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1306 Flag = Chain.getValue(1);
1307 }
1308
1309 if (Flag.Val)
1310 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1311 else
1312 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1313}
1314
1315
1316//===----------------------------------------------------------------------===//
1317// Vector related lowering:
1318//===----------------------------------------------------------------------===//
1319
1320static ConstantSDNode *
1321getVecImm(SDNode *N) {
1322 SDOperand OpVal(0, 0);
1323
1324 // Check to see if this buildvec has a single non-undef value in its elements.
1325 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1326 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1327 if (OpVal.Val == 0)
1328 OpVal = N->getOperand(i);
1329 else if (OpVal != N->getOperand(i))
1330 return 0;
1331 }
1332
1333 if (OpVal.Val != 0) {
1334 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1335 return CN;
1336 }
1337 }
1338
1339 return 0; // All UNDEF: use implicit def.; not Constant node
1340}
1341
1342/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1343/// and the value fits into an unsigned 18-bit constant, and if so, return the
1344/// constant
1345SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1346 MVT::ValueType ValueType) {
1347 if (ConstantSDNode *CN = getVecImm(N)) {
1348 uint64_t Value = CN->getValue();
1349 if (Value <= 0x3ffff)
1350 return DAG.getConstant(Value, ValueType);
1351 }
1352
1353 return SDOperand();
1354}
1355
1356/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1357/// and the value fits into a signed 16-bit constant, and if so, return the
1358/// constant
1359SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1360 MVT::ValueType ValueType) {
1361 if (ConstantSDNode *CN = getVecImm(N)) {
1362 if (ValueType == MVT::i32) {
1363 int Value = (int) CN->getValue();
1364 int SExtValue = ((Value & 0xffff) << 16) >> 16;
1365
1366 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001367 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001368 } else if (ValueType == MVT::i16) {
1369 short Value = (short) CN->getValue();
1370 int SExtValue = ((int) Value << 16) >> 16;
1371
1372 if (Value == (short) SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001373 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001374 } else if (ValueType == MVT::i64) {
1375 int64_t Value = CN->getValue();
1376 int64_t SExtValue = ((Value & 0xffff) << (64 - 16)) >> (64 - 16);
1377
1378 if (Value == SExtValue)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001379 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001380 }
1381 }
1382
1383 return SDOperand();
1384}
1385
1386/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1387/// and the value fits into a signed 10-bit constant, and if so, return the
1388/// constant
1389SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1390 MVT::ValueType ValueType) {
1391 if (ConstantSDNode *CN = getVecImm(N)) {
1392 int Value = (int) CN->getValue();
1393 if ((ValueType == MVT::i32 && isS10Constant(Value))
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001394 || (ValueType == MVT::i16 && isS10Constant((short) Value)))
Scott Michel266bc8f2007-12-04 22:23:35 +00001395 return DAG.getConstant(Value, ValueType);
1396 }
1397
1398 return SDOperand();
1399}
1400
1401/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1402/// and the value fits into a signed 8-bit constant, and if so, return the
1403/// constant.
1404///
1405/// @note: The incoming vector is v16i8 because that's the only way we can load
1406/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1407/// same value.
1408SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1409 MVT::ValueType ValueType) {
1410 if (ConstantSDNode *CN = getVecImm(N)) {
1411 int Value = (int) CN->getValue();
1412 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001413 && Value <= 0xffff /* truncated from uint64_t */
1414 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001415 return DAG.getConstant(Value & 0xff, ValueType);
1416 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001417 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001418 return DAG.getConstant(Value, ValueType);
1419 }
1420
1421 return SDOperand();
1422}
1423
1424/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1425/// and the value fits into a signed 16-bit constant, and if so, return the
1426/// constant
1427SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1428 MVT::ValueType ValueType) {
1429 if (ConstantSDNode *CN = getVecImm(N)) {
1430 uint64_t Value = CN->getValue();
1431 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001432 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1433 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001434 return DAG.getConstant(Value >> 16, ValueType);
1435 }
1436
1437 return SDOperand();
1438}
1439
1440/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1441SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1442 if (ConstantSDNode *CN = getVecImm(N)) {
1443 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1444 }
1445
1446 return SDOperand();
1447}
1448
1449/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1450SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1451 if (ConstantSDNode *CN = getVecImm(N)) {
1452 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1453 }
1454
1455 return SDOperand();
1456}
1457
1458// If this is a vector of constants or undefs, get the bits. A bit in
1459// UndefBits is set if the corresponding element of the vector is an
1460// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1461// zero. Return true if this is not an array of constants, false if it is.
1462//
1463static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1464 uint64_t UndefBits[2]) {
1465 // Start with zero'd results.
1466 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1467
1468 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1469 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1470 SDOperand OpVal = BV->getOperand(i);
1471
1472 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1473 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1474
1475 uint64_t EltBits = 0;
1476 if (OpVal.getOpcode() == ISD::UNDEF) {
1477 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1478 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1479 continue;
1480 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1481 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1482 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1483 const APFloat &apf = CN->getValueAPF();
1484 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001485 ? FloatToBits(apf.convertToFloat())
1486 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001487 } else {
1488 // Nonconstant element.
1489 return true;
1490 }
1491
1492 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1493 }
1494
1495 //printf("%llx %llx %llx %llx\n",
1496 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1497 return false;
1498}
1499
1500/// If this is a splat (repetition) of a value across the whole vector, return
1501/// the smallest size that splats it. For example, "0x01010101010101..." is a
1502/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1503/// SplatSize = 1 byte.
1504static bool isConstantSplat(const uint64_t Bits128[2],
1505 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001506 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001507 uint64_t &SplatBits, uint64_t &SplatUndef,
1508 int &SplatSize) {
1509 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1510 // the same as the lower 64-bits, ignoring undefs.
1511 uint64_t Bits64 = Bits128[0] | Bits128[1];
1512 uint64_t Undef64 = Undef128[0] & Undef128[1];
1513 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1514 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1515 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1516 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1517
1518 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1519 if (MinSplatBits < 64) {
1520
1521 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1522 // undefs.
1523 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001524 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001525
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001526 // If the top 16-bits are different than the lower 16-bits, ignoring
1527 // undefs, we have an i32 splat.
1528 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1529 if (MinSplatBits < 16) {
1530 // If the top 8-bits are different than the lower 8-bits, ignoring
1531 // undefs, we have an i16 splat.
1532 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1533 // Otherwise, we have an 8-bit splat.
1534 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1535 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1536 SplatSize = 1;
1537 return true;
1538 }
1539 } else {
1540 SplatBits = Bits16;
1541 SplatUndef = Undef16;
1542 SplatSize = 2;
1543 return true;
1544 }
1545 }
1546 } else {
1547 SplatBits = Bits32;
1548 SplatUndef = Undef32;
1549 SplatSize = 4;
1550 return true;
1551 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001552 }
1553 } else {
1554 SplatBits = Bits128[0];
1555 SplatUndef = Undef128[0];
1556 SplatSize = 8;
1557 return true;
1558 }
1559 }
1560
1561 return false; // Can't be a splat if two pieces don't match.
1562}
1563
1564// If this is a case we can't handle, return null and let the default
1565// expansion code take care of it. If we CAN select this case, and if it
1566// selects to a single instruction, return Op. Otherwise, if we can codegen
1567// this case more efficiently than a constant pool load, lower it to the
1568// sequence of ops that should be used.
1569static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1570 MVT::ValueType VT = Op.getValueType();
1571 // If this is a vector of constants or undefs, get the bits. A bit in
1572 // UndefBits is set if the corresponding element of the vector is an
1573 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1574 // zero.
1575 uint64_t VectorBits[2];
1576 uint64_t UndefBits[2];
1577 uint64_t SplatBits, SplatUndef;
1578 int SplatSize;
1579 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1580 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001581 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001582 SplatBits, SplatUndef, SplatSize))
1583 return SDOperand(); // Not a constant vector, not a splat.
1584
1585 switch (VT) {
1586 default:
1587 case MVT::v4f32: {
1588 uint32_t Value32 = SplatBits;
1589 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001590 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001591 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1592 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1593 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001594 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001595 break;
1596 }
1597 case MVT::v2f64: {
1598 uint64_t f64val = SplatBits;
1599 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001600 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001601 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1602 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1603 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001604 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001605 break;
1606 }
1607 case MVT::v16i8: {
1608 // 8-bit constants have to be expanded to 16-bits
1609 unsigned short Value16 = SplatBits | (SplatBits << 8);
1610 SDOperand Ops[8];
1611 for (int i = 0; i < 8; ++i)
1612 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1613 return DAG.getNode(ISD::BIT_CONVERT, VT,
1614 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1615 }
1616 case MVT::v8i16: {
1617 unsigned short Value16;
1618 if (SplatSize == 2)
1619 Value16 = (unsigned short) (SplatBits & 0xffff);
1620 else
1621 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1622 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1623 SDOperand Ops[8];
1624 for (int i = 0; i < 8; ++i) Ops[i] = T;
1625 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1626 }
1627 case MVT::v4i32: {
1628 unsigned int Value = SplatBits;
1629 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1630 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1631 }
1632 case MVT::v2i64: {
1633 uint64_t val = SplatBits;
1634 uint32_t upper = uint32_t(val >> 32);
1635 uint32_t lower = uint32_t(val);
1636
1637 if (val != 0) {
1638 SDOperand LO32;
1639 SDOperand HI32;
1640 SmallVector<SDOperand, 16> ShufBytes;
1641 SDOperand Result;
1642 bool upper_special, lower_special;
1643
1644 // NOTE: This code creates common-case shuffle masks that can be easily
1645 // detected as common expressions. It is not attempting to create highly
1646 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1647
1648 // Detect if the upper or lower half is a special shuffle mask pattern:
1649 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1650 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1651
1652 // Create lower vector if not a special pattern
1653 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001654 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1655 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1656 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1657 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001658 }
1659
1660 // Create upper vector if not a special pattern
1661 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001662 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1663 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1664 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1665 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001666 }
1667
1668 // If either upper or lower are special, then the two input operands are
1669 // the same (basically, one of them is a "don't care")
1670 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001671 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001672 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001673 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001674 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001675 // Unhappy situation... both upper and lower are special, so punt with
1676 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001677 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001678 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001679 Zero, Zero);
1680 }
1681
1682 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001683 for (int j = 0; j < 4; ++j) {
1684 SDOperand V;
1685 bool process_upper, process_lower;
1686 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001687
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001688 process_upper = (upper_special && (i & 1) == 0);
1689 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001690
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001691 if (process_upper || process_lower) {
1692 if ((process_upper && upper == 0)
1693 || (process_lower && lower == 0))
1694 val = 0x80;
1695 else if ((process_upper && upper == 0xffffffff)
1696 || (process_lower && lower == 0xffffffff))
1697 val = 0xc0;
1698 else if ((process_upper && upper == 0x80000000)
1699 || (process_lower && lower == 0x80000000))
1700 val = (j == 0 ? 0xe0 : 0x80);
1701 } else
1702 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001703
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001704 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1705 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001706 }
1707
1708 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001709 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1710 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001711 } else {
1712 // For zero, this can be lowered efficiently via v4i32 BUILD_VECTOR
1713 SDOperand Zero = DAG.getConstant(0, MVT::i32);
1714 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001715 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1716 Zero, Zero, Zero, Zero));
Scott Michel266bc8f2007-12-04 22:23:35 +00001717 }
1718 }
1719 }
1720
1721 return SDOperand();
1722}
1723
1724/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1725/// which the Cell can operate. The code inspects V3 to ascertain whether the
1726/// permutation vector, V3, is monotonically increasing with one "exception"
1727/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1728/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1729/// In either case, the net result is going to eventually invoke SHUFB to
1730/// permute/shuffle the bytes from V1 and V2.
1731/// \note
1732/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1733/// control word for byte/halfword/word insertion. This takes care of a single
1734/// element move from V2 into V1.
1735/// \note
1736/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1737static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1738 SDOperand V1 = Op.getOperand(0);
1739 SDOperand V2 = Op.getOperand(1);
1740 SDOperand PermMask = Op.getOperand(2);
1741
1742 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1743
1744 // If we have a single element being moved from V1 to V2, this can be handled
1745 // using the C*[DX] compute mask instructions, but the vector elements have
1746 // to be monotonically increasing with one exception element.
1747 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1748 unsigned EltsFromV2 = 0;
1749 unsigned V2Elt = 0;
1750 unsigned V2EltIdx0 = 0;
1751 unsigned CurrElt = 0;
1752 bool monotonic = true;
1753 if (EltVT == MVT::i8)
1754 V2EltIdx0 = 16;
1755 else if (EltVT == MVT::i16)
1756 V2EltIdx0 = 8;
1757 else if (EltVT == MVT::i32)
1758 V2EltIdx0 = 4;
1759 else
1760 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1761
1762 for (unsigned i = 0, e = PermMask.getNumOperands();
1763 EltsFromV2 <= 1 && monotonic && i != e;
1764 ++i) {
1765 unsigned SrcElt;
1766 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1767 SrcElt = 0;
1768 else
1769 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1770
1771 if (SrcElt >= V2EltIdx0) {
1772 ++EltsFromV2;
1773 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1774 } else if (CurrElt != SrcElt) {
1775 monotonic = false;
1776 }
1777
1778 ++CurrElt;
1779 }
1780
1781 if (EltsFromV2 == 1 && monotonic) {
1782 // Compute mask and shuffle
1783 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001784 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1785 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001786 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1787 // Initialize temporary register to 0
1788 SDOperand InitTempReg =
1789 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1790 // Copy register's contents as index in INSERT_MASK:
1791 SDOperand ShufMaskOp =
1792 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001793 DAG.getTargetConstant(V2Elt, MVT::i32),
1794 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001795 // Use shuffle mask in SHUFB synthetic instruction:
1796 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1797 } else {
1798 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1799 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1800
1801 SmallVector<SDOperand, 16> ResultMask;
1802 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1803 unsigned SrcElt;
1804 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001805 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001806 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001807 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001808
Scott Michela59d4692008-02-23 18:41:37 +00001809 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001810 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1811 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001812 }
1813 }
1814
1815 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001816 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001817 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1818 }
1819}
1820
1821static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001822 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001823
1824 if (Op0.Val->getOpcode() == ISD::Constant) {
1825 // For a constant, build the appropriate constant vector, which will
1826 // eventually simplify to a vector register load.
1827
1828 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1829 SmallVector<SDOperand, 16> ConstVecValues;
1830 MVT::ValueType VT;
1831 size_t n_copies;
1832
1833 // Create a constant vector:
1834 switch (Op.getValueType()) {
1835 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001836 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001837 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1838 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1839 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1840 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1841 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1842 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1843 }
1844
1845 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1846 for (size_t j = 0; j < n_copies; ++j)
1847 ConstVecValues.push_back(CValue);
1848
1849 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001850 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001851 } else {
1852 // Otherwise, copy the value from one register to another:
1853 switch (Op0.getValueType()) {
1854 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1855 case MVT::i8:
1856 case MVT::i16:
1857 case MVT::i32:
1858 case MVT::i64:
1859 case MVT::f32:
1860 case MVT::f64:
1861 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1862 }
1863 }
1864
1865 return SDOperand();
1866}
1867
1868static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1869 switch (Op.getValueType()) {
1870 case MVT::v4i32: {
1871 SDOperand rA = Op.getOperand(0);
1872 SDOperand rB = Op.getOperand(1);
1873 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1874 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1875 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1876 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1877
1878 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1879 break;
1880 }
1881
1882 // Multiply two v8i16 vectors (pipeline friendly version):
1883 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1884 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1885 // c) Use SELB to select upper and lower halves from the intermediate results
1886 //
1887 // NOTE: We really want to move the FSMBI to earlier to actually get the
1888 // dual-issue. This code does manage to do this, even if it's a little on
1889 // the wacky side
1890 case MVT::v8i16: {
1891 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001892 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001893 SDOperand Chain = Op.getOperand(0);
1894 SDOperand rA = Op.getOperand(0);
1895 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001896 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1897 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001898
1899 SDOperand FSMBOp =
1900 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001901 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1902 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001903
1904 SDOperand HHProd =
1905 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001906 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001907
1908 SDOperand HHProd_v4i32 =
1909 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001910 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001911
1912 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001913 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1914 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1915 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1916 HHProd_v4i32,
1917 DAG.getConstant(16, MVT::i16))),
1918 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001919 }
1920
1921 // This M00sE is N@stI! (apologies to Monty Python)
1922 //
1923 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1924 // is to break it all apart, sign extend, and reassemble the various
1925 // intermediate products.
1926 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001927 SDOperand rA = Op.getOperand(0);
1928 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001929 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1930 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001931
1932 SDOperand LLProd =
1933 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001934 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1935 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001936
1937 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1938
1939 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1940
1941 SDOperand LHProd =
1942 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001943 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001944
Scott Michela59d4692008-02-23 18:41:37 +00001945 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1946 DAG.getConstant(0x2222, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001947
Scott Michela59d4692008-02-23 18:41:37 +00001948 SDOperand LoProdParts =
1949 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1950 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1951 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001952
1953 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1954
1955 SDOperand LoProd =
1956 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001957 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001958 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1959 LoProdMask, LoProdMask,
1960 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001961
1962 SDOperand rAH =
1963 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001964 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001965
1966 SDOperand rBH =
1967 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001968 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001969
1970 SDOperand HLProd =
1971 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001972 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1973 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001974
1975 SDOperand HHProd_1 =
1976 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001977 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1978 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1979 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1980 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001981
1982 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00001983 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1984 HLProd,
1985 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
1986 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00001987
1988 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00001989 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001990
1991 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001992 DAG.getNode(ISD::OR, MVT::v4i32,
1993 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00001994 }
1995
1996 default:
1997 cerr << "CellSPU: Unknown vector multiplication, got "
1998 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001999 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002000 abort();
2001 /*NOTREACHED*/
2002 }
2003
2004 return SDOperand();
2005}
2006
2007static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2008 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002009 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002010
2011 SDOperand A = Op.getOperand(0);
2012 SDOperand B = Op.getOperand(1);
2013 unsigned VT = Op.getValueType();
2014
2015 unsigned VRegBR, VRegC;
2016
2017 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002018 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2019 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002020 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002021 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2022 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002023 }
2024 // TODO: make sure we're feeding FPInterp the right arguments
2025 // Right now: fi B, frest(B)
2026
2027 // Computes BRcpl =
2028 // (Floating Interpolate (FP Reciprocal Estimate B))
2029 SDOperand BRcpl =
2030 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002031 DAG.getNode(SPUISD::FPInterp, VT, B,
2032 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002033
2034 // Computes A * BRcpl and stores in a temporary register
2035 SDOperand AxBRcpl =
2036 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002037 DAG.getNode(ISD::FMUL, VT, A,
2038 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002039 // What's the Chain variable do? It's magic!
2040 // TODO: set Chain = Op(0).getEntryNode()
2041
2042 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002043 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2044 DAG.getNode(ISD::FMUL, VT,
2045 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2046 DAG.getNode(ISD::FSUB, VT, A,
2047 DAG.getNode(ISD::FMUL, VT, B,
2048 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002049}
2050
Scott Michel266bc8f2007-12-04 22:23:35 +00002051static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2052 unsigned VT = Op.getValueType();
2053 SDOperand N = Op.getOperand(0);
2054 SDOperand Elt = Op.getOperand(1);
2055 SDOperand ShufMask[16];
2056 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2057
2058 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2059
2060 int EltNo = (int) C->getValue();
2061
2062 // sanity checks:
2063 if (VT == MVT::i8 && EltNo >= 16)
2064 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2065 else if (VT == MVT::i16 && EltNo >= 8)
2066 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2067 else if (VT == MVT::i32 && EltNo >= 4)
2068 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2069 else if (VT == MVT::i64 && EltNo >= 2)
2070 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2071
2072 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2073 // i32 and i64: Element 0 is the preferred slot
2074 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2075 }
2076
2077 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002078 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002079 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2080
2081 switch (VT) {
2082 case MVT::i8: {
2083 prefslot_begin = prefslot_end = 3;
2084 break;
2085 }
2086 case MVT::i16: {
2087 prefslot_begin = 2; prefslot_end = 3;
2088 break;
2089 }
2090 case MVT::i32: {
2091 prefslot_begin = 0; prefslot_end = 3;
2092 break;
2093 }
2094 case MVT::i64: {
2095 prefslot_begin = 0; prefslot_end = 7;
2096 break;
2097 }
2098 }
2099
Scott Michel0e5665b2007-12-19 21:17:42 +00002100 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002101 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002102
Scott Michel266bc8f2007-12-04 22:23:35 +00002103 for (int i = 0; i < 16; ++i) {
2104 // zero fill uppper part of preferred slot, don't care about the
2105 // other slots:
2106 unsigned int mask_val;
2107
2108 if (i <= prefslot_end) {
2109 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002110 ((i < prefslot_begin)
2111 ? 0x80
2112 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002113
Scott Michel0e5665b2007-12-19 21:17:42 +00002114 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002115 } else
2116 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2117 }
2118
2119 SDOperand ShufMaskVec =
2120 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002121 &ShufMask[0],
2122 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002123
2124 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002125 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2126 N, N, ShufMaskVec));
2127
Scott Michel266bc8f2007-12-04 22:23:35 +00002128}
2129
2130static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2131 SDOperand VecOp = Op.getOperand(0);
2132 SDOperand ValOp = Op.getOperand(1);
2133 SDOperand IdxOp = Op.getOperand(2);
2134 MVT::ValueType VT = Op.getValueType();
2135
2136 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2137 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2138
2139 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2140 // Use $2 because it's always 16-byte aligned and it's available:
2141 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2142
2143 SDOperand result =
2144 DAG.getNode(SPUISD::SHUFB, VT,
2145 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2146 VecOp,
2147 DAG.getNode(SPUISD::INSERT_MASK, VT,
2148 DAG.getNode(ISD::ADD, PtrVT,
2149 PtrBase,
2150 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002151 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002152
2153 return result;
2154}
2155
Scott Michela59d4692008-02-23 18:41:37 +00002156static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2157{
Scott Michel266bc8f2007-12-04 22:23:35 +00002158 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2159
2160 assert(Op.getValueType() == MVT::i8);
2161 switch (Opc) {
2162 default:
2163 assert(0 && "Unhandled i8 math operator");
2164 /*NOTREACHED*/
2165 break;
2166 case ISD::SUB: {
2167 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2168 // the result:
2169 SDOperand N1 = Op.getOperand(1);
2170 N0 = (N0.getOpcode() != ISD::Constant
2171 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2172 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2173 N1 = (N1.getOpcode() != ISD::Constant
2174 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2175 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2176 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2177 DAG.getNode(Opc, MVT::i16, N0, N1));
2178 }
2179 case ISD::ROTR:
2180 case ISD::ROTL: {
2181 SDOperand N1 = Op.getOperand(1);
2182 unsigned N1Opc;
2183 N0 = (N0.getOpcode() != ISD::Constant
2184 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2185 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2186 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2187 N1 = (N1.getOpcode() != ISD::Constant
2188 ? DAG.getNode(N1Opc, MVT::i16, N1)
2189 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2190 SDOperand ExpandArg =
2191 DAG.getNode(ISD::OR, MVT::i16, N0,
2192 DAG.getNode(ISD::SHL, MVT::i16,
2193 N0, DAG.getConstant(8, MVT::i16)));
2194 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2195 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2196 }
2197 case ISD::SRL:
2198 case ISD::SHL: {
2199 SDOperand N1 = Op.getOperand(1);
2200 unsigned N1Opc;
2201 N0 = (N0.getOpcode() != ISD::Constant
2202 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2203 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2204 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2205 N1 = (N1.getOpcode() != ISD::Constant
2206 ? DAG.getNode(N1Opc, MVT::i16, N1)
2207 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2208 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2209 DAG.getNode(Opc, MVT::i16, N0, N1));
2210 }
2211 case ISD::SRA: {
2212 SDOperand N1 = Op.getOperand(1);
2213 unsigned N1Opc;
2214 N0 = (N0.getOpcode() != ISD::Constant
2215 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2216 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2217 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_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::MUL: {
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 break;
2237 }
2238 }
2239
2240 return SDOperand();
2241}
2242
Scott Michela59d4692008-02-23 18:41:37 +00002243static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2244{
2245 MVT::ValueType VT = Op.getValueType();
2246 unsigned VecVT =
2247 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2248
2249 SDOperand Op0 = Op.getOperand(0);
2250
2251 switch (Opc) {
2252 case ISD::ZERO_EXTEND:
2253 case ISD::SIGN_EXTEND:
2254 case ISD::ANY_EXTEND: {
2255 MVT::ValueType Op0VT = Op0.getValueType();
2256 unsigned Op0VecVT =
2257 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2258
2259 assert(Op0VT == MVT::i32
2260 && "CellSPU: Zero/sign extending something other than i32");
2261
2262 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2263 ? SPUISD::ROTBYTES_RIGHT_S
2264 : SPUISD::ROTQUAD_RZ_BYTES);
2265 SDOperand PromoteScalar =
2266 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2267
2268 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2269 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2270 DAG.getNode(NewOpc, Op0VecVT,
2271 PromoteScalar,
2272 DAG.getConstant(4, MVT::i32))));
2273 }
2274
2275 case ISD::SHL: {
2276 SDOperand ShiftAmt = Op.getOperand(1);
2277 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2278 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2279 SDOperand MaskLower =
2280 DAG.getNode(SPUISD::SELB, VecVT,
2281 Op0Vec,
2282 DAG.getConstant(0, VecVT),
2283 DAG.getNode(SPUISD::FSMBI, VecVT,
2284 DAG.getConstant(0xff00ULL, MVT::i16)));
2285 SDOperand ShiftAmtBytes =
2286 DAG.getNode(ISD::SRL, ShiftAmtVT,
2287 ShiftAmt,
2288 DAG.getConstant(3, ShiftAmtVT));
2289 SDOperand ShiftAmtBits =
2290 DAG.getNode(ISD::AND, ShiftAmtVT,
2291 ShiftAmt,
2292 DAG.getConstant(7, ShiftAmtVT));
2293
2294 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2295 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2296 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2297 MaskLower, ShiftAmtBytes),
2298 ShiftAmtBits));
2299 }
2300
2301 case ISD::SRL: {
2302 unsigned VT = unsigned(Op.getValueType());
2303 SDOperand ShiftAmt = Op.getOperand(1);
2304 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2305 SDOperand ShiftAmtBytes =
2306 DAG.getNode(ISD::SRL, ShiftAmtVT,
2307 ShiftAmt,
2308 DAG.getConstant(3, ShiftAmtVT));
2309 SDOperand ShiftAmtBits =
2310 DAG.getNode(ISD::AND, ShiftAmtVT,
2311 ShiftAmt,
2312 DAG.getConstant(7, ShiftAmtVT));
2313
2314 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2315 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2316 Op0, ShiftAmtBytes),
2317 ShiftAmtBits);
2318 }
2319 }
2320
2321 return SDOperand();
2322}
2323
Scott Michel266bc8f2007-12-04 22:23:35 +00002324//! Lower byte immediate operations for v16i8 vectors:
2325static SDOperand
2326LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2327 SDOperand ConstVec;
2328 SDOperand Arg;
2329 MVT::ValueType VT = Op.getValueType();
2330
2331 ConstVec = Op.getOperand(0);
2332 Arg = Op.getOperand(1);
2333 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2334 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2335 ConstVec = ConstVec.getOperand(0);
2336 } else {
2337 ConstVec = Op.getOperand(1);
2338 Arg = Op.getOperand(0);
2339 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002340 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002341 }
2342 }
2343 }
2344
2345 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2346 uint64_t VectorBits[2];
2347 uint64_t UndefBits[2];
2348 uint64_t SplatBits, SplatUndef;
2349 int SplatSize;
2350
2351 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002352 && isConstantSplat(VectorBits, UndefBits,
2353 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2354 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002355 SDOperand tcVec[16];
2356 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2357 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2358
2359 // Turn the BUILD_VECTOR into a set of target constants:
2360 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002361 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002362
2363 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002364 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002365 }
2366 }
2367
2368 return SDOperand();
2369}
2370
2371//! Lower i32 multiplication
2372static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2373 unsigned Opc) {
2374 switch (VT) {
2375 default:
2376 cerr << "CellSPU: Unknown LowerMUL value type, got "
2377 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002378 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002379 abort();
2380 /*NOTREACHED*/
2381
2382 case MVT::i32: {
2383 SDOperand rA = Op.getOperand(0);
2384 SDOperand rB = Op.getOperand(1);
2385
2386 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002387 DAG.getNode(ISD::ADD, MVT::i32,
2388 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2389 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2390 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002391 }
2392 }
2393
2394 return SDOperand();
2395}
2396
2397//! Custom lowering for CTPOP (count population)
2398/*!
2399 Custom lowering code that counts the number ones in the input
2400 operand. SPU has such an instruction, but it counts the number of
2401 ones per byte, which then have to be accumulated.
2402*/
2403static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2404 unsigned VT = Op.getValueType();
2405 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2406
2407 switch (VT) {
2408 case MVT::i8: {
2409 SDOperand N = Op.getOperand(0);
2410 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2411
2412 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2413 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2414
2415 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2416 }
2417
2418 case MVT::i16: {
2419 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002420 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002421
Chris Lattner84bc5422007-12-31 04:13:23 +00002422 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002423
2424 SDOperand N = Op.getOperand(0);
2425 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2426 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2427 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2428
2429 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2430 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2431
2432 // CNTB_result becomes the chain to which all of the virtual registers
2433 // CNTB_reg, SUM1_reg become associated:
2434 SDOperand CNTB_result =
2435 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002436
Scott Michel266bc8f2007-12-04 22:23:35 +00002437 SDOperand CNTB_rescopy =
2438 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2439
2440 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2441
2442 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002443 DAG.getNode(ISD::ADD, MVT::i16,
2444 DAG.getNode(ISD::SRL, MVT::i16,
2445 Tmp1, Shift1),
2446 Tmp1),
2447 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002448 }
2449
2450 case MVT::i32: {
2451 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002452 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002453
Chris Lattner84bc5422007-12-31 04:13:23 +00002454 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2455 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002456
2457 SDOperand N = Op.getOperand(0);
2458 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2459 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2460 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2461 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2462
2463 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2464 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2465
2466 // CNTB_result becomes the chain to which all of the virtual registers
2467 // CNTB_reg, SUM1_reg become associated:
2468 SDOperand CNTB_result =
2469 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002470
Scott Michel266bc8f2007-12-04 22:23:35 +00002471 SDOperand CNTB_rescopy =
2472 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2473
2474 SDOperand Comp1 =
2475 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002476 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002477
2478 SDOperand Sum1 =
2479 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002480 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002481
2482 SDOperand Sum1_rescopy =
2483 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2484
2485 SDOperand Comp2 =
2486 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002487 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2488 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002489 SDOperand Sum2 =
2490 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002491 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002492
2493 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2494 }
2495
2496 case MVT::i64:
2497 break;
2498 }
2499
2500 return SDOperand();
2501}
2502
2503/// LowerOperation - Provide custom lowering hooks for some operations.
2504///
2505SDOperand
2506SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2507{
Scott Michela59d4692008-02-23 18:41:37 +00002508 unsigned Opc = (unsigned) Op.getOpcode();
2509 unsigned VT = (unsigned) Op.getValueType();
2510
2511 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002512 default: {
2513 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002514 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002515 cerr << "*Op.Val:\n";
2516 Op.Val->dump();
2517 abort();
2518 }
2519 case ISD::LOAD:
2520 case ISD::SEXTLOAD:
2521 case ISD::ZEXTLOAD:
2522 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2523 case ISD::STORE:
2524 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2525 case ISD::ConstantPool:
2526 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2527 case ISD::GlobalAddress:
2528 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2529 case ISD::JumpTable:
2530 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2531 case ISD::Constant:
2532 return LowerConstant(Op, DAG);
2533 case ISD::ConstantFP:
2534 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002535 case ISD::BRCOND:
2536 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002537 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002538 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002539 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002540 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002541 case ISD::RET:
2542 return LowerRET(Op, DAG, getTargetMachine());
2543
Scott Michela59d4692008-02-23 18:41:37 +00002544
2545 // i8, i64 math ops:
2546 case ISD::ZERO_EXTEND:
2547 case ISD::SIGN_EXTEND:
2548 case ISD::ANY_EXTEND:
Scott Michel266bc8f2007-12-04 22:23:35 +00002549 case ISD::SUB:
2550 case ISD::ROTR:
2551 case ISD::ROTL:
2552 case ISD::SRL:
2553 case ISD::SHL:
2554 case ISD::SRA:
Scott Michela59d4692008-02-23 18:41:37 +00002555 if (VT == MVT::i8)
2556 return LowerI8Math(Op, DAG, Opc);
2557 else if (VT == MVT::i64)
2558 return LowerI64Math(Op, DAG, Opc);
2559 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00002560
2561 // Vector-related lowering.
2562 case ISD::BUILD_VECTOR:
2563 return LowerBUILD_VECTOR(Op, DAG);
2564 case ISD::SCALAR_TO_VECTOR:
2565 return LowerSCALAR_TO_VECTOR(Op, DAG);
2566 case ISD::VECTOR_SHUFFLE:
2567 return LowerVECTOR_SHUFFLE(Op, DAG);
2568 case ISD::EXTRACT_VECTOR_ELT:
2569 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2570 case ISD::INSERT_VECTOR_ELT:
2571 return LowerINSERT_VECTOR_ELT(Op, DAG);
2572
2573 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2574 case ISD::AND:
2575 case ISD::OR:
2576 case ISD::XOR:
2577 return LowerByteImmed(Op, DAG);
2578
2579 // Vector and i8 multiply:
2580 case ISD::MUL:
Scott Michela59d4692008-02-23 18:41:37 +00002581 if (MVT::isVector(VT))
Scott Michel266bc8f2007-12-04 22:23:35 +00002582 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002583 else if (VT == MVT::i8)
2584 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002585 else
Scott Michela59d4692008-02-23 18:41:37 +00002586 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002587
2588 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002589 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002590 return LowerFDIVf32(Op, DAG);
2591// else if (Op.getValueType() == MVT::f64)
2592// return LowerFDIVf64(Op, DAG);
2593 else
2594 assert(0 && "Calling FDIV on unsupported MVT");
2595
2596 case ISD::CTPOP:
2597 return LowerCTPOP(Op, DAG);
2598 }
2599
2600 return SDOperand();
2601}
2602
2603//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002604// Target Optimization Hooks
2605//===----------------------------------------------------------------------===//
2606
2607SDOperand
2608SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2609{
2610#if 0
2611 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002612#endif
2613 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002614 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002615 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2616 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002617
2618 switch (N->getOpcode()) {
2619 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002620 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002621 SDOperand Op1 = N->getOperand(1);
2622
2623 if ((Op1.getOpcode() == ISD::Constant
2624 || Op1.getOpcode() == ISD::TargetConstant)
2625 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2626 SDOperand Op01 = Op0.getOperand(1);
2627 if (Op01.getOpcode() == ISD::Constant
2628 || Op01.getOpcode() == ISD::TargetConstant) {
2629 // (add <const>, (SPUindirect <arg>, <const>)) ->
2630 // (SPUindirect <arg>, <const + const>)
2631 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2632 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2633 SDOperand combinedConst =
2634 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2635 Op0.getValueType());
2636
2637 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2638 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2639 DEBUG(cerr << "With: (SPUindirect <arg>, "
2640 << CN0->getValue() + CN1->getValue() << ")\n");
2641 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2642 Op0.getOperand(0), combinedConst);
2643 }
2644 } else if ((Op0.getOpcode() == ISD::Constant
2645 || Op0.getOpcode() == ISD::TargetConstant)
2646 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2647 SDOperand Op11 = Op1.getOperand(1);
2648 if (Op11.getOpcode() == ISD::Constant
2649 || Op11.getOpcode() == ISD::TargetConstant) {
2650 // (add (SPUindirect <arg>, <const>), <const>) ->
2651 // (SPUindirect <arg>, <const + const>)
2652 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2653 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2654 SDOperand combinedConst =
2655 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2656 Op0.getValueType());
2657
2658 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2659 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2660 DEBUG(cerr << "With: (SPUindirect <arg>, "
2661 << CN0->getValue() + CN1->getValue() << ")\n");
2662
2663 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2664 Op1.getOperand(0), combinedConst);
2665 }
2666 }
Scott Michela59d4692008-02-23 18:41:37 +00002667 break;
2668 }
2669 case ISD::SIGN_EXTEND:
2670 case ISD::ZERO_EXTEND:
2671 case ISD::ANY_EXTEND: {
2672 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2673 N->getValueType(0) == Op0.getValueType()) {
2674 // (any_extend (SPUextract_elt0 <arg>)) ->
2675 // (SPUextract_elt0 <arg>)
2676 // Types must match, however...
2677 DEBUG(cerr << "Replace: ");
2678 DEBUG(N->dump(&DAG));
2679 DEBUG(cerr << "\nWith: ");
2680 DEBUG(Op0.Val->dump(&DAG));
2681 DEBUG(cerr << "\n");
2682
2683 return Op0;
2684 }
2685 break;
2686 }
2687 case SPUISD::IndirectAddr: {
2688 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2689 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2690 if (CN->getValue() == 0) {
2691 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2692 // (SPUaform <addr>, 0)
2693
2694 DEBUG(cerr << "Replace: ");
2695 DEBUG(N->dump(&DAG));
2696 DEBUG(cerr << "\nWith: ");
2697 DEBUG(Op0.Val->dump(&DAG));
2698 DEBUG(cerr << "\n");
2699
2700 return Op0;
2701 }
2702 }
2703 break;
2704 }
2705 case SPUISD::SHLQUAD_L_BITS:
2706 case SPUISD::SHLQUAD_L_BYTES:
2707 case SPUISD::VEC_SHL:
2708 case SPUISD::VEC_SRL:
2709 case SPUISD::VEC_SRA:
2710 case SPUISD::ROTQUAD_RZ_BYTES:
2711 case SPUISD::ROTQUAD_RZ_BITS: {
2712 SDOperand Op1 = N->getOperand(1);
2713
2714 if (isa<ConstantSDNode>(Op1)) {
2715 // Kill degenerate vector shifts:
2716 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2717
2718 if (CN->getValue() == 0) {
2719 Result = Op0;
2720 }
2721 }
2722 break;
2723 }
2724 case SPUISD::PROMOTE_SCALAR: {
2725 switch (Op0.getOpcode()) {
2726 default:
2727 break;
2728 case ISD::ANY_EXTEND:
2729 case ISD::ZERO_EXTEND:
2730 case ISD::SIGN_EXTEND: {
2731 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2732 // <arg>
2733 // but only if the SPUpromote_scalar and <arg> types match.
2734 SDOperand Op00 = Op0.getOperand(0);
2735 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2736 SDOperand Op000 = Op00.getOperand(0);
2737 if (Op000.getValueType() == N->getValueType(0)) {
2738 Result = Op000;
2739 }
2740 }
2741 break;
2742 }
2743 case SPUISD::EXTRACT_ELT0: {
2744 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2745 // <arg>
2746 Result = Op0.getOperand(0);
2747 break;
2748 }
2749 }
2750 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002751 }
2752 }
Scott Michel58c58182008-01-17 20:38:41 +00002753 // Otherwise, return unchanged.
Scott Michela59d4692008-02-23 18:41:37 +00002754#if 0
2755 if (Result.Val) {
2756 DEBUG(cerr << "\nReplace.SPU: ");
2757 DEBUG(N->dump(&DAG));
2758 DEBUG(cerr << "\nWith: ");
2759 DEBUG(Result.Val->dump(&DAG));
2760 DEBUG(cerr << "\n");
2761 }
2762#endif
2763
2764 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002765}
2766
2767//===----------------------------------------------------------------------===//
2768// Inline Assembly Support
2769//===----------------------------------------------------------------------===//
2770
2771/// getConstraintType - Given a constraint letter, return the type of
2772/// constraint it is for this target.
2773SPUTargetLowering::ConstraintType
2774SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2775 if (ConstraintLetter.size() == 1) {
2776 switch (ConstraintLetter[0]) {
2777 default: break;
2778 case 'b':
2779 case 'r':
2780 case 'f':
2781 case 'v':
2782 case 'y':
2783 return C_RegisterClass;
2784 }
2785 }
2786 return TargetLowering::getConstraintType(ConstraintLetter);
2787}
2788
2789std::pair<unsigned, const TargetRegisterClass*>
2790SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2791 MVT::ValueType VT) const
2792{
2793 if (Constraint.size() == 1) {
2794 // GCC RS6000 Constraint Letters
2795 switch (Constraint[0]) {
2796 case 'b': // R1-R31
2797 case 'r': // R0-R31
2798 if (VT == MVT::i64)
2799 return std::make_pair(0U, SPU::R64CRegisterClass);
2800 return std::make_pair(0U, SPU::R32CRegisterClass);
2801 case 'f':
2802 if (VT == MVT::f32)
2803 return std::make_pair(0U, SPU::R32FPRegisterClass);
2804 else if (VT == MVT::f64)
2805 return std::make_pair(0U, SPU::R64FPRegisterClass);
2806 break;
2807 case 'v':
2808 return std::make_pair(0U, SPU::GPRCRegisterClass);
2809 }
2810 }
2811
2812 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2813}
2814
Scott Michela59d4692008-02-23 18:41:37 +00002815//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002816void
2817SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002818 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002819 APInt &KnownZero,
2820 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002821 const SelectionDAG &DAG,
2822 unsigned Depth ) const {
Scott Michela59d4692008-02-23 18:41:37 +00002823 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2824
2825 switch (Op.getOpcode()) {
2826 default:
2827 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2828 break;
2829
2830#if 0
2831 case CALL:
2832 case SHUFB:
2833 case INSERT_MASK:
2834 case CNTB:
2835#endif
2836
2837 case SPUISD::PROMOTE_SCALAR: {
2838 SDOperand Op0 = Op.getOperand(0);
2839 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2840 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2841 KnownOne |= APInt(uint64_sizebits, InMask, false);
2842 break;
2843 }
2844
2845 case SPUISD::LDRESULT:
2846 case SPUISD::EXTRACT_ELT0:
2847 case SPUISD::EXTRACT_ELT0_CHAINED: {
2848 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2849 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2850 KnownOne |= APInt(uint64_sizebits, InMask, false);
2851 break;
2852 }
2853
2854#if 0
2855 case EXTRACT_I1_ZEXT:
2856 case EXTRACT_I1_SEXT:
2857 case EXTRACT_I8_ZEXT:
2858 case EXTRACT_I8_SEXT:
2859 case MPY:
2860 case MPYU:
2861 case MPYH:
2862 case MPYHH:
2863 case SHLQUAD_L_BITS:
2864 case SHLQUAD_L_BYTES:
2865 case VEC_SHL:
2866 case VEC_SRL:
2867 case VEC_SRA:
2868 case VEC_ROTL:
2869 case VEC_ROTR:
2870 case ROTQUAD_RZ_BYTES:
2871 case ROTQUAD_RZ_BITS:
2872 case ROTBYTES_RIGHT_S:
2873 case ROTBYTES_LEFT:
2874 case ROTBYTES_LEFT_CHAINED:
2875 case FSMBI:
2876 case SELB:
2877 case SFPConstant:
2878 case FPInterp:
2879 case FPRecipEst:
2880 case SEXT32TO64:
2881#endif
2882 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002883}
2884
2885// LowerAsmOperandForConstraint
2886void
2887SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2888 char ConstraintLetter,
2889 std::vector<SDOperand> &Ops,
2890 SelectionDAG &DAG) {
2891 // Default, for the time being, to the base class handler
2892 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2893}
2894
2895/// isLegalAddressImmediate - Return true if the integer value can be used
2896/// as the offset of the target addressing mode.
2897bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2898 // SPU's addresses are 256K:
2899 return (V > -(1 << 18) && V < (1 << 18) - 1);
2900}
2901
2902bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2903 return false;
2904}