blob: de1fff0ccaed095162a800fb04b3ea194a397951 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
17#include "llvm/ADT/VectorExtras.h"
18#include "llvm/Analysis/ScalarEvolutionExpressions.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000023#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000024#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/Constants.h"
26#include "llvm/Function.h"
27#include "llvm/Intrinsics.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Target/TargetOptions.h"
31
32#include <map>
33
34using namespace llvm;
35
36// Used in getTargetNodeName() below
37namespace {
38 std::map<unsigned, const char *> node_names;
39
40 //! MVT::ValueType mapping to useful data for Cell SPU
41 struct valtype_map_s {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000042 const MVT::ValueType valtype;
43 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000044 };
45
46 const valtype_map_s valtype_map[] = {
47 { MVT::i1, 3 },
48 { MVT::i8, 3 },
49 { MVT::i16, 2 },
50 { MVT::i32, 0 },
51 { MVT::f32, 0 },
52 { MVT::i64, 0 },
53 { MVT::f64, 0 },
54 { MVT::i128, 0 }
55 };
56
57 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
58
59 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) {
60 const valtype_map_s *retval = 0;
61
62 for (size_t i = 0; i < n_valtype_map; ++i) {
63 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000064 retval = valtype_map + i;
65 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000066 }
67 }
68
69#ifndef NDEBUG
70 if (retval == 0) {
71 cerr << "getValueTypeMapEntry returns NULL for "
Scott Michel7f9ba9b2008-01-30 02:55:46 +000072 << MVT::getValueTypeString(VT)
73 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000074 abort();
75 }
76#endif
77
78 return retval;
79 }
80
81 //! Predicate that returns true if operand is a memory target
82 /*!
83 \arg Op Operand to test
84 \return true if the operand is a memory target (i.e., global
Scott Michel9de5d0d2008-01-11 02:53:15 +000085 address, external symbol, constant pool) or an A-form
Scott Michel266bc8f2007-12-04 22:23:35 +000086 address.
87 */
88 bool isMemoryOperand(const SDOperand &Op)
89 {
90 const unsigned Opc = Op.getOpcode();
91 return (Opc == ISD::GlobalAddress
92 || Opc == ISD::GlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000093 || Opc == ISD::JumpTable
94 || Opc == ISD::ConstantPool
95 || Opc == ISD::ExternalSymbol
96 || Opc == ISD::TargetGlobalAddress
97 || Opc == ISD::TargetGlobalTLSAddress
Scott Michel266bc8f2007-12-04 22:23:35 +000098 || Opc == ISD::TargetJumpTable
99 || Opc == ISD::TargetConstantPool
100 || Opc == ISD::TargetExternalSymbol
Scott Michel9de5d0d2008-01-11 02:53:15 +0000101 || Opc == SPUISD::AFormAddr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000102 }
Scott Michel58c58182008-01-17 20:38:41 +0000103
104 //! Predicate that returns true if the operand is an indirect target
105 bool isIndirectOperand(const SDOperand &Op)
106 {
107 const unsigned Opc = Op.getOpcode();
108 return (Opc == ISD::Register
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000109 || Opc == SPUISD::LDRESULT);
Scott Michel58c58182008-01-17 20:38:41 +0000110 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000111}
112
113SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
114 : TargetLowering(TM),
115 SPUTM(TM)
116{
117 // Fold away setcc operations if possible.
118 setPow2DivIsCheap();
119
120 // Use _setjmp/_longjmp instead of setjmp/longjmp.
121 setUseUnderscoreSetJmp(true);
122 setUseUnderscoreLongJmp(true);
123
124 // Set up the SPU's register classes:
125 // NOTE: i8 register class is not registered because we cannot determine when
126 // we need to zero or sign extend for custom-lowered loads and stores.
Scott Michel504c3692007-12-17 22:32:34 +0000127 // NOTE: Ignore the previous note. For now. :-)
128 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
129 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
130 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
131 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
132 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
133 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000134 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
135
136 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000137 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000138 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
139 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000140 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
142 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
143 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
144 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000145
146 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
147 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
148 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000149 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
151 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
152 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
153 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
154
Scott Michel266bc8f2007-12-04 22:23:35 +0000155 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
156 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
157 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
158
159 // SPU constant load actions are custom lowered:
160 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000161 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000162 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
163
164 // SPU's loads and stores have to be custom lowered:
165 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
166 ++sctype) {
167 setOperationAction(ISD::LOAD, sctype, Custom);
168 setOperationAction(ISD::STORE, sctype, Custom);
169 }
170
Scott Michel58c58182008-01-17 20:38:41 +0000171 // Custom lower BRCOND for i1, i8 to "promote" the result to
172 // i32 and i16, respectively.
173 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000174
175 // Expand the jumptable branches
176 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
177 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
178 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
179
180 // SPU has no intrinsics for these particular operations:
181 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
182 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
183 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000184 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
185
Scott Michel266bc8f2007-12-04 22:23:35 +0000186 // PowerPC has no SREM/UREM instructions
187 setOperationAction(ISD::SREM, MVT::i32, Expand);
188 setOperationAction(ISD::UREM, MVT::i32, Expand);
189 setOperationAction(ISD::SREM, MVT::i64, Expand);
190 setOperationAction(ISD::UREM, MVT::i64, Expand);
191
192 // We don't support sin/cos/sqrt/fmod
193 setOperationAction(ISD::FSIN , MVT::f64, Expand);
194 setOperationAction(ISD::FCOS , MVT::f64, Expand);
195 setOperationAction(ISD::FREM , MVT::f64, Expand);
196 setOperationAction(ISD::FSIN , MVT::f32, Expand);
197 setOperationAction(ISD::FCOS , MVT::f32, Expand);
198 setOperationAction(ISD::FREM , MVT::f32, Expand);
199
200 // If we're enabling GP optimizations, use hardware square root
201 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
202 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
203
204 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
205 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
206
207 // SPU can do rotate right and left, so legalize it... but customize for i8
208 // because instructions don't exist.
209 setOperationAction(ISD::ROTR, MVT::i32, Legal);
210 setOperationAction(ISD::ROTR, MVT::i16, Legal);
211 setOperationAction(ISD::ROTR, MVT::i8, Custom);
212 setOperationAction(ISD::ROTL, MVT::i32, Legal);
213 setOperationAction(ISD::ROTL, MVT::i16, Legal);
214 setOperationAction(ISD::ROTL, MVT::i8, Custom);
215 // SPU has no native version of shift left/right for i8
216 setOperationAction(ISD::SHL, MVT::i8, Custom);
217 setOperationAction(ISD::SRL, MVT::i8, Custom);
218 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000219 // And SPU needs custom lowering for shift left/right for i64
220 setOperationAction(ISD::SHL, MVT::i64, Custom);
221 setOperationAction(ISD::SRL, MVT::i64, Custom);
222 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000223
224 // Custom lower i32 multiplications
225 setOperationAction(ISD::MUL, MVT::i32, Custom);
226
227 // Need to custom handle (some) common i8 math ops
228 setOperationAction(ISD::SUB, MVT::i8, Custom);
229 setOperationAction(ISD::MUL, MVT::i8, Custom);
230
231 // SPU does not have BSWAP. It does have i32 support CTLZ.
232 // CTPOP has to be custom lowered.
233 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
234 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
235
236 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
237 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
238 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
239 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
240
241 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
242 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
243
244 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
245
Scott Michelad2715e2008-03-05 23:02:02 +0000246 // SPU has a version of select
Scott Michel266bc8f2007-12-04 22:23:35 +0000247 setOperationAction(ISD::SELECT, MVT::i1, Expand);
248 setOperationAction(ISD::SELECT, MVT::i8, Expand);
Scott Michelad2715e2008-03-05 23:02:02 +0000249 setOperationAction(ISD::SELECT, MVT::i16, Legal);
250 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000251 setOperationAction(ISD::SELECT, MVT::i64, Expand);
252 setOperationAction(ISD::SELECT, MVT::f32, Expand);
253 setOperationAction(ISD::SELECT, MVT::f64, Expand);
254
Scott Michelad2715e2008-03-05 23:02:02 +0000255 setOperationAction(ISD::SETCC, MVT::i1, Expand);
256 setOperationAction(ISD::SETCC, MVT::i8, Expand);
257 setOperationAction(ISD::SETCC, MVT::i16, Legal);
258 setOperationAction(ISD::SETCC, MVT::i32, Legal);
259 setOperationAction(ISD::SETCC, MVT::i64, Expand);
260 setOperationAction(ISD::SETCC, MVT::f32, Expand);
261 setOperationAction(ISD::SETCC, MVT::f64, Expand);
262
Scott Michela59d4692008-02-23 18:41:37 +0000263 // Zero extension and sign extension for i64 have to be
264 // custom legalized
265 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
266 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
267 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000268
269 // SPU has a legal FP -> signed INT instruction
270 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
271 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
272 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
273 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
274
275 // FDIV on SPU requires custom lowering
276 setOperationAction(ISD::FDIV, MVT::f32, Custom);
277 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
278
279 // SPU has [U|S]INT_TO_FP
280 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
281 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
282 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
283 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
284 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
285 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
286 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
287 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
288
Scott Michel86c041f2007-12-20 00:44:13 +0000289 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
290 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
291 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
292 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000293
294 // We cannot sextinreg(i1). Expand to shifts.
295 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
296
297 // Support label based line numbers.
298 setOperationAction(ISD::LOCATION, MVT::Other, Expand);
299 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
300
301 // We want to legalize GlobalAddress and ConstantPool nodes into the
302 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000303 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
304 ++sctype) {
305 setOperationAction(ISD::GlobalAddress, sctype, Custom);
306 setOperationAction(ISD::ConstantPool, sctype, Custom);
307 setOperationAction(ISD::JumpTable, sctype, Custom);
308 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000309
310 // RET must be custom lowered, to meet ABI requirements
311 setOperationAction(ISD::RET, MVT::Other, Custom);
312
313 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
314 setOperationAction(ISD::VASTART , MVT::Other, Custom);
315
316 // Use the default implementation.
317 setOperationAction(ISD::VAARG , MVT::Other, Expand);
318 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
319 setOperationAction(ISD::VAEND , MVT::Other, Expand);
320 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
321 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
322 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
323 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
324
325 // Cell SPU has instructions for converting between i64 and fp.
326 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
327 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
328
329 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
330 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
331
332 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
333 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
334
335 // First set operation action for all vector types to expand. Then we
336 // will selectively turn on ones that can be effectively codegen'd.
337 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
338 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
339 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
340 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
341 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
342 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
343
344 for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
345 VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
346 // add/sub are legal for all supported vector VT's.
347 setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
348 setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
349 // mul has to be custom lowered.
350 setOperationAction(ISD::MUL , (MVT::ValueType)VT, Custom);
351
352 setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal);
353 setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal);
354 setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal);
355 setOperationAction(ISD::LOAD , (MVT::ValueType)VT, Legal);
356 setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Legal);
357 setOperationAction(ISD::STORE, (MVT::ValueType)VT, Legal);
358
359 // These operations need to be expanded:
360 setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
361 setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
362 setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
363 setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
364 setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Custom);
365
366 // Custom lower build_vector, constant pool spills, insert and
367 // extract vector elements:
368 setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Custom);
369 setOperationAction(ISD::ConstantPool, (MVT::ValueType)VT, Custom);
370 setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Custom);
371 setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
372 setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Custom);
373 setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Custom);
374 }
375
376 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
377 setOperationAction(ISD::AND, MVT::v16i8, Custom);
378 setOperationAction(ISD::OR, MVT::v16i8, Custom);
379 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
380 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000381
Scott Michel266bc8f2007-12-04 22:23:35 +0000382 setSetCCResultType(MVT::i32);
383 setShiftAmountType(MVT::i32);
384 setSetCCResultContents(ZeroOrOneSetCCResult);
385
386 setStackPointerRegisterToSaveRestore(SPU::R1);
387
388 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000389 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000390 setTargetDAGCombine(ISD::ZERO_EXTEND);
391 setTargetDAGCombine(ISD::SIGN_EXTEND);
392 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel266bc8f2007-12-04 22:23:35 +0000393
394 computeRegisterProperties();
395}
396
397const char *
398SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
399{
400 if (node_names.empty()) {
401 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
402 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
403 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
404 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000405 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000406 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000407 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
408 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
409 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
410 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
411 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
412 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
413 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
414 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
415 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
416 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
417 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
418 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
419 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
420 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
421 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
422 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michela59d4692008-02-23 18:41:37 +0000423 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
424 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000425 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
426 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
427 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
428 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
429 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michela59d4692008-02-23 18:41:37 +0000430 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
431 "SPUISD::ROTQUAD_RZ_BYTES";
432 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
433 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel266bc8f2007-12-04 22:23:35 +0000434 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
435 "SPUISD::ROTBYTES_RIGHT_S";
436 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
437 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
438 "SPUISD::ROTBYTES_LEFT_CHAINED";
439 node_names[(unsigned) SPUISD::FSMBI] = "SPUISD::FSMBI";
440 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel266bc8f2007-12-04 22:23:35 +0000441 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
442 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
443 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
444 }
445
446 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
447
448 return ((i != node_names.end()) ? i->second : 0);
449}
450
451//===----------------------------------------------------------------------===//
452// Calling convention code:
453//===----------------------------------------------------------------------===//
454
455#include "SPUGenCallingConv.inc"
456
457//===----------------------------------------------------------------------===//
458// LowerOperation implementation
459//===----------------------------------------------------------------------===//
460
Scott Michel9de5d0d2008-01-11 02:53:15 +0000461/// Aligned load common code for CellSPU
462/*!
463 \param[in] Op The SelectionDAG load or store operand
464 \param[in] DAG The selection DAG
465 \param[in] ST CellSPU subtarget information structure
466 \param[in,out] alignment Caller initializes this to the load or store node's
467 value from getAlignment(), may be updated while generating the aligned load
468 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
469 offset (divisible by 16, modulo 16 == 0)
470 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
471 offset of the preferred slot (modulo 16 != 0)
472 \param[in,out] VT Caller initializes this value type to the the load or store
473 node's loaded or stored value type; may be updated if an i1-extended load or
474 store.
475 \param[out] was16aligned true if the base pointer had 16-byte alignment,
476 otherwise false. Can help to determine if the chunk needs to be rotated.
477
478 Both load and store lowering load a block of data aligned on a 16-byte
479 boundary. This is the common aligned load code shared between both.
480 */
481static SDOperand
482AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
483 LSBaseSDNode *LSN,
484 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Chris Lattner3f732802008-01-12 22:54:07 +0000485 MVT::ValueType &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000486{
487 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
488 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
489 SDOperand basePtr = LSN->getBasePtr();
490 SDOperand chain = LSN->getChain();
491
492 if (basePtr.getOpcode() == ISD::ADD) {
493 SDOperand Op1 = basePtr.Val->getOperand(1);
494
495 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000496 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000497
498 alignOffs = (int) CN->getValue();
499 prefSlotOffs = (int) (alignOffs & 0xf);
500
501 // Adjust the rotation amount to ensure that the final result ends up in
502 // the preferred slot:
503 prefSlotOffs -= vtm->prefslot_byte;
504 basePtr = basePtr.getOperand(0);
505
Scott Michel58c58182008-01-17 20:38:41 +0000506 // Loading from memory, can we adjust alignment?
507 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
508 SDOperand APtr = basePtr.getOperand(0);
509 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
510 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
511 alignment = GSDN->getGlobal()->getAlignment();
512 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000513 }
514 } else {
515 alignOffs = 0;
516 prefSlotOffs = -vtm->prefslot_byte;
517 }
518 } else {
519 alignOffs = 0;
520 prefSlotOffs = -vtm->prefslot_byte;
521 }
522
523 if (alignment == 16) {
524 // Realign the base pointer as a D-Form address:
525 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000526 basePtr = DAG.getNode(ISD::ADD, PtrVT,
527 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000528 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000529 }
530
531 // Emit the vector load:
532 was16aligned = true;
533 return DAG.getLoad(MVT::v16i8, chain, basePtr,
534 LSN->getSrcValue(), LSN->getSrcValueOffset(),
535 LSN->isVolatile(), 16);
536 }
537
538 // Unaligned load or we're using the "large memory" model, which means that
539 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000540 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000541 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000542 }
543
544 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000545 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000546 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000547 was16aligned = false;
548 return DAG.getLoad(MVT::v16i8, chain, basePtr,
549 LSN->getSrcValue(), LSN->getSrcValueOffset(),
550 LSN->isVolatile(), 16);
551}
552
Scott Michel266bc8f2007-12-04 22:23:35 +0000553/// Custom lower loads for CellSPU
554/*!
555 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
556 within a 16-byte block, we have to rotate to extract the requested element.
557 */
558static SDOperand
559LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
560 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000561 SDOperand the_chain = LN->getChain();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000562 MVT::ValueType VT = LN->getMemoryVT();
Scott Michel266bc8f2007-12-04 22:23:35 +0000563 MVT::ValueType OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000564 ISD::LoadExtType ExtType = LN->getExtensionType();
565 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000566 SDOperand Ops[8];
567
Scott Michel266bc8f2007-12-04 22:23:35 +0000568 switch (LN->getAddressingMode()) {
569 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000570 int offset, rotamt;
571 bool was16aligned;
572 SDOperand result =
573 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000574
Scott Michel9de5d0d2008-01-11 02:53:15 +0000575 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000576 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000577
578 the_chain = result.getValue(1);
579 // Rotate the chunk if necessary
580 if (rotamt < 0)
581 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000582 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000583 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
584
Scott Michel58c58182008-01-17 20:38:41 +0000585 Ops[0] = the_chain;
586 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000587 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000588 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
589 } else {
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000590 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000591 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000592 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000593 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000594 }
595
596 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
597 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000598 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000599
600 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
601 SDVTList scalarvts;
602 MVT::ValueType vecVT = MVT::v16i8;
603
604 // Convert the loaded v16i8 vector to the appropriate vector type
605 // specified by the operand:
606 if (OpVT == VT) {
607 if (VT != MVT::i1)
608 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
609 } else
610 vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
611
612 Ops[0] = the_chain;
613 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
614 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
615 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
616 the_chain = result.getValue(1);
617 } else {
618 // Handle the sign and zero-extending loads for i1 and i8:
619 unsigned NewOpC;
620
621 if (ExtType == ISD::SEXTLOAD) {
622 NewOpC = (OpVT == MVT::i1
623 ? SPUISD::EXTRACT_I1_SEXT
624 : SPUISD::EXTRACT_I8_SEXT);
625 } else {
626 assert(ExtType == ISD::ZEXTLOAD);
627 NewOpC = (OpVT == MVT::i1
628 ? SPUISD::EXTRACT_I1_ZEXT
629 : SPUISD::EXTRACT_I8_ZEXT);
630 }
631
632 result = DAG.getNode(NewOpC, OpVT, result);
633 }
634
635 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000636 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000637 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000638 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000639 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000640
Scott Michel58c58182008-01-17 20:38:41 +0000641 result = DAG.getNode(SPUISD::LDRESULT, retvts,
642 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000643 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000644 }
645 case ISD::PRE_INC:
646 case ISD::PRE_DEC:
647 case ISD::POST_INC:
648 case ISD::POST_DEC:
649 case ISD::LAST_INDEXED_MODE:
650 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
651 "UNINDEXED\n";
652 cerr << (unsigned) LN->getAddressingMode() << "\n";
653 abort();
654 /*NOTREACHED*/
655 }
656
657 return SDOperand();
658}
659
660/// Custom lower stores for CellSPU
661/*!
662 All CellSPU stores are aligned to 16-byte boundaries, so for elements
663 within a 16-byte block, we have to generate a shuffle to insert the
664 requested element into its place, then store the resulting block.
665 */
666static SDOperand
667LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
668 StoreSDNode *SN = cast<StoreSDNode>(Op);
669 SDOperand Value = SN->getValue();
670 MVT::ValueType VT = Value.getValueType();
Dan Gohmanb625f2f2008-01-30 00:15:11 +0000671 MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
Scott Michel266bc8f2007-12-04 22:23:35 +0000672 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000673 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000674
675 switch (SN->getAddressingMode()) {
676 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000677 int chunk_offset, slot_offset;
678 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000679
680 // The vector type we really want to load from the 16-byte chunk, except
681 // in the case of MVT::i1, which has to be v16i8.
Scott Michel9de5d0d2008-01-11 02:53:15 +0000682 unsigned vecVT, stVecVT = MVT::v16i8;
683
Scott Michel266bc8f2007-12-04 22:23:35 +0000684 if (StVT != MVT::i1)
685 stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
Scott Michel266bc8f2007-12-04 22:23:35 +0000686 vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
687
Scott Michel9de5d0d2008-01-11 02:53:15 +0000688 SDOperand alignLoadVec =
689 AlignedLoad(Op, DAG, ST, SN, alignment,
690 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000691
Scott Michel9de5d0d2008-01-11 02:53:15 +0000692 if (alignLoadVec.Val == 0)
693 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000694
Scott Michel9de5d0d2008-01-11 02:53:15 +0000695 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
696 SDOperand basePtr = LN->getBasePtr();
697 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000698 SDOperand theValue = SN->getValue();
699 SDOperand result;
700
701 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000702 && (theValue.getOpcode() == ISD::AssertZext
703 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000704 // Drill down and get the value for zero- and sign-extended
705 // quantities
706 theValue = theValue.getOperand(0);
707 }
708
Scott Michel9de5d0d2008-01-11 02:53:15 +0000709 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000710
Scott Michel9de5d0d2008-01-11 02:53:15 +0000711 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
712 SDOperand insertEltPtr;
713 SDOperand insertEltOp;
714
715 // If the base pointer is already a D-form address, then just create
716 // a new D-form address with a slot offset and the orignal base pointer.
717 // Otherwise generate a D-form address with the slot offset relative
718 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000719 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
720 DEBUG(basePtr.Val->dump(&DAG));
721 DEBUG(cerr << "\n");
722
Scott Michel053c1da2008-01-29 02:16:57 +0000723 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
724 (basePtr.getOpcode() == ISD::ADD
725 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000726 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000727 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000728 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000729 }
730
731 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000732 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000733 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
734 alignLoadVec,
735 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000736
Scott Michel9de5d0d2008-01-11 02:53:15 +0000737 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000738 LN->getSrcValue(), LN->getSrcValueOffset(),
739 LN->isVolatile(), LN->getAlignment());
740
741 return result;
742 /*UNREACHED*/
743 }
744 case ISD::PRE_INC:
745 case ISD::PRE_DEC:
746 case ISD::POST_INC:
747 case ISD::POST_DEC:
748 case ISD::LAST_INDEXED_MODE:
749 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
750 "UNINDEXED\n";
751 cerr << (unsigned) SN->getAddressingMode() << "\n";
752 abort();
753 /*NOTREACHED*/
754 }
755
756 return SDOperand();
757}
758
759/// Generate the address of a constant pool entry.
760static SDOperand
761LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
762 MVT::ValueType PtrVT = Op.getValueType();
763 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
764 Constant *C = CP->getConstVal();
765 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000766 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000767 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000768
769 if (TM.getRelocationModel() == Reloc::Static) {
770 if (!ST->usingLargeMem()) {
771 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000772 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000773 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000774 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
775 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000776 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000777 }
778 }
779
780 assert(0 &&
781 "LowerConstantPool: Relocation model other than static not supported.");
782 return SDOperand();
783}
784
785static SDOperand
786LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
787 MVT::ValueType PtrVT = Op.getValueType();
788 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
789 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
790 SDOperand Zero = DAG.getConstant(0, PtrVT);
791 const TargetMachine &TM = DAG.getTarget();
792
793 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000794 if (!ST->usingLargeMem()) {
795 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
796 } else {
797 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
798 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
799 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
800 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000801 }
802
803 assert(0 &&
804 "LowerJumpTable: Relocation model other than static not supported.");
805 return SDOperand();
806}
807
808static SDOperand
809LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
810 MVT::ValueType PtrVT = Op.getValueType();
811 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
812 GlobalValue *GV = GSDN->getGlobal();
813 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000814 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000815 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000816
817 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000818 if (!ST->usingLargeMem()) {
819 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
820 } else {
821 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
822 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
823 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
824 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000825 } else {
826 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000827 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000828 abort();
829 /*NOTREACHED*/
830 }
831
832 return SDOperand();
833}
834
835//! Custom lower i64 integer constants
836/*!
837 This code inserts all of the necessary juggling that needs to occur to load
838 a 64-bit constant into a register.
839 */
840static SDOperand
841LowerConstant(SDOperand Op, SelectionDAG &DAG) {
842 unsigned VT = Op.getValueType();
843 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
844
845 if (VT == MVT::i64) {
846 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
847 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000848 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000849 } else {
850 cerr << "LowerConstant: unhandled constant type "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000851 << MVT::getValueTypeString(VT)
852 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000853 abort();
854 /*NOTREACHED*/
855 }
856
857 return SDOperand();
858}
859
Nate Begemanccef5802008-02-14 18:43:04 +0000860//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000861static SDOperand
862LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
863 unsigned VT = Op.getValueType();
864 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
865
866 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000867 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000868
Nate Begemanccef5802008-02-14 18:43:04 +0000869 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000870 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000871 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000872 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000873 }
874
875 return SDOperand();
876}
877
Scott Michel58c58182008-01-17 20:38:41 +0000878//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
879static SDOperand
880LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
881{
882 SDOperand Cond = Op.getOperand(1);
883 MVT::ValueType CondVT = Cond.getValueType();
884 MVT::ValueType CondNVT;
885
886 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
887 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
888 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
889 Op.getOperand(0),
890 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
891 Op.getOperand(2));
892 } else
893 return SDOperand(); // Unchanged
894}
895
Scott Michel266bc8f2007-12-04 22:23:35 +0000896static SDOperand
897LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
898{
899 MachineFunction &MF = DAG.getMachineFunction();
900 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000901 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000902 SmallVector<SDOperand, 8> ArgValues;
903 SDOperand Root = Op.getOperand(0);
904 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
905
906 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
907 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
908
909 unsigned ArgOffset = SPUFrameInfo::minStackSize();
910 unsigned ArgRegIdx = 0;
911 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
912
913 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
914
915 // Add DAG nodes to load the arguments or copy them out of registers.
916 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
917 SDOperand ArgVal;
918 bool needsLoad = false;
919 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
920 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
921
922 switch (ObjectVT) {
923 default: {
924 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000925 << MVT::getValueTypeString(ObjectVT)
Scott Michel266bc8f2007-12-04 22:23:35 +0000926 << "\n";
927 abort();
928 }
929 case MVT::i8:
930 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000931 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
932 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000933 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
934 ++ArgRegIdx;
935 } else {
936 needsLoad = true;
937 }
938 break;
939 case MVT::i16:
940 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000941 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
942 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000943 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
944 ++ArgRegIdx;
945 } else {
946 needsLoad = true;
947 }
948 break;
949 case MVT::i32:
950 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000951 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
952 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000953 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
954 ++ArgRegIdx;
955 } else {
956 needsLoad = true;
957 }
958 break;
959 case MVT::i64:
960 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000961 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
962 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000963 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
964 ++ArgRegIdx;
965 } else {
966 needsLoad = true;
967 }
968 break;
969 case MVT::f32:
970 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000971 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
972 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000973 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
974 ++ArgRegIdx;
975 } else {
976 needsLoad = true;
977 }
978 break;
979 case MVT::f64:
980 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000981 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
982 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000983 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
984 ++ArgRegIdx;
985 } else {
986 needsLoad = true;
987 }
988 break;
989 case MVT::v2f64:
990 case MVT::v4f32:
Scott Michelad2715e2008-03-05 23:02:02 +0000991 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +0000992 case MVT::v4i32:
993 case MVT::v8i16:
994 case MVT::v16i8:
995 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000996 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
997 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000998 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
999 ++ArgRegIdx;
1000 } else {
1001 needsLoad = true;
1002 }
1003 break;
1004 }
1005
1006 // We need to load the argument to a virtual register if we determined above
1007 // that we ran out of physical registers of the appropriate type
1008 if (needsLoad) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001009 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1010 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1011 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001012 ArgOffset += StackSlotSize;
1013 }
1014
1015 ArgValues.push_back(ArgVal);
1016 }
1017
1018 // If the function takes variable number of arguments, make a frame index for
1019 // the start of the first vararg value... for expansion of llvm.va_start.
1020 if (isVarArg) {
1021 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
1022 ArgOffset);
1023 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1024 // If this function is vararg, store any remaining integer argument regs to
1025 // their spots on the stack so that they may be loaded by deferencing the
1026 // result of va_next.
1027 SmallVector<SDOperand, 8> MemOps;
1028 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001029 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1030 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001031 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1032 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1033 MemOps.push_back(Store);
1034 // Increment the address by four for the next argument to store
1035 SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
1036 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1037 }
1038 if (!MemOps.empty())
1039 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1040 }
1041
1042 ArgValues.push_back(Root);
1043
1044 // Return the new list of results.
1045 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
1046 Op.Val->value_end());
1047 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
1048}
1049
1050/// isLSAAddress - Return the immediate to use if the specified
1051/// value is representable as a LSA address.
1052static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1053 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1054 if (!C) return 0;
1055
1056 int Addr = C->getValue();
1057 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1058 (Addr << 14 >> 14) != Addr)
1059 return 0; // Top 14 bits have to be sext of immediate.
1060
1061 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1062}
1063
1064static
1065SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001066LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001067 SDOperand Chain = Op.getOperand(0);
1068#if 0
1069 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1070 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1071#endif
1072 SDOperand Callee = Op.getOperand(4);
1073 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1074 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1075 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1076 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1077
1078 // Handy pointer type
1079 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1080
1081 // Accumulate how many bytes are to be pushed on the stack, including the
1082 // linkage area, and parameter passing area. According to the SPU ABI,
1083 // we minimally need space for [LR] and [SP]
1084 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1085
1086 // Set up a copy of the stack pointer for use loading and storing any
1087 // arguments that may not fit in the registers available for argument
1088 // passing.
1089 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1090
1091 // Figure out which arguments are going to go in registers, and which in
1092 // memory.
1093 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1094 unsigned ArgRegIdx = 0;
1095
1096 // Keep track of registers passing arguments
1097 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1098 // And the arguments passed on the stack
1099 SmallVector<SDOperand, 8> MemOpChains;
1100
1101 for (unsigned i = 0; i != NumOps; ++i) {
1102 SDOperand Arg = Op.getOperand(5+2*i);
1103
1104 // PtrOff will be used to store the current argument to the stack if a
1105 // register cannot be found for it.
1106 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1107 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1108
1109 switch (Arg.getValueType()) {
1110 default: assert(0 && "Unexpected ValueType for argument!");
1111 case MVT::i32:
1112 case MVT::i64:
1113 case MVT::i128:
1114 if (ArgRegIdx != NumArgRegs) {
1115 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1116 } else {
1117 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001118 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001119 }
1120 break;
1121 case MVT::f32:
1122 case MVT::f64:
1123 if (ArgRegIdx != NumArgRegs) {
1124 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1125 } else {
1126 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001127 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001128 }
1129 break;
1130 case MVT::v4f32:
1131 case MVT::v4i32:
1132 case MVT::v8i16:
1133 case MVT::v16i8:
1134 if (ArgRegIdx != NumArgRegs) {
1135 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1136 } else {
1137 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001138 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001139 }
1140 break;
1141 }
1142 }
1143
1144 // Update number of stack bytes actually used, insert a call sequence start
1145 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1146 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1147
1148 if (!MemOpChains.empty()) {
1149 // Adjust the stack pointer for the stack arguments.
1150 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1151 &MemOpChains[0], MemOpChains.size());
1152 }
1153
1154 // Build a sequence of copy-to-reg nodes chained together with token chain
1155 // and flag operands which copy the outgoing args into the appropriate regs.
1156 SDOperand InFlag;
1157 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1158 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1159 InFlag);
1160 InFlag = Chain.getValue(1);
1161 }
1162
1163 std::vector<MVT::ValueType> NodeTys;
1164 NodeTys.push_back(MVT::Other); // Returns a chain
1165 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1166
1167 SmallVector<SDOperand, 8> Ops;
1168 unsigned CallOpc = SPUISD::CALL;
1169
1170 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1171 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1172 // node so that legalize doesn't hack it.
1173 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1174 GlobalValue *GV = G->getGlobal();
1175 unsigned CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001176 SDOperand Zero = DAG.getConstant(0, PtrVT);
1177 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001178
Scott Michel9de5d0d2008-01-11 02:53:15 +00001179 if (!ST->usingLargeMem()) {
1180 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1181 // style calls, otherwise, external symbols are BRASL calls. This assumes
1182 // that declared/defined symbols are in the same compilation unit and can
1183 // be reached through PC-relative jumps.
1184 //
1185 // NOTE:
1186 // This may be an unsafe assumption for JIT and really large compilation
1187 // units.
1188 if (GV->isDeclaration()) {
1189 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1190 } else {
1191 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1192 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001193 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001194 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1195 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001196 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001197 }
1198 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1199 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001200 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001201 // If this is an absolute destination address that appears to be a legal
1202 // local store address, use the munged value.
1203 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001204 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001205
1206 Ops.push_back(Chain);
1207 Ops.push_back(Callee);
1208
1209 // Add argument registers to the end of the list so that they are known live
1210 // into the call.
1211 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1212 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1213 RegsToPass[i].second.getValueType()));
1214
1215 if (InFlag.Val)
1216 Ops.push_back(InFlag);
1217 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1218 InFlag = Chain.getValue(1);
1219
Evan Chengebaaa912008-02-05 22:44:06 +00001220 Chain = DAG.getCALLSEQ_END(Chain,
1221 DAG.getConstant(NumStackBytes, PtrVT),
1222 DAG.getConstant(0, PtrVT),
1223 InFlag);
1224 if (Op.Val->getValueType(0) != MVT::Other)
1225 InFlag = Chain.getValue(1);
1226
Scott Michel266bc8f2007-12-04 22:23:35 +00001227 SDOperand ResultVals[3];
1228 unsigned NumResults = 0;
1229 NodeTys.clear();
1230
1231 // If the call has results, copy the values out of the ret val registers.
1232 switch (Op.Val->getValueType(0)) {
1233 default: assert(0 && "Unexpected ret value!");
1234 case MVT::Other: break;
1235 case MVT::i32:
1236 if (Op.Val->getValueType(1) == MVT::i32) {
1237 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1238 ResultVals[0] = Chain.getValue(0);
1239 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1240 Chain.getValue(2)).getValue(1);
1241 ResultVals[1] = Chain.getValue(0);
1242 NumResults = 2;
1243 NodeTys.push_back(MVT::i32);
1244 } else {
1245 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1246 ResultVals[0] = Chain.getValue(0);
1247 NumResults = 1;
1248 }
1249 NodeTys.push_back(MVT::i32);
1250 break;
1251 case MVT::i64:
1252 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1253 ResultVals[0] = Chain.getValue(0);
1254 NumResults = 1;
1255 NodeTys.push_back(MVT::i64);
1256 break;
1257 case MVT::f32:
1258 case MVT::f64:
1259 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1260 InFlag).getValue(1);
1261 ResultVals[0] = Chain.getValue(0);
1262 NumResults = 1;
1263 NodeTys.push_back(Op.Val->getValueType(0));
1264 break;
1265 case MVT::v2f64:
1266 case MVT::v4f32:
1267 case MVT::v4i32:
1268 case MVT::v8i16:
1269 case MVT::v16i8:
1270 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1271 InFlag).getValue(1);
1272 ResultVals[0] = Chain.getValue(0);
1273 NumResults = 1;
1274 NodeTys.push_back(Op.Val->getValueType(0));
1275 break;
1276 }
1277
Scott Michel266bc8f2007-12-04 22:23:35 +00001278 NodeTys.push_back(MVT::Other);
1279
1280 // If the function returns void, just return the chain.
1281 if (NumResults == 0)
1282 return Chain;
1283
1284 // Otherwise, merge everything together with a MERGE_VALUES node.
1285 ResultVals[NumResults++] = Chain;
1286 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
1287 ResultVals, NumResults);
1288 return Res.getValue(Op.ResNo);
1289}
1290
1291static SDOperand
1292LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1293 SmallVector<CCValAssign, 16> RVLocs;
1294 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1295 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1296 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1297 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1298
1299 // If this is the first return lowered for this function, add the regs to the
1300 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001301 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001302 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001303 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001304 }
1305
1306 SDOperand Chain = Op.getOperand(0);
1307 SDOperand Flag;
1308
1309 // Copy the result values into the output registers.
1310 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1311 CCValAssign &VA = RVLocs[i];
1312 assert(VA.isRegLoc() && "Can only return in registers!");
1313 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1314 Flag = Chain.getValue(1);
1315 }
1316
1317 if (Flag.Val)
1318 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1319 else
1320 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1321}
1322
1323
1324//===----------------------------------------------------------------------===//
1325// Vector related lowering:
1326//===----------------------------------------------------------------------===//
1327
1328static ConstantSDNode *
1329getVecImm(SDNode *N) {
1330 SDOperand OpVal(0, 0);
1331
1332 // Check to see if this buildvec has a single non-undef value in its elements.
1333 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1334 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1335 if (OpVal.Val == 0)
1336 OpVal = N->getOperand(i);
1337 else if (OpVal != N->getOperand(i))
1338 return 0;
1339 }
1340
1341 if (OpVal.Val != 0) {
1342 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1343 return CN;
1344 }
1345 }
1346
1347 return 0; // All UNDEF: use implicit def.; not Constant node
1348}
1349
1350/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1351/// and the value fits into an unsigned 18-bit constant, and if so, return the
1352/// constant
1353SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
1354 MVT::ValueType ValueType) {
1355 if (ConstantSDNode *CN = getVecImm(N)) {
1356 uint64_t Value = CN->getValue();
1357 if (Value <= 0x3ffff)
1358 return DAG.getConstant(Value, ValueType);
1359 }
1360
1361 return SDOperand();
1362}
1363
1364/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1365/// and the value fits into a signed 16-bit constant, and if so, return the
1366/// constant
1367SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
1368 MVT::ValueType ValueType) {
1369 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001370 int64_t Value = CN->getSignExtended();
1371 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1372 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001373 }
1374 }
1375
1376 return SDOperand();
1377}
1378
1379/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1380/// and the value fits into a signed 10-bit constant, and if so, return the
1381/// constant
1382SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
1383 MVT::ValueType ValueType) {
1384 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001385 int64_t Value = CN->getSignExtended();
1386 if (isS10Constant(Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001387 return DAG.getConstant(Value, ValueType);
1388 }
1389
1390 return SDOperand();
1391}
1392
1393/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1394/// and the value fits into a signed 8-bit constant, and if so, return the
1395/// constant.
1396///
1397/// @note: The incoming vector is v16i8 because that's the only way we can load
1398/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1399/// same value.
1400SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
1401 MVT::ValueType ValueType) {
1402 if (ConstantSDNode *CN = getVecImm(N)) {
1403 int Value = (int) CN->getValue();
1404 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001405 && Value <= 0xffff /* truncated from uint64_t */
1406 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001407 return DAG.getConstant(Value & 0xff, ValueType);
1408 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001409 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001410 return DAG.getConstant(Value, ValueType);
1411 }
1412
1413 return SDOperand();
1414}
1415
1416/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1417/// and the value fits into a signed 16-bit constant, and if so, return the
1418/// constant
1419SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
1420 MVT::ValueType ValueType) {
1421 if (ConstantSDNode *CN = getVecImm(N)) {
1422 uint64_t Value = CN->getValue();
1423 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001424 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1425 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001426 return DAG.getConstant(Value >> 16, ValueType);
1427 }
1428
1429 return SDOperand();
1430}
1431
1432/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1433SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1434 if (ConstantSDNode *CN = getVecImm(N)) {
1435 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1436 }
1437
1438 return SDOperand();
1439}
1440
1441/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1442SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1443 if (ConstantSDNode *CN = getVecImm(N)) {
1444 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1445 }
1446
1447 return SDOperand();
1448}
1449
1450// If this is a vector of constants or undefs, get the bits. A bit in
1451// UndefBits is set if the corresponding element of the vector is an
1452// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1453// zero. Return true if this is not an array of constants, false if it is.
1454//
1455static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1456 uint64_t UndefBits[2]) {
1457 // Start with zero'd results.
1458 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1459
1460 unsigned EltBitSize = MVT::getSizeInBits(BV->getOperand(0).getValueType());
1461 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1462 SDOperand OpVal = BV->getOperand(i);
1463
1464 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1465 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1466
1467 uint64_t EltBits = 0;
1468 if (OpVal.getOpcode() == ISD::UNDEF) {
1469 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1470 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1471 continue;
1472 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1473 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1474 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1475 const APFloat &apf = CN->getValueAPF();
1476 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001477 ? FloatToBits(apf.convertToFloat())
1478 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001479 } else {
1480 // Nonconstant element.
1481 return true;
1482 }
1483
1484 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1485 }
1486
1487 //printf("%llx %llx %llx %llx\n",
1488 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1489 return false;
1490}
1491
1492/// If this is a splat (repetition) of a value across the whole vector, return
1493/// the smallest size that splats it. For example, "0x01010101010101..." is a
1494/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1495/// SplatSize = 1 byte.
1496static bool isConstantSplat(const uint64_t Bits128[2],
1497 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001498 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001499 uint64_t &SplatBits, uint64_t &SplatUndef,
1500 int &SplatSize) {
1501 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1502 // the same as the lower 64-bits, ignoring undefs.
1503 uint64_t Bits64 = Bits128[0] | Bits128[1];
1504 uint64_t Undef64 = Undef128[0] & Undef128[1];
1505 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1506 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1507 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1508 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1509
1510 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1511 if (MinSplatBits < 64) {
1512
1513 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1514 // undefs.
1515 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001516 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001517
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001518 // If the top 16-bits are different than the lower 16-bits, ignoring
1519 // undefs, we have an i32 splat.
1520 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1521 if (MinSplatBits < 16) {
1522 // If the top 8-bits are different than the lower 8-bits, ignoring
1523 // undefs, we have an i16 splat.
1524 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1525 // Otherwise, we have an 8-bit splat.
1526 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1527 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1528 SplatSize = 1;
1529 return true;
1530 }
1531 } else {
1532 SplatBits = Bits16;
1533 SplatUndef = Undef16;
1534 SplatSize = 2;
1535 return true;
1536 }
1537 }
1538 } else {
1539 SplatBits = Bits32;
1540 SplatUndef = Undef32;
1541 SplatSize = 4;
1542 return true;
1543 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001544 }
1545 } else {
1546 SplatBits = Bits128[0];
1547 SplatUndef = Undef128[0];
1548 SplatSize = 8;
1549 return true;
1550 }
1551 }
1552
1553 return false; // Can't be a splat if two pieces don't match.
1554}
1555
1556// If this is a case we can't handle, return null and let the default
1557// expansion code take care of it. If we CAN select this case, and if it
1558// selects to a single instruction, return Op. Otherwise, if we can codegen
1559// this case more efficiently than a constant pool load, lower it to the
1560// sequence of ops that should be used.
1561static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
1562 MVT::ValueType VT = Op.getValueType();
1563 // If this is a vector of constants or undefs, get the bits. A bit in
1564 // UndefBits is set if the corresponding element of the vector is an
1565 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1566 // zero.
1567 uint64_t VectorBits[2];
1568 uint64_t UndefBits[2];
1569 uint64_t SplatBits, SplatUndef;
1570 int SplatSize;
1571 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1572 || !isConstantSplat(VectorBits, UndefBits,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001573 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
Scott Michel266bc8f2007-12-04 22:23:35 +00001574 SplatBits, SplatUndef, SplatSize))
1575 return SDOperand(); // Not a constant vector, not a splat.
1576
1577 switch (VT) {
1578 default:
1579 case MVT::v4f32: {
1580 uint32_t Value32 = SplatBits;
1581 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001582 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001583 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1584 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1585 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001586 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001587 break;
1588 }
1589 case MVT::v2f64: {
1590 uint64_t f64val = SplatBits;
1591 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001592 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001593 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1594 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1595 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001596 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001597 break;
1598 }
1599 case MVT::v16i8: {
1600 // 8-bit constants have to be expanded to 16-bits
1601 unsigned short Value16 = SplatBits | (SplatBits << 8);
1602 SDOperand Ops[8];
1603 for (int i = 0; i < 8; ++i)
1604 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1605 return DAG.getNode(ISD::BIT_CONVERT, VT,
1606 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1607 }
1608 case MVT::v8i16: {
1609 unsigned short Value16;
1610 if (SplatSize == 2)
1611 Value16 = (unsigned short) (SplatBits & 0xffff);
1612 else
1613 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
1614 SDOperand T = DAG.getConstant(Value16, MVT::getVectorElementType(VT));
1615 SDOperand Ops[8];
1616 for (int i = 0; i < 8; ++i) Ops[i] = T;
1617 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1618 }
1619 case MVT::v4i32: {
1620 unsigned int Value = SplatBits;
1621 SDOperand T = DAG.getConstant(Value, MVT::getVectorElementType(VT));
1622 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1623 }
1624 case MVT::v2i64: {
1625 uint64_t val = SplatBits;
1626 uint32_t upper = uint32_t(val >> 32);
1627 uint32_t lower = uint32_t(val);
1628
Scott Michelad2715e2008-03-05 23:02:02 +00001629 if (val == 0) {
1630 SDOperand Zero = DAG.getTargetConstant(0, MVT::i64);
1631 return DAG.getNode(ISD::BUILD_VECTOR, VT, Zero, Zero);
1632 } else if (val == 0xffffffffffffffffULL) {
1633 // For -1, this and has a chance of matching immAllOnesV.
1634 SDOperand NegOne = DAG.getTargetConstant(-1, MVT::i64);
1635 return DAG.getNode(ISD::BUILD_VECTOR, VT, NegOne, NegOne);
1636 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +00001637 SDOperand LO32;
1638 SDOperand HI32;
1639 SmallVector<SDOperand, 16> ShufBytes;
1640 SDOperand Result;
1641 bool upper_special, lower_special;
1642
1643 // NOTE: This code creates common-case shuffle masks that can be easily
1644 // detected as common expressions. It is not attempting to create highly
1645 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1646
1647 // Detect if the upper or lower half is a special shuffle mask pattern:
1648 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1649 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1650
1651 // Create lower vector if not a special pattern
1652 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001653 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1654 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1655 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1656 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001657 }
1658
1659 // Create upper vector if not a special pattern
1660 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001661 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1662 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1663 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1664 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001665 }
1666
1667 // If either upper or lower are special, then the two input operands are
1668 // the same (basically, one of them is a "don't care")
1669 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001670 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001671 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001672 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001673 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001674 // Unhappy situation... both upper and lower are special, so punt with
1675 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001676 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001677 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001678 Zero, Zero);
1679 }
1680
1681 for (int i = 0; i < 4; ++i) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001682 for (int j = 0; j < 4; ++j) {
1683 SDOperand V;
1684 bool process_upper, process_lower;
1685 uint64_t val = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001686
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001687 process_upper = (upper_special && (i & 1) == 0);
1688 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001689
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001690 if (process_upper || process_lower) {
1691 if ((process_upper && upper == 0)
1692 || (process_lower && lower == 0))
1693 val = 0x80;
1694 else if ((process_upper && upper == 0xffffffff)
1695 || (process_lower && lower == 0xffffffff))
1696 val = 0xc0;
1697 else if ((process_upper && upper == 0x80000000)
1698 || (process_lower && lower == 0x80000000))
1699 val = (j == 0 ? 0xe0 : 0x80);
1700 } else
1701 val = i * 4 + j + ((i & 1) * 16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001702
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001703 ShufBytes.push_back(DAG.getConstant(val, MVT::i8));
1704 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001705 }
1706
1707 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001708 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
1709 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001710 }
1711 }
1712 }
1713
1714 return SDOperand();
1715}
1716
1717/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1718/// which the Cell can operate. The code inspects V3 to ascertain whether the
1719/// permutation vector, V3, is monotonically increasing with one "exception"
1720/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1721/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1722/// In either case, the net result is going to eventually invoke SHUFB to
1723/// permute/shuffle the bytes from V1 and V2.
1724/// \note
1725/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1726/// control word for byte/halfword/word insertion. This takes care of a single
1727/// element move from V2 into V1.
1728/// \note
1729/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1730static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1731 SDOperand V1 = Op.getOperand(0);
1732 SDOperand V2 = Op.getOperand(1);
1733 SDOperand PermMask = Op.getOperand(2);
1734
1735 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1736
1737 // If we have a single element being moved from V1 to V2, this can be handled
1738 // using the C*[DX] compute mask instructions, but the vector elements have
1739 // to be monotonically increasing with one exception element.
1740 MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
1741 unsigned EltsFromV2 = 0;
1742 unsigned V2Elt = 0;
1743 unsigned V2EltIdx0 = 0;
1744 unsigned CurrElt = 0;
1745 bool monotonic = true;
1746 if (EltVT == MVT::i8)
1747 V2EltIdx0 = 16;
1748 else if (EltVT == MVT::i16)
1749 V2EltIdx0 = 8;
1750 else if (EltVT == MVT::i32)
1751 V2EltIdx0 = 4;
1752 else
1753 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1754
1755 for (unsigned i = 0, e = PermMask.getNumOperands();
1756 EltsFromV2 <= 1 && monotonic && i != e;
1757 ++i) {
1758 unsigned SrcElt;
1759 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1760 SrcElt = 0;
1761 else
1762 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1763
1764 if (SrcElt >= V2EltIdx0) {
1765 ++EltsFromV2;
1766 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1767 } else if (CurrElt != SrcElt) {
1768 monotonic = false;
1769 }
1770
1771 ++CurrElt;
1772 }
1773
1774 if (EltsFromV2 == 1 && monotonic) {
1775 // Compute mask and shuffle
1776 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001777 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1778 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001779 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
1780 // Initialize temporary register to 0
1781 SDOperand InitTempReg =
1782 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1783 // Copy register's contents as index in INSERT_MASK:
1784 SDOperand ShufMaskOp =
1785 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001786 DAG.getTargetConstant(V2Elt, MVT::i32),
1787 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001788 // Use shuffle mask in SHUFB synthetic instruction:
1789 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1790 } else {
1791 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
1792 unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
1793
1794 SmallVector<SDOperand, 16> ResultMask;
1795 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1796 unsigned SrcElt;
1797 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001798 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001799 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001800 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001801
Scott Michela59d4692008-02-23 18:41:37 +00001802 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001803 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1804 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001805 }
1806 }
1807
1808 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001809 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001810 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1811 }
1812}
1813
1814static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001815 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001816
1817 if (Op0.Val->getOpcode() == ISD::Constant) {
1818 // For a constant, build the appropriate constant vector, which will
1819 // eventually simplify to a vector register load.
1820
1821 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1822 SmallVector<SDOperand, 16> ConstVecValues;
1823 MVT::ValueType VT;
1824 size_t n_copies;
1825
1826 // Create a constant vector:
1827 switch (Op.getValueType()) {
1828 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001829 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001830 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1831 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1832 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1833 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1834 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1835 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1836 }
1837
1838 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1839 for (size_t j = 0; j < n_copies; ++j)
1840 ConstVecValues.push_back(CValue);
1841
1842 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001843 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001844 } else {
1845 // Otherwise, copy the value from one register to another:
1846 switch (Op0.getValueType()) {
1847 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1848 case MVT::i8:
1849 case MVT::i16:
1850 case MVT::i32:
1851 case MVT::i64:
1852 case MVT::f32:
1853 case MVT::f64:
1854 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1855 }
1856 }
1857
1858 return SDOperand();
1859}
1860
1861static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
1862 switch (Op.getValueType()) {
1863 case MVT::v4i32: {
1864 SDOperand rA = Op.getOperand(0);
1865 SDOperand rB = Op.getOperand(1);
1866 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1867 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1868 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1869 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1870
1871 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1872 break;
1873 }
1874
1875 // Multiply two v8i16 vectors (pipeline friendly version):
1876 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1877 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1878 // c) Use SELB to select upper and lower halves from the intermediate results
1879 //
1880 // NOTE: We really want to move the FSMBI to earlier to actually get the
1881 // dual-issue. This code does manage to do this, even if it's a little on
1882 // the wacky side
1883 case MVT::v8i16: {
1884 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001885 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001886 SDOperand Chain = Op.getOperand(0);
1887 SDOperand rA = Op.getOperand(0);
1888 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001889 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1890 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001891
1892 SDOperand FSMBOp =
1893 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001894 DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1895 DAG.getConstant(0xcccc, MVT::i32)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001896
1897 SDOperand HHProd =
1898 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001899 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001900
1901 SDOperand HHProd_v4i32 =
1902 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001903 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001904
1905 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001906 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1907 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1908 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1909 HHProd_v4i32,
1910 DAG.getConstant(16, MVT::i16))),
1911 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001912 }
1913
1914 // This M00sE is N@stI! (apologies to Monty Python)
1915 //
1916 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1917 // is to break it all apart, sign extend, and reassemble the various
1918 // intermediate products.
1919 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001920 SDOperand rA = Op.getOperand(0);
1921 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001922 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1923 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001924
1925 SDOperand LLProd =
1926 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001927 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1928 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001929
1930 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1931
1932 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1933
1934 SDOperand LHProd =
1935 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001936 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001937
Scott Michela59d4692008-02-23 18:41:37 +00001938 SDOperand FSMBmask = DAG.getNode(SPUISD::FSMBI, MVT::v8i16,
1939 DAG.getConstant(0x2222, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001940
Scott Michela59d4692008-02-23 18:41:37 +00001941 SDOperand LoProdParts =
1942 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1943 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1944 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001945
1946 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1947
1948 SDOperand LoProd =
1949 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001950 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001951 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1952 LoProdMask, LoProdMask,
1953 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001954
1955 SDOperand rAH =
1956 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001957 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001958
1959 SDOperand rBH =
1960 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001961 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001962
1963 SDOperand HLProd =
1964 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001965 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
1966 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00001967
1968 SDOperand HHProd_1 =
1969 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001970 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1971 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
1972 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
1973 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001974
1975 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00001976 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1977 HLProd,
1978 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
1979 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00001980
1981 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00001982 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00001983
1984 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001985 DAG.getNode(ISD::OR, MVT::v4i32,
1986 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00001987 }
1988
1989 default:
1990 cerr << "CellSPU: Unknown vector multiplication, got "
1991 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001992 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00001993 abort();
1994 /*NOTREACHED*/
1995 }
1996
1997 return SDOperand();
1998}
1999
2000static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2001 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002002 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002003
2004 SDOperand A = Op.getOperand(0);
2005 SDOperand B = Op.getOperand(1);
2006 unsigned VT = Op.getValueType();
2007
2008 unsigned VRegBR, VRegC;
2009
2010 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002011 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2012 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002013 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002014 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2015 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002016 }
2017 // TODO: make sure we're feeding FPInterp the right arguments
2018 // Right now: fi B, frest(B)
2019
2020 // Computes BRcpl =
2021 // (Floating Interpolate (FP Reciprocal Estimate B))
2022 SDOperand BRcpl =
2023 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002024 DAG.getNode(SPUISD::FPInterp, VT, B,
2025 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002026
2027 // Computes A * BRcpl and stores in a temporary register
2028 SDOperand AxBRcpl =
2029 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002030 DAG.getNode(ISD::FMUL, VT, A,
2031 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002032 // What's the Chain variable do? It's magic!
2033 // TODO: set Chain = Op(0).getEntryNode()
2034
2035 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002036 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2037 DAG.getNode(ISD::FMUL, VT,
2038 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2039 DAG.getNode(ISD::FSUB, VT, A,
2040 DAG.getNode(ISD::FMUL, VT, B,
2041 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002042}
2043
Scott Michel266bc8f2007-12-04 22:23:35 +00002044static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2045 unsigned VT = Op.getValueType();
2046 SDOperand N = Op.getOperand(0);
2047 SDOperand Elt = Op.getOperand(1);
2048 SDOperand ShufMask[16];
2049 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2050
2051 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2052
2053 int EltNo = (int) C->getValue();
2054
2055 // sanity checks:
2056 if (VT == MVT::i8 && EltNo >= 16)
2057 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2058 else if (VT == MVT::i16 && EltNo >= 8)
2059 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2060 else if (VT == MVT::i32 && EltNo >= 4)
2061 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2062 else if (VT == MVT::i64 && EltNo >= 2)
2063 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2064
2065 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2066 // i32 and i64: Element 0 is the preferred slot
2067 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2068 }
2069
2070 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002071 int prefslot_begin = -1, prefslot_end = -1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002072 int elt_byte = EltNo * MVT::getSizeInBits(VT) / 8;
2073
2074 switch (VT) {
2075 case MVT::i8: {
2076 prefslot_begin = prefslot_end = 3;
2077 break;
2078 }
2079 case MVT::i16: {
2080 prefslot_begin = 2; prefslot_end = 3;
2081 break;
2082 }
2083 case MVT::i32: {
2084 prefslot_begin = 0; prefslot_end = 3;
2085 break;
2086 }
2087 case MVT::i64: {
2088 prefslot_begin = 0; prefslot_end = 7;
2089 break;
2090 }
2091 }
2092
Scott Michel0e5665b2007-12-19 21:17:42 +00002093 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002094 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002095
Scott Michel266bc8f2007-12-04 22:23:35 +00002096 for (int i = 0; i < 16; ++i) {
2097 // zero fill uppper part of preferred slot, don't care about the
2098 // other slots:
2099 unsigned int mask_val;
2100
2101 if (i <= prefslot_end) {
2102 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002103 ((i < prefslot_begin)
2104 ? 0x80
2105 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002106
Scott Michel0e5665b2007-12-19 21:17:42 +00002107 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002108 } else
2109 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2110 }
2111
2112 SDOperand ShufMaskVec =
2113 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002114 &ShufMask[0],
2115 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002116
2117 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002118 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2119 N, N, ShufMaskVec));
2120
Scott Michel266bc8f2007-12-04 22:23:35 +00002121}
2122
2123static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2124 SDOperand VecOp = Op.getOperand(0);
2125 SDOperand ValOp = Op.getOperand(1);
2126 SDOperand IdxOp = Op.getOperand(2);
2127 MVT::ValueType VT = Op.getValueType();
2128
2129 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2130 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2131
2132 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
2133 // Use $2 because it's always 16-byte aligned and it's available:
2134 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2135
2136 SDOperand result =
2137 DAG.getNode(SPUISD::SHUFB, VT,
2138 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2139 VecOp,
2140 DAG.getNode(SPUISD::INSERT_MASK, VT,
2141 DAG.getNode(ISD::ADD, PtrVT,
2142 PtrBase,
2143 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002144 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002145
2146 return result;
2147}
2148
Scott Michela59d4692008-02-23 18:41:37 +00002149static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2150{
Scott Michel266bc8f2007-12-04 22:23:35 +00002151 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2152
2153 assert(Op.getValueType() == MVT::i8);
2154 switch (Opc) {
2155 default:
2156 assert(0 && "Unhandled i8 math operator");
2157 /*NOTREACHED*/
2158 break;
2159 case ISD::SUB: {
2160 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2161 // the result:
2162 SDOperand N1 = Op.getOperand(1);
2163 N0 = (N0.getOpcode() != ISD::Constant
2164 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2165 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2166 N1 = (N1.getOpcode() != ISD::Constant
2167 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2168 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2169 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2170 DAG.getNode(Opc, MVT::i16, N0, N1));
2171 }
2172 case ISD::ROTR:
2173 case ISD::ROTL: {
2174 SDOperand N1 = Op.getOperand(1);
2175 unsigned N1Opc;
2176 N0 = (N0.getOpcode() != ISD::Constant
2177 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2178 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2179 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2180 N1 = (N1.getOpcode() != ISD::Constant
2181 ? DAG.getNode(N1Opc, MVT::i16, N1)
2182 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2183 SDOperand ExpandArg =
2184 DAG.getNode(ISD::OR, MVT::i16, N0,
2185 DAG.getNode(ISD::SHL, MVT::i16,
2186 N0, DAG.getConstant(8, MVT::i16)));
2187 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2188 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2189 }
2190 case ISD::SRL:
2191 case ISD::SHL: {
2192 SDOperand N1 = Op.getOperand(1);
2193 unsigned N1Opc;
2194 N0 = (N0.getOpcode() != ISD::Constant
2195 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2196 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2197 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::ZERO_EXTEND : ISD::TRUNCATE);
2198 N1 = (N1.getOpcode() != ISD::Constant
2199 ? DAG.getNode(N1Opc, MVT::i16, N1)
2200 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2201 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2202 DAG.getNode(Opc, MVT::i16, N0, N1));
2203 }
2204 case ISD::SRA: {
2205 SDOperand N1 = Op.getOperand(1);
2206 unsigned N1Opc;
2207 N0 = (N0.getOpcode() != ISD::Constant
2208 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2209 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2210 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2211 N1 = (N1.getOpcode() != ISD::Constant
2212 ? DAG.getNode(N1Opc, MVT::i16, N1)
2213 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2214 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2215 DAG.getNode(Opc, MVT::i16, N0, N1));
2216 }
2217 case ISD::MUL: {
2218 SDOperand N1 = Op.getOperand(1);
2219 unsigned N1Opc;
2220 N0 = (N0.getOpcode() != ISD::Constant
2221 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2222 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2223 N1Opc = (N1.getValueType() < MVT::i16 ? ISD::SIGN_EXTEND : ISD::TRUNCATE);
2224 N1 = (N1.getOpcode() != ISD::Constant
2225 ? DAG.getNode(N1Opc, MVT::i16, N1)
2226 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2227 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2228 DAG.getNode(Opc, MVT::i16, N0, N1));
2229 break;
2230 }
2231 }
2232
2233 return SDOperand();
2234}
2235
Scott Michela59d4692008-02-23 18:41:37 +00002236static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2237{
2238 MVT::ValueType VT = Op.getValueType();
2239 unsigned VecVT =
2240 MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2241
2242 SDOperand Op0 = Op.getOperand(0);
2243
2244 switch (Opc) {
2245 case ISD::ZERO_EXTEND:
2246 case ISD::SIGN_EXTEND:
2247 case ISD::ANY_EXTEND: {
2248 MVT::ValueType Op0VT = Op0.getValueType();
2249 unsigned Op0VecVT =
2250 MVT::getVectorType(Op0VT, (128 / MVT::getSizeInBits(Op0VT)));
2251
2252 assert(Op0VT == MVT::i32
2253 && "CellSPU: Zero/sign extending something other than i32");
2254
2255 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2256 ? SPUISD::ROTBYTES_RIGHT_S
2257 : SPUISD::ROTQUAD_RZ_BYTES);
2258 SDOperand PromoteScalar =
2259 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2260
2261 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2262 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2263 DAG.getNode(NewOpc, Op0VecVT,
2264 PromoteScalar,
2265 DAG.getConstant(4, MVT::i32))));
2266 }
2267
2268 case ISD::SHL: {
2269 SDOperand ShiftAmt = Op.getOperand(1);
2270 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2271 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2272 SDOperand MaskLower =
2273 DAG.getNode(SPUISD::SELB, VecVT,
2274 Op0Vec,
2275 DAG.getConstant(0, VecVT),
2276 DAG.getNode(SPUISD::FSMBI, VecVT,
2277 DAG.getConstant(0xff00ULL, MVT::i16)));
2278 SDOperand ShiftAmtBytes =
2279 DAG.getNode(ISD::SRL, ShiftAmtVT,
2280 ShiftAmt,
2281 DAG.getConstant(3, ShiftAmtVT));
2282 SDOperand ShiftAmtBits =
2283 DAG.getNode(ISD::AND, ShiftAmtVT,
2284 ShiftAmt,
2285 DAG.getConstant(7, ShiftAmtVT));
2286
2287 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2288 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2289 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2290 MaskLower, ShiftAmtBytes),
2291 ShiftAmtBits));
2292 }
2293
2294 case ISD::SRL: {
2295 unsigned VT = unsigned(Op.getValueType());
2296 SDOperand ShiftAmt = Op.getOperand(1);
2297 unsigned ShiftAmtVT = unsigned(ShiftAmt.getValueType());
2298 SDOperand ShiftAmtBytes =
2299 DAG.getNode(ISD::SRL, ShiftAmtVT,
2300 ShiftAmt,
2301 DAG.getConstant(3, ShiftAmtVT));
2302 SDOperand ShiftAmtBits =
2303 DAG.getNode(ISD::AND, ShiftAmtVT,
2304 ShiftAmt,
2305 DAG.getConstant(7, ShiftAmtVT));
2306
2307 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2308 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2309 Op0, ShiftAmtBytes),
2310 ShiftAmtBits);
2311 }
2312 }
2313
2314 return SDOperand();
2315}
2316
Scott Michel266bc8f2007-12-04 22:23:35 +00002317//! Lower byte immediate operations for v16i8 vectors:
2318static SDOperand
2319LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2320 SDOperand ConstVec;
2321 SDOperand Arg;
2322 MVT::ValueType VT = Op.getValueType();
2323
2324 ConstVec = Op.getOperand(0);
2325 Arg = Op.getOperand(1);
2326 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2327 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2328 ConstVec = ConstVec.getOperand(0);
2329 } else {
2330 ConstVec = Op.getOperand(1);
2331 Arg = Op.getOperand(0);
2332 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002333 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002334 }
2335 }
2336 }
2337
2338 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2339 uint64_t VectorBits[2];
2340 uint64_t UndefBits[2];
2341 uint64_t SplatBits, SplatUndef;
2342 int SplatSize;
2343
2344 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002345 && isConstantSplat(VectorBits, UndefBits,
2346 MVT::getSizeInBits(MVT::getVectorElementType(VT)),
2347 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002348 SDOperand tcVec[16];
2349 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2350 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2351
2352 // Turn the BUILD_VECTOR into a set of target constants:
2353 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002354 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002355
2356 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002357 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002358 }
2359 }
2360
2361 return SDOperand();
2362}
2363
2364//! Lower i32 multiplication
2365static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, unsigned VT,
2366 unsigned Opc) {
2367 switch (VT) {
2368 default:
2369 cerr << "CellSPU: Unknown LowerMUL value type, got "
2370 << MVT::getValueTypeString(Op.getValueType())
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002371 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002372 abort();
2373 /*NOTREACHED*/
2374
2375 case MVT::i32: {
2376 SDOperand rA = Op.getOperand(0);
2377 SDOperand rB = Op.getOperand(1);
2378
2379 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002380 DAG.getNode(ISD::ADD, MVT::i32,
2381 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2382 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2383 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002384 }
2385 }
2386
2387 return SDOperand();
2388}
2389
2390//! Custom lowering for CTPOP (count population)
2391/*!
2392 Custom lowering code that counts the number ones in the input
2393 operand. SPU has such an instruction, but it counts the number of
2394 ones per byte, which then have to be accumulated.
2395*/
2396static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
2397 unsigned VT = Op.getValueType();
2398 unsigned vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
2399
2400 switch (VT) {
2401 case MVT::i8: {
2402 SDOperand N = Op.getOperand(0);
2403 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2404
2405 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2406 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2407
2408 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2409 }
2410
2411 case MVT::i16: {
2412 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002413 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002414
Chris Lattner84bc5422007-12-31 04:13:23 +00002415 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002416
2417 SDOperand N = Op.getOperand(0);
2418 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2419 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2420 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2421
2422 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2423 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2424
2425 // CNTB_result becomes the chain to which all of the virtual registers
2426 // CNTB_reg, SUM1_reg become associated:
2427 SDOperand CNTB_result =
2428 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002429
Scott Michel266bc8f2007-12-04 22:23:35 +00002430 SDOperand CNTB_rescopy =
2431 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2432
2433 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2434
2435 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002436 DAG.getNode(ISD::ADD, MVT::i16,
2437 DAG.getNode(ISD::SRL, MVT::i16,
2438 Tmp1, Shift1),
2439 Tmp1),
2440 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002441 }
2442
2443 case MVT::i32: {
2444 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002445 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002446
Chris Lattner84bc5422007-12-31 04:13:23 +00002447 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2448 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002449
2450 SDOperand N = Op.getOperand(0);
2451 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2452 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2453 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2454 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2455
2456 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2457 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2458
2459 // CNTB_result becomes the chain to which all of the virtual registers
2460 // CNTB_reg, SUM1_reg become associated:
2461 SDOperand CNTB_result =
2462 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002463
Scott Michel266bc8f2007-12-04 22:23:35 +00002464 SDOperand CNTB_rescopy =
2465 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2466
2467 SDOperand Comp1 =
2468 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002469 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002470
2471 SDOperand Sum1 =
2472 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002473 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002474
2475 SDOperand Sum1_rescopy =
2476 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2477
2478 SDOperand Comp2 =
2479 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002480 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2481 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002482 SDOperand Sum2 =
2483 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002484 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002485
2486 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2487 }
2488
2489 case MVT::i64:
2490 break;
2491 }
2492
2493 return SDOperand();
2494}
2495
2496/// LowerOperation - Provide custom lowering hooks for some operations.
2497///
2498SDOperand
2499SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2500{
Scott Michela59d4692008-02-23 18:41:37 +00002501 unsigned Opc = (unsigned) Op.getOpcode();
2502 unsigned VT = (unsigned) Op.getValueType();
2503
2504 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002505 default: {
2506 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002507 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002508 cerr << "*Op.Val:\n";
2509 Op.Val->dump();
2510 abort();
2511 }
2512 case ISD::LOAD:
2513 case ISD::SEXTLOAD:
2514 case ISD::ZEXTLOAD:
2515 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2516 case ISD::STORE:
2517 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2518 case ISD::ConstantPool:
2519 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2520 case ISD::GlobalAddress:
2521 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2522 case ISD::JumpTable:
2523 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2524 case ISD::Constant:
2525 return LowerConstant(Op, DAG);
2526 case ISD::ConstantFP:
2527 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002528 case ISD::BRCOND:
2529 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002530 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002531 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002532 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002533 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002534 case ISD::RET:
2535 return LowerRET(Op, DAG, getTargetMachine());
2536
Scott Michela59d4692008-02-23 18:41:37 +00002537
2538 // i8, i64 math ops:
2539 case ISD::ZERO_EXTEND:
2540 case ISD::SIGN_EXTEND:
2541 case ISD::ANY_EXTEND:
Scott Michel266bc8f2007-12-04 22:23:35 +00002542 case ISD::SUB:
2543 case ISD::ROTR:
2544 case ISD::ROTL:
2545 case ISD::SRL:
2546 case ISD::SHL:
2547 case ISD::SRA:
Scott Michela59d4692008-02-23 18:41:37 +00002548 if (VT == MVT::i8)
2549 return LowerI8Math(Op, DAG, Opc);
2550 else if (VT == MVT::i64)
2551 return LowerI64Math(Op, DAG, Opc);
2552 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00002553
2554 // Vector-related lowering.
2555 case ISD::BUILD_VECTOR:
2556 return LowerBUILD_VECTOR(Op, DAG);
2557 case ISD::SCALAR_TO_VECTOR:
2558 return LowerSCALAR_TO_VECTOR(Op, DAG);
2559 case ISD::VECTOR_SHUFFLE:
2560 return LowerVECTOR_SHUFFLE(Op, DAG);
2561 case ISD::EXTRACT_VECTOR_ELT:
2562 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2563 case ISD::INSERT_VECTOR_ELT:
2564 return LowerINSERT_VECTOR_ELT(Op, DAG);
2565
2566 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2567 case ISD::AND:
2568 case ISD::OR:
2569 case ISD::XOR:
2570 return LowerByteImmed(Op, DAG);
2571
2572 // Vector and i8 multiply:
2573 case ISD::MUL:
Scott Michela59d4692008-02-23 18:41:37 +00002574 if (MVT::isVector(VT))
Scott Michel266bc8f2007-12-04 22:23:35 +00002575 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002576 else if (VT == MVT::i8)
2577 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002578 else
Scott Michela59d4692008-02-23 18:41:37 +00002579 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002580
2581 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002582 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002583 return LowerFDIVf32(Op, DAG);
2584// else if (Op.getValueType() == MVT::f64)
2585// return LowerFDIVf64(Op, DAG);
2586 else
2587 assert(0 && "Calling FDIV on unsupported MVT");
2588
2589 case ISD::CTPOP:
2590 return LowerCTPOP(Op, DAG);
2591 }
2592
2593 return SDOperand();
2594}
2595
2596//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002597// Target Optimization Hooks
2598//===----------------------------------------------------------------------===//
2599
2600SDOperand
2601SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2602{
2603#if 0
2604 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002605#endif
2606 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002607 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002608 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2609 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002610
2611 switch (N->getOpcode()) {
2612 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002613 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002614 SDOperand Op1 = N->getOperand(1);
2615
2616 if ((Op1.getOpcode() == ISD::Constant
2617 || Op1.getOpcode() == ISD::TargetConstant)
2618 && Op0.getOpcode() == SPUISD::IndirectAddr) {
2619 SDOperand Op01 = Op0.getOperand(1);
2620 if (Op01.getOpcode() == ISD::Constant
2621 || Op01.getOpcode() == ISD::TargetConstant) {
2622 // (add <const>, (SPUindirect <arg>, <const>)) ->
2623 // (SPUindirect <arg>, <const + const>)
2624 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2625 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2626 SDOperand combinedConst =
2627 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2628 Op0.getValueType());
2629
2630 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2631 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2632 DEBUG(cerr << "With: (SPUindirect <arg>, "
2633 << CN0->getValue() + CN1->getValue() << ")\n");
2634 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2635 Op0.getOperand(0), combinedConst);
2636 }
2637 } else if ((Op0.getOpcode() == ISD::Constant
2638 || Op0.getOpcode() == ISD::TargetConstant)
2639 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2640 SDOperand Op11 = Op1.getOperand(1);
2641 if (Op11.getOpcode() == ISD::Constant
2642 || Op11.getOpcode() == ISD::TargetConstant) {
2643 // (add (SPUindirect <arg>, <const>), <const>) ->
2644 // (SPUindirect <arg>, <const + const>)
2645 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2646 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2647 SDOperand combinedConst =
2648 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2649 Op0.getValueType());
2650
2651 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2652 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2653 DEBUG(cerr << "With: (SPUindirect <arg>, "
2654 << CN0->getValue() + CN1->getValue() << ")\n");
2655
2656 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2657 Op1.getOperand(0), combinedConst);
2658 }
2659 }
Scott Michela59d4692008-02-23 18:41:37 +00002660 break;
2661 }
2662 case ISD::SIGN_EXTEND:
2663 case ISD::ZERO_EXTEND:
2664 case ISD::ANY_EXTEND: {
2665 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2666 N->getValueType(0) == Op0.getValueType()) {
2667 // (any_extend (SPUextract_elt0 <arg>)) ->
2668 // (SPUextract_elt0 <arg>)
2669 // Types must match, however...
2670 DEBUG(cerr << "Replace: ");
2671 DEBUG(N->dump(&DAG));
2672 DEBUG(cerr << "\nWith: ");
2673 DEBUG(Op0.Val->dump(&DAG));
2674 DEBUG(cerr << "\n");
2675
2676 return Op0;
2677 }
2678 break;
2679 }
2680 case SPUISD::IndirectAddr: {
2681 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2682 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2683 if (CN->getValue() == 0) {
2684 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2685 // (SPUaform <addr>, 0)
2686
2687 DEBUG(cerr << "Replace: ");
2688 DEBUG(N->dump(&DAG));
2689 DEBUG(cerr << "\nWith: ");
2690 DEBUG(Op0.Val->dump(&DAG));
2691 DEBUG(cerr << "\n");
2692
2693 return Op0;
2694 }
2695 }
2696 break;
2697 }
2698 case SPUISD::SHLQUAD_L_BITS:
2699 case SPUISD::SHLQUAD_L_BYTES:
2700 case SPUISD::VEC_SHL:
2701 case SPUISD::VEC_SRL:
2702 case SPUISD::VEC_SRA:
2703 case SPUISD::ROTQUAD_RZ_BYTES:
2704 case SPUISD::ROTQUAD_RZ_BITS: {
2705 SDOperand Op1 = N->getOperand(1);
2706
2707 if (isa<ConstantSDNode>(Op1)) {
2708 // Kill degenerate vector shifts:
2709 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2710
2711 if (CN->getValue() == 0) {
2712 Result = Op0;
2713 }
2714 }
2715 break;
2716 }
2717 case SPUISD::PROMOTE_SCALAR: {
2718 switch (Op0.getOpcode()) {
2719 default:
2720 break;
2721 case ISD::ANY_EXTEND:
2722 case ISD::ZERO_EXTEND:
2723 case ISD::SIGN_EXTEND: {
2724 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2725 // <arg>
2726 // but only if the SPUpromote_scalar and <arg> types match.
2727 SDOperand Op00 = Op0.getOperand(0);
2728 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2729 SDOperand Op000 = Op00.getOperand(0);
2730 if (Op000.getValueType() == N->getValueType(0)) {
2731 Result = Op000;
2732 }
2733 }
2734 break;
2735 }
2736 case SPUISD::EXTRACT_ELT0: {
2737 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2738 // <arg>
2739 Result = Op0.getOperand(0);
2740 break;
2741 }
2742 }
2743 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002744 }
2745 }
Scott Michel58c58182008-01-17 20:38:41 +00002746 // Otherwise, return unchanged.
Scott Michela59d4692008-02-23 18:41:37 +00002747#if 0
2748 if (Result.Val) {
2749 DEBUG(cerr << "\nReplace.SPU: ");
2750 DEBUG(N->dump(&DAG));
2751 DEBUG(cerr << "\nWith: ");
2752 DEBUG(Result.Val->dump(&DAG));
2753 DEBUG(cerr << "\n");
2754 }
2755#endif
2756
2757 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002758}
2759
2760//===----------------------------------------------------------------------===//
2761// Inline Assembly Support
2762//===----------------------------------------------------------------------===//
2763
2764/// getConstraintType - Given a constraint letter, return the type of
2765/// constraint it is for this target.
2766SPUTargetLowering::ConstraintType
2767SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2768 if (ConstraintLetter.size() == 1) {
2769 switch (ConstraintLetter[0]) {
2770 default: break;
2771 case 'b':
2772 case 'r':
2773 case 'f':
2774 case 'v':
2775 case 'y':
2776 return C_RegisterClass;
2777 }
2778 }
2779 return TargetLowering::getConstraintType(ConstraintLetter);
2780}
2781
2782std::pair<unsigned, const TargetRegisterClass*>
2783SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
2784 MVT::ValueType VT) const
2785{
2786 if (Constraint.size() == 1) {
2787 // GCC RS6000 Constraint Letters
2788 switch (Constraint[0]) {
2789 case 'b': // R1-R31
2790 case 'r': // R0-R31
2791 if (VT == MVT::i64)
2792 return std::make_pair(0U, SPU::R64CRegisterClass);
2793 return std::make_pair(0U, SPU::R32CRegisterClass);
2794 case 'f':
2795 if (VT == MVT::f32)
2796 return std::make_pair(0U, SPU::R32FPRegisterClass);
2797 else if (VT == MVT::f64)
2798 return std::make_pair(0U, SPU::R64FPRegisterClass);
2799 break;
2800 case 'v':
2801 return std::make_pair(0U, SPU::GPRCRegisterClass);
2802 }
2803 }
2804
2805 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2806}
2807
Scott Michela59d4692008-02-23 18:41:37 +00002808//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002809void
2810SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002811 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002812 APInt &KnownZero,
2813 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002814 const SelectionDAG &DAG,
2815 unsigned Depth ) const {
Scott Michela59d4692008-02-23 18:41:37 +00002816 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
2817
2818 switch (Op.getOpcode()) {
2819 default:
2820 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2821 break;
2822
2823#if 0
2824 case CALL:
2825 case SHUFB:
2826 case INSERT_MASK:
2827 case CNTB:
2828#endif
2829
2830 case SPUISD::PROMOTE_SCALAR: {
2831 SDOperand Op0 = Op.getOperand(0);
2832 uint64_t InMask = MVT::getIntVTBitMask(Op0.getValueType());
2833 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2834 KnownOne |= APInt(uint64_sizebits, InMask, false);
2835 break;
2836 }
2837
2838 case SPUISD::LDRESULT:
2839 case SPUISD::EXTRACT_ELT0:
2840 case SPUISD::EXTRACT_ELT0_CHAINED: {
2841 uint64_t InMask = MVT::getIntVTBitMask(Op.getValueType());
2842 KnownZero |= APInt(uint64_sizebits, ~InMask, false);
2843 KnownOne |= APInt(uint64_sizebits, InMask, false);
2844 break;
2845 }
2846
2847#if 0
2848 case EXTRACT_I1_ZEXT:
2849 case EXTRACT_I1_SEXT:
2850 case EXTRACT_I8_ZEXT:
2851 case EXTRACT_I8_SEXT:
2852 case MPY:
2853 case MPYU:
2854 case MPYH:
2855 case MPYHH:
2856 case SHLQUAD_L_BITS:
2857 case SHLQUAD_L_BYTES:
2858 case VEC_SHL:
2859 case VEC_SRL:
2860 case VEC_SRA:
2861 case VEC_ROTL:
2862 case VEC_ROTR:
2863 case ROTQUAD_RZ_BYTES:
2864 case ROTQUAD_RZ_BITS:
2865 case ROTBYTES_RIGHT_S:
2866 case ROTBYTES_LEFT:
2867 case ROTBYTES_LEFT_CHAINED:
2868 case FSMBI:
2869 case SELB:
2870 case SFPConstant:
2871 case FPInterp:
2872 case FPRecipEst:
2873 case SEXT32TO64:
2874#endif
2875 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002876}
2877
2878// LowerAsmOperandForConstraint
2879void
2880SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
2881 char ConstraintLetter,
2882 std::vector<SDOperand> &Ops,
2883 SelectionDAG &DAG) {
2884 // Default, for the time being, to the base class handler
2885 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
2886}
2887
2888/// isLegalAddressImmediate - Return true if the integer value can be used
2889/// as the offset of the target addressing mode.
2890bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
2891 // SPU's addresses are 256K:
2892 return (V > -(1 << 18) && V < (1 << 18) - 1);
2893}
2894
2895bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
2896 return false;
2897}