blob: 1aae24ff1fd88382905f629250094419d3d750c9 [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"
Scott Michel203b2d62008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000018#include "llvm/ADT/VectorExtras.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000019#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
Duncan Sands83ec4b62008-06-06 12:08:01 +000040 //! MVT mapping to useful data for Cell SPU
Scott Michel266bc8f2007-12-04 22:23:35 +000041 struct valtype_map_s {
Duncan Sands83ec4b62008-06-06 12:08:01 +000042 const MVT valtype;
Scott Michel7f9ba9b2008-01-30 02:55:46 +000043 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
Duncan Sands83ec4b62008-06-06 12:08:01 +000059 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel266bc8f2007-12-04 22:23:35 +000060 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 "
Duncan Sands83ec4b62008-06-06 12:08:01 +000072 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +000073 << "\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:
Scott Michel504c3692007-12-17 22:32:34 +0000125 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
126 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
127 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
128 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
129 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
130 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000131 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
132
133 // SPU has no sign or zero extended loads for i1, i8, i16:
Scott Michel58c58182008-01-17 20:38:41 +0000134 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000135 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
136 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Chris Lattnerddf89562008-01-17 19:59:44 +0000137 setTruncStoreAction(MVT::i8, MVT::i1, Custom);
138 setTruncStoreAction(MVT::i16, MVT::i1, Custom);
139 setTruncStoreAction(MVT::i32, MVT::i1, Custom);
140 setTruncStoreAction(MVT::i64, MVT::i1, Custom);
141 setTruncStoreAction(MVT::i128, MVT::i1, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000142
143 setLoadXAction(ISD::EXTLOAD, MVT::i8, Custom);
144 setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
145 setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
Chris Lattnerddf89562008-01-17 19:59:44 +0000146 setTruncStoreAction(MVT::i8 , MVT::i8, Custom);
147 setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
148 setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
149 setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
150 setTruncStoreAction(MVT::i128, MVT::i8, Custom);
151
Scott Michel266bc8f2007-12-04 22:23:35 +0000152 setLoadXAction(ISD::EXTLOAD, MVT::i16, Custom);
153 setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
154 setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
155
156 // SPU constant load actions are custom lowered:
157 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000158 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000159 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
160
161 // SPU's loads and stores have to be custom lowered:
162 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
163 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000164 MVT VT = (MVT::SimpleValueType)sctype;
165
166 setOperationAction(ISD::LOAD, VT, Custom);
167 setOperationAction(ISD::STORE, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000168 }
169
Scott Michel58c58182008-01-17 20:38:41 +0000170 // Custom lower BRCOND for i1, i8 to "promote" the result to
171 // i32 and i16, respectively.
172 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000173
174 // Expand the jumptable branches
175 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
176 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
177 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
178
179 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000180 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
181
Scott Michel266bc8f2007-12-04 22:23:35 +0000182 // PowerPC has no SREM/UREM instructions
183 setOperationAction(ISD::SREM, MVT::i32, Expand);
184 setOperationAction(ISD::UREM, MVT::i32, Expand);
185 setOperationAction(ISD::SREM, MVT::i64, Expand);
186 setOperationAction(ISD::UREM, MVT::i64, Expand);
187
188 // We don't support sin/cos/sqrt/fmod
189 setOperationAction(ISD::FSIN , MVT::f64, Expand);
190 setOperationAction(ISD::FCOS , MVT::f64, Expand);
191 setOperationAction(ISD::FREM , MVT::f64, Expand);
192 setOperationAction(ISD::FSIN , MVT::f32, Expand);
193 setOperationAction(ISD::FCOS , MVT::f32, Expand);
194 setOperationAction(ISD::FREM , MVT::f32, Expand);
195
196 // If we're enabling GP optimizations, use hardware square root
197 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
198 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
199
200 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
201 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
202
203 // SPU can do rotate right and left, so legalize it... but customize for i8
204 // because instructions don't exist.
205 setOperationAction(ISD::ROTR, MVT::i32, Legal);
206 setOperationAction(ISD::ROTR, MVT::i16, Legal);
207 setOperationAction(ISD::ROTR, MVT::i8, Custom);
208 setOperationAction(ISD::ROTL, MVT::i32, Legal);
209 setOperationAction(ISD::ROTL, MVT::i16, Legal);
210 setOperationAction(ISD::ROTL, MVT::i8, Custom);
211 // SPU has no native version of shift left/right for i8
212 setOperationAction(ISD::SHL, MVT::i8, Custom);
213 setOperationAction(ISD::SRL, MVT::i8, Custom);
214 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michela59d4692008-02-23 18:41:37 +0000215 // And SPU needs custom lowering for shift left/right for i64
216 setOperationAction(ISD::SHL, MVT::i64, Custom);
217 setOperationAction(ISD::SRL, MVT::i64, Custom);
218 setOperationAction(ISD::SRA, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000219
220 // Custom lower i32 multiplications
221 setOperationAction(ISD::MUL, MVT::i32, Custom);
222
Scott Michel8bf61e82008-06-02 22:18:03 +0000223 // Need to custom handle (some) common i8, i64 math ops
224 setOperationAction(ISD::ADD, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000225 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel8bf61e82008-06-02 22:18:03 +0000226 setOperationAction(ISD::SUB, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000227 setOperationAction(ISD::MUL, MVT::i8, Custom);
228
229 // SPU does not have BSWAP. It does have i32 support CTLZ.
230 // CTPOP has to be custom lowered.
231 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
232 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
233
234 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
235 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
236 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
237 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
238
239 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
240 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
241
242 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
243
Scott Michel8bf61e82008-06-02 22:18:03 +0000244 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000245 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000246 setOperationAction(ISD::SELECT, MVT::i1, Promote);
247 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000248 setOperationAction(ISD::SELECT, MVT::i16, Legal);
249 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000250 setOperationAction(ISD::SELECT, MVT::i64, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000251
Scott Michel78c47fa2008-03-10 16:58:52 +0000252 setOperationAction(ISD::SETCC, MVT::i1, Promote);
253 setOperationAction(ISD::SETCC, MVT::i8, Legal);
254 setOperationAction(ISD::SETCC, MVT::i16, Legal);
255 setOperationAction(ISD::SETCC, MVT::i32, Legal);
256 setOperationAction(ISD::SETCC, MVT::i64, Expand);
Scott Michelad2715e2008-03-05 23:02:02 +0000257
Scott Michela59d4692008-02-23 18:41:37 +0000258 // Zero extension and sign extension for i64 have to be
259 // custom legalized
260 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
261 setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
262 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000263
264 // SPU has a legal FP -> signed INT instruction
265 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
266 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
267 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
268 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
269
270 // FDIV on SPU requires custom lowering
271 setOperationAction(ISD::FDIV, MVT::f32, Custom);
272 //setOperationAction(ISD::FDIV, MVT::f64, Custom);
273
274 // SPU has [U|S]INT_TO_FP
275 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
276 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
277 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
278 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
279 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
280 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
281 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
282 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
283
Scott Michel86c041f2007-12-20 00:44:13 +0000284 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
285 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
286 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
287 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000288
289 // We cannot sextinreg(i1). Expand to shifts.
290 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
291
292 // Support label based line numbers.
Dan Gohman7f460202008-06-30 20:59:49 +0000293 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000294 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
295
296 // We want to legalize GlobalAddress and ConstantPool nodes into the
297 // appropriate instructions to materialize the address.
Scott Michel053c1da2008-01-29 02:16:57 +0000298 for (unsigned sctype = (unsigned) MVT::i1; sctype < (unsigned) MVT::f128;
299 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000300 MVT VT = (MVT::SimpleValueType)sctype;
301
302 setOperationAction(ISD::GlobalAddress, VT, Custom);
303 setOperationAction(ISD::ConstantPool, VT, Custom);
304 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michel053c1da2008-01-29 02:16:57 +0000305 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000306
307 // RET must be custom lowered, to meet ABI requirements
308 setOperationAction(ISD::RET, MVT::Other, Custom);
309
310 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
311 setOperationAction(ISD::VASTART , MVT::Other, Custom);
312
313 // Use the default implementation.
314 setOperationAction(ISD::VAARG , MVT::Other, Expand);
315 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
316 setOperationAction(ISD::VAEND , MVT::Other, Expand);
317 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
318 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
319 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
320 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
321
322 // Cell SPU has instructions for converting between i64 and fp.
323 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
324 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
325
326 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
327 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
328
329 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
330 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
331
332 // First set operation action for all vector types to expand. Then we
333 // will selectively turn on ones that can be effectively codegen'd.
334 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
335 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
336 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
337 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
338 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
339 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
340
Duncan Sands83ec4b62008-06-06 12:08:01 +0000341 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
342 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
343 MVT VT = (MVT::SimpleValueType)i;
Scott Michel266bc8f2007-12-04 22:23:35 +0000344
Duncan Sands83ec4b62008-06-06 12:08:01 +0000345 // add/sub are legal for all supported vector VT's.
346 setOperationAction(ISD::ADD , VT, Legal);
347 setOperationAction(ISD::SUB , VT, Legal);
348 // mul has to be custom lowered.
349 setOperationAction(ISD::MUL , VT, Custom);
350
351 setOperationAction(ISD::AND , VT, Legal);
352 setOperationAction(ISD::OR , VT, Legal);
353 setOperationAction(ISD::XOR , VT, Legal);
354 setOperationAction(ISD::LOAD , VT, Legal);
355 setOperationAction(ISD::SELECT, VT, Legal);
356 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000357
358 // These operations need to be expanded:
Duncan Sands83ec4b62008-06-06 12:08:01 +0000359 setOperationAction(ISD::SDIV, VT, Expand);
360 setOperationAction(ISD::SREM, VT, Expand);
361 setOperationAction(ISD::UDIV, VT, Expand);
362 setOperationAction(ISD::UREM, VT, Expand);
363 setOperationAction(ISD::FDIV, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000364
365 // Custom lower build_vector, constant pool spills, insert and
366 // extract vector elements:
Duncan Sands83ec4b62008-06-06 12:08:01 +0000367 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
368 setOperationAction(ISD::ConstantPool, VT, Custom);
369 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
370 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
371 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
372 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000373 }
374
375 setOperationAction(ISD::MUL, MVT::v16i8, Custom);
376 setOperationAction(ISD::AND, MVT::v16i8, Custom);
377 setOperationAction(ISD::OR, MVT::v16i8, Custom);
378 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
379 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000380
Scott Michel266bc8f2007-12-04 22:23:35 +0000381 setShiftAmountType(MVT::i32);
382 setSetCCResultContents(ZeroOrOneSetCCResult);
383
384 setStackPointerRegisterToSaveRestore(SPU::R1);
385
386 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000387 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000388 setTargetDAGCombine(ISD::ZERO_EXTEND);
389 setTargetDAGCombine(ISD::SIGN_EXTEND);
390 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel266bc8f2007-12-04 22:23:35 +0000391
392 computeRegisterProperties();
393}
394
395const char *
396SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
397{
398 if (node_names.empty()) {
399 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
400 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
401 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
402 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000403 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000404 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000405 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
406 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
407 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
408 node_names[(unsigned) SPUISD::INSERT_MASK] = "SPUISD::INSERT_MASK";
409 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
410 node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR";
411 node_names[(unsigned) SPUISD::EXTRACT_ELT0] = "SPUISD::EXTRACT_ELT0";
412 node_names[(unsigned) SPUISD::EXTRACT_ELT0_CHAINED] = "SPUISD::EXTRACT_ELT0_CHAINED";
413 node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT";
414 node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT";
415 node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT";
416 node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT";
417 node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY";
418 node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU";
419 node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH";
420 node_names[(unsigned) SPUISD::MPYHH] = "SPUISD::MPYHH";
Scott Michela59d4692008-02-23 18:41:37 +0000421 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
422 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000423 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
424 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
425 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
426 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
427 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michela59d4692008-02-23 18:41:37 +0000428 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BYTES] =
429 "SPUISD::ROTQUAD_RZ_BYTES";
430 node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] =
431 "SPUISD::ROTQUAD_RZ_BITS";
Scott Michel266bc8f2007-12-04 22:23:35 +0000432 node_names[(unsigned) SPUISD::ROTBYTES_RIGHT_S] =
433 "SPUISD::ROTBYTES_RIGHT_S";
434 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
435 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] =
436 "SPUISD::ROTBYTES_LEFT_CHAINED";
Scott Michel8bf61e82008-06-02 22:18:03 +0000437 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
438 "SPUISD::ROTBYTES_LEFT_BITS";
439 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000440 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel8bf61e82008-06-02 22:18:03 +0000441 node_names[(unsigned) SPUISD::ADD_EXTENDED] = "SPUISD::ADD_EXTENDED";
442 node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
443 node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
444 node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
Scott Michel266bc8f2007-12-04 22:23:35 +0000445 node_names[(unsigned) SPUISD::FPInterp] = "SPUISD::FPInterp";
446 node_names[(unsigned) SPUISD::FPRecipEst] = "SPUISD::FPRecipEst";
447 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
448 }
449
450 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
451
452 return ((i != node_names.end()) ? i->second : 0);
453}
454
Duncan Sands83ec4b62008-06-06 12:08:01 +0000455MVT SPUTargetLowering::getSetCCResultType(const SDOperand &Op) const {
456 MVT VT = Op.getValueType();
457 if (VT.isInteger())
Scott Michel405fba12008-03-10 23:49:09 +0000458 return VT;
459 else
460 return MVT::i32;
Scott Michel78c47fa2008-03-10 16:58:52 +0000461}
462
Scott Michel266bc8f2007-12-04 22:23:35 +0000463//===----------------------------------------------------------------------===//
464// Calling convention code:
465//===----------------------------------------------------------------------===//
466
467#include "SPUGenCallingConv.inc"
468
469//===----------------------------------------------------------------------===//
470// LowerOperation implementation
471//===----------------------------------------------------------------------===//
472
Scott Michel9de5d0d2008-01-11 02:53:15 +0000473/// Aligned load common code for CellSPU
474/*!
475 \param[in] Op The SelectionDAG load or store operand
476 \param[in] DAG The selection DAG
477 \param[in] ST CellSPU subtarget information structure
478 \param[in,out] alignment Caller initializes this to the load or store node's
479 value from getAlignment(), may be updated while generating the aligned load
480 \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
481 offset (divisible by 16, modulo 16 == 0)
482 \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
483 offset of the preferred slot (modulo 16 != 0)
484 \param[in,out] VT Caller initializes this value type to the the load or store
485 node's loaded or stored value type; may be updated if an i1-extended load or
486 store.
487 \param[out] was16aligned true if the base pointer had 16-byte alignment,
488 otherwise false. Can help to determine if the chunk needs to be rotated.
489
490 Both load and store lowering load a block of data aligned on a 16-byte
491 boundary. This is the common aligned load code shared between both.
492 */
493static SDOperand
494AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
495 LSBaseSDNode *LSN,
496 unsigned &alignment, int &alignOffs, int &prefSlotOffs,
Duncan Sands83ec4b62008-06-06 12:08:01 +0000497 MVT &VT, bool &was16aligned)
Scott Michel9de5d0d2008-01-11 02:53:15 +0000498{
Duncan Sands83ec4b62008-06-06 12:08:01 +0000499 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000500 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
501 SDOperand basePtr = LSN->getBasePtr();
502 SDOperand chain = LSN->getChain();
503
504 if (basePtr.getOpcode() == ISD::ADD) {
505 SDOperand Op1 = basePtr.Val->getOperand(1);
506
507 if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
Scott Michel58c58182008-01-17 20:38:41 +0000508 const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.getOperand(1));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000509
510 alignOffs = (int) CN->getValue();
511 prefSlotOffs = (int) (alignOffs & 0xf);
512
513 // Adjust the rotation amount to ensure that the final result ends up in
514 // the preferred slot:
515 prefSlotOffs -= vtm->prefslot_byte;
516 basePtr = basePtr.getOperand(0);
517
Scott Michel58c58182008-01-17 20:38:41 +0000518 // Loading from memory, can we adjust alignment?
519 if (basePtr.getOpcode() == SPUISD::AFormAddr) {
520 SDOperand APtr = basePtr.getOperand(0);
521 if (APtr.getOpcode() == ISD::TargetGlobalAddress) {
522 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(APtr);
523 alignment = GSDN->getGlobal()->getAlignment();
524 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000525 }
526 } else {
527 alignOffs = 0;
528 prefSlotOffs = -vtm->prefslot_byte;
529 }
Scott Michel203b2d62008-04-30 00:30:08 +0000530 } else if (basePtr.getOpcode() == ISD::FrameIndex) {
531 FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(basePtr);
532 alignOffs = int(FIN->getIndex() * SPUFrameInfo::stackSlotSize());
533 prefSlotOffs = (int) (alignOffs & 0xf);
534 prefSlotOffs -= vtm->prefslot_byte;
535 basePtr = DAG.getRegister(SPU::R1, VT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000536 } else {
537 alignOffs = 0;
538 prefSlotOffs = -vtm->prefslot_byte;
539 }
540
541 if (alignment == 16) {
542 // Realign the base pointer as a D-Form address:
543 if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
Scott Michel58c58182008-01-17 20:38:41 +0000544 basePtr = DAG.getNode(ISD::ADD, PtrVT,
545 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000546 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000547 }
548
549 // Emit the vector load:
550 was16aligned = true;
551 return DAG.getLoad(MVT::v16i8, chain, basePtr,
552 LSN->getSrcValue(), LSN->getSrcValueOffset(),
553 LSN->isVolatile(), 16);
554 }
555
556 // Unaligned load or we're using the "large memory" model, which means that
557 // we have to be very pessimistic:
Scott Michel58c58182008-01-17 20:38:41 +0000558 if (isMemoryOperand(basePtr) || isIndirectOperand(basePtr)) {
Scott Michel053c1da2008-01-29 02:16:57 +0000559 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000560 }
561
562 // Add the offset
Scott Michel053c1da2008-01-29 02:16:57 +0000563 basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000564 DAG.getConstant((alignOffs & ~0xf), PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000565 was16aligned = false;
566 return DAG.getLoad(MVT::v16i8, chain, basePtr,
567 LSN->getSrcValue(), LSN->getSrcValueOffset(),
568 LSN->isVolatile(), 16);
569}
570
Scott Michel266bc8f2007-12-04 22:23:35 +0000571/// Custom lower loads for CellSPU
572/*!
573 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
574 within a 16-byte block, we have to rotate to extract the requested element.
575 */
576static SDOperand
577LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
578 LoadSDNode *LN = cast<LoadSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +0000579 SDOperand the_chain = LN->getChain();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000580 MVT VT = LN->getMemoryVT();
581 MVT OpVT = Op.Val->getValueType(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000582 ISD::LoadExtType ExtType = LN->getExtensionType();
583 unsigned alignment = LN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000584 SDOperand Ops[8];
585
Scott Michel266bc8f2007-12-04 22:23:35 +0000586 switch (LN->getAddressingMode()) {
587 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000588 int offset, rotamt;
589 bool was16aligned;
590 SDOperand result =
591 AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000592
Scott Michel9de5d0d2008-01-11 02:53:15 +0000593 if (result.Val == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +0000594 return result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000595
596 the_chain = result.getValue(1);
597 // Rotate the chunk if necessary
598 if (rotamt < 0)
599 rotamt += 16;
Scott Michel497e8882008-01-11 21:01:19 +0000600 if (rotamt != 0 || !was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000601 SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
602
Scott Michel58c58182008-01-17 20:38:41 +0000603 Ops[0] = the_chain;
604 Ops[1] = result;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000605 if (was16aligned) {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000606 Ops[2] = DAG.getConstant(rotamt, MVT::i16);
607 } else {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000608 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000609 LoadSDNode *LN1 = cast<LoadSDNode>(result);
Scott Michel497e8882008-01-11 21:01:19 +0000610 Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000611 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000612 }
613
614 result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
615 the_chain = result.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000616 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000617
618 if (VT == OpVT || ExtType == ISD::EXTLOAD) {
619 SDVTList scalarvts;
Duncan Sands83ec4b62008-06-06 12:08:01 +0000620 MVT vecVT = MVT::v16i8;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000621
622 // Convert the loaded v16i8 vector to the appropriate vector type
623 // specified by the operand:
624 if (OpVT == VT) {
625 if (VT != MVT::i1)
Duncan Sands83ec4b62008-06-06 12:08:01 +0000626 vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000627 } else
Duncan Sands83ec4b62008-06-06 12:08:01 +0000628 vecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits()));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000629
630 Ops[0] = the_chain;
631 Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
632 scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
633 result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
634 the_chain = result.getValue(1);
635 } else {
636 // Handle the sign and zero-extending loads for i1 and i8:
637 unsigned NewOpC;
638
639 if (ExtType == ISD::SEXTLOAD) {
640 NewOpC = (OpVT == MVT::i1
641 ? SPUISD::EXTRACT_I1_SEXT
642 : SPUISD::EXTRACT_I8_SEXT);
643 } else {
644 assert(ExtType == ISD::ZEXTLOAD);
645 NewOpC = (OpVT == MVT::i1
646 ? SPUISD::EXTRACT_I1_ZEXT
647 : SPUISD::EXTRACT_I8_ZEXT);
648 }
649
650 result = DAG.getNode(NewOpC, OpVT, result);
651 }
652
653 SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000654 SDOperand retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000655 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000656 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000657 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000658
Scott Michel58c58182008-01-17 20:38:41 +0000659 result = DAG.getNode(SPUISD::LDRESULT, retvts,
660 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000661 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000662 }
663 case ISD::PRE_INC:
664 case ISD::PRE_DEC:
665 case ISD::POST_INC:
666 case ISD::POST_DEC:
667 case ISD::LAST_INDEXED_MODE:
668 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
669 "UNINDEXED\n";
670 cerr << (unsigned) LN->getAddressingMode() << "\n";
671 abort();
672 /*NOTREACHED*/
673 }
674
675 return SDOperand();
676}
677
678/// Custom lower stores for CellSPU
679/*!
680 All CellSPU stores are aligned to 16-byte boundaries, so for elements
681 within a 16-byte block, we have to generate a shuffle to insert the
682 requested element into its place, then store the resulting block.
683 */
684static SDOperand
685LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
686 StoreSDNode *SN = cast<StoreSDNode>(Op);
687 SDOperand Value = SN->getValue();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000688 MVT VT = Value.getValueType();
689 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
690 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000691 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000692
693 switch (SN->getAddressingMode()) {
694 case ISD::UNINDEXED: {
Scott Michel9de5d0d2008-01-11 02:53:15 +0000695 int chunk_offset, slot_offset;
696 bool was16aligned;
Scott Michel266bc8f2007-12-04 22:23:35 +0000697
698 // The vector type we really want to load from the 16-byte chunk, except
699 // in the case of MVT::i1, which has to be v16i8.
Duncan Sands83ec4b62008-06-06 12:08:01 +0000700 MVT vecVT, stVecVT = MVT::v16i8;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000701
Scott Michel266bc8f2007-12-04 22:23:35 +0000702 if (StVT != MVT::i1)
Duncan Sands83ec4b62008-06-06 12:08:01 +0000703 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
704 vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +0000705
Scott Michel9de5d0d2008-01-11 02:53:15 +0000706 SDOperand alignLoadVec =
707 AlignedLoad(Op, DAG, ST, SN, alignment,
708 chunk_offset, slot_offset, VT, was16aligned);
Scott Michel266bc8f2007-12-04 22:23:35 +0000709
Scott Michel9de5d0d2008-01-11 02:53:15 +0000710 if (alignLoadVec.Val == 0)
711 return alignLoadVec;
Scott Michel266bc8f2007-12-04 22:23:35 +0000712
Scott Michel9de5d0d2008-01-11 02:53:15 +0000713 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
714 SDOperand basePtr = LN->getBasePtr();
715 SDOperand the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000716 SDOperand theValue = SN->getValue();
717 SDOperand result;
718
719 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000720 && (theValue.getOpcode() == ISD::AssertZext
721 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000722 // Drill down and get the value for zero- and sign-extended
723 // quantities
724 theValue = theValue.getOperand(0);
725 }
726
Scott Michel9de5d0d2008-01-11 02:53:15 +0000727 chunk_offset &= 0xf;
Scott Michel266bc8f2007-12-04 22:23:35 +0000728
Scott Michel9de5d0d2008-01-11 02:53:15 +0000729 SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
730 SDOperand insertEltPtr;
731 SDOperand insertEltOp;
732
733 // If the base pointer is already a D-form address, then just create
734 // a new D-form address with a slot offset and the orignal base pointer.
735 // Otherwise generate a D-form address with the slot offset relative
736 // to the stack pointer, which is always aligned.
Scott Michel497e8882008-01-11 21:01:19 +0000737 DEBUG(cerr << "CellSPU LowerSTORE: basePtr = ");
738 DEBUG(basePtr.Val->dump(&DAG));
739 DEBUG(cerr << "\n");
740
Scott Michel053c1da2008-01-29 02:16:57 +0000741 if (basePtr.getOpcode() == SPUISD::IndirectAddr ||
742 (basePtr.getOpcode() == ISD::ADD
743 && basePtr.getOperand(0).getOpcode() == SPUISD::IndirectAddr)) {
Scott Michel497e8882008-01-11 21:01:19 +0000744 insertEltPtr = basePtr;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000745 } else {
Scott Michel053c1da2008-01-29 02:16:57 +0000746 insertEltPtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, insertEltOffs);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000747 }
748
749 insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
Scott Michel266bc8f2007-12-04 22:23:35 +0000750 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000751 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
752 alignLoadVec,
753 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000754
Scott Michel9de5d0d2008-01-11 02:53:15 +0000755 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000756 LN->getSrcValue(), LN->getSrcValueOffset(),
757 LN->isVolatile(), LN->getAlignment());
758
759 return result;
760 /*UNREACHED*/
761 }
762 case ISD::PRE_INC:
763 case ISD::PRE_DEC:
764 case ISD::POST_INC:
765 case ISD::POST_DEC:
766 case ISD::LAST_INDEXED_MODE:
767 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
768 "UNINDEXED\n";
769 cerr << (unsigned) SN->getAddressingMode() << "\n";
770 abort();
771 /*NOTREACHED*/
772 }
773
774 return SDOperand();
775}
776
777/// Generate the address of a constant pool entry.
778static SDOperand
779LowerConstantPool(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000780 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000781 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
782 Constant *C = CP->getConstVal();
783 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
Scott Michel266bc8f2007-12-04 22:23:35 +0000784 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000785 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000786
787 if (TM.getRelocationModel() == Reloc::Static) {
788 if (!ST->usingLargeMem()) {
789 // Just return the SDOperand with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000790 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000791 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +0000792 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
793 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000794 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000795 }
796 }
797
798 assert(0 &&
799 "LowerConstantPool: Relocation model other than static not supported.");
800 return SDOperand();
801}
802
803static SDOperand
804LowerJumpTable(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000805 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000806 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
807 SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
808 SDOperand Zero = DAG.getConstant(0, PtrVT);
809 const TargetMachine &TM = DAG.getTarget();
810
811 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000812 if (!ST->usingLargeMem()) {
813 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
814 } else {
815 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
816 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
817 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
818 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000819 }
820
821 assert(0 &&
822 "LowerJumpTable: Relocation model other than static not supported.");
823 return SDOperand();
824}
825
826static SDOperand
827LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000828 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000829 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
830 GlobalValue *GV = GSDN->getGlobal();
831 SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000832 const TargetMachine &TM = DAG.getTarget();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000833 SDOperand Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000834
835 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000836 if (!ST->usingLargeMem()) {
837 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
838 } else {
839 SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
840 SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
841 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
842 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000843 } else {
844 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000845 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000846 abort();
847 /*NOTREACHED*/
848 }
849
850 return SDOperand();
851}
852
853//! Custom lower i64 integer constants
854/*!
855 This code inserts all of the necessary juggling that needs to occur to load
856 a 64-bit constant into a register.
857 */
858static SDOperand
859LowerConstant(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000860 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000861 ConstantSDNode *CN = cast<ConstantSDNode>(Op.Val);
862
863 if (VT == MVT::i64) {
864 SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
865 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000866 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000867 } else {
868 cerr << "LowerConstant: unhandled constant type "
Duncan Sands83ec4b62008-06-06 12:08:01 +0000869 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000870 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000871 abort();
872 /*NOTREACHED*/
873 }
874
875 return SDOperand();
876}
877
Nate Begemanccef5802008-02-14 18:43:04 +0000878//! Custom lower double precision floating point constants
Scott Michel266bc8f2007-12-04 22:23:35 +0000879static SDOperand
880LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000881 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000882 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.Val);
883
884 assert((FP != 0) &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000885 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel266bc8f2007-12-04 22:23:35 +0000886
Nate Begemanccef5802008-02-14 18:43:04 +0000887 if (VT == MVT::f64) {
Scott Michel170783a2007-12-19 20:15:47 +0000888 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel266bc8f2007-12-04 22:23:35 +0000889 return DAG.getNode(ISD::BIT_CONVERT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000890 LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG));
Scott Michel266bc8f2007-12-04 22:23:35 +0000891 }
892
893 return SDOperand();
894}
895
Scott Michel58c58182008-01-17 20:38:41 +0000896//! Lower MVT::i1, MVT::i8 brcond to a promoted type (MVT::i32, MVT::i16)
897static SDOperand
898LowerBRCOND(SDOperand Op, SelectionDAG &DAG)
899{
900 SDOperand Cond = Op.getOperand(1);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000901 MVT CondVT = Cond.getValueType();
902 MVT CondNVT;
Scott Michel58c58182008-01-17 20:38:41 +0000903
904 if (CondVT == MVT::i1 || CondVT == MVT::i8) {
905 CondNVT = (CondVT == MVT::i1 ? MVT::i32 : MVT::i16);
906 return DAG.getNode(ISD::BRCOND, Op.getValueType(),
907 Op.getOperand(0),
908 DAG.getNode(ISD::ZERO_EXTEND, CondNVT, Op.getOperand(1)),
909 Op.getOperand(2));
910 } else
911 return SDOperand(); // Unchanged
912}
913
Scott Michel266bc8f2007-12-04 22:23:35 +0000914static SDOperand
915LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
916{
917 MachineFunction &MF = DAG.getMachineFunction();
918 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000919 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +0000920 SmallVector<SDOperand, 8> ArgValues;
921 SDOperand Root = Op.getOperand(0);
922 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
923
924 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
925 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
926
927 unsigned ArgOffset = SPUFrameInfo::minStackSize();
928 unsigned ArgRegIdx = 0;
929 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
930
Duncan Sands83ec4b62008-06-06 12:08:01 +0000931 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +0000932
933 // Add DAG nodes to load the arguments or copy them out of registers.
934 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
935 SDOperand ArgVal;
936 bool needsLoad = false;
Duncan Sands83ec4b62008-06-06 12:08:01 +0000937 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
938 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michel266bc8f2007-12-04 22:23:35 +0000939
Duncan Sands83ec4b62008-06-06 12:08:01 +0000940 switch (ObjectVT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000941 default: {
942 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
Duncan Sands83ec4b62008-06-06 12:08:01 +0000943 << ObjectVT.getMVTString()
Scott Michel266bc8f2007-12-04 22:23:35 +0000944 << "\n";
945 abort();
946 }
947 case MVT::i8:
948 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000949 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
950 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000951 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
952 ++ArgRegIdx;
953 } else {
954 needsLoad = true;
955 }
956 break;
957 case MVT::i16:
958 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000959 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
960 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000961 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
962 ++ArgRegIdx;
963 } else {
964 needsLoad = true;
965 }
966 break;
967 case MVT::i32:
968 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000969 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
970 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000971 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
972 ++ArgRegIdx;
973 } else {
974 needsLoad = true;
975 }
976 break;
977 case MVT::i64:
978 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000979 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
980 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000981 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
982 ++ArgRegIdx;
983 } else {
984 needsLoad = true;
985 }
986 break;
987 case MVT::f32:
988 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000989 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
990 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +0000991 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
992 ++ArgRegIdx;
993 } else {
994 needsLoad = true;
995 }
996 break;
997 case MVT::f64:
998 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +0000999 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
1000 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001001 ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
1002 ++ArgRegIdx;
1003 } else {
1004 needsLoad = true;
1005 }
1006 break;
1007 case MVT::v2f64:
1008 case MVT::v4f32:
Scott Michelad2715e2008-03-05 23:02:02 +00001009 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001010 case MVT::v4i32:
1011 case MVT::v8i16:
1012 case MVT::v16i8:
1013 if (!isVarArg && ArgRegIdx < NumArgRegs) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001014 unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1015 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001016 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
1017 ++ArgRegIdx;
1018 } else {
1019 needsLoad = true;
1020 }
1021 break;
1022 }
1023
1024 // We need to load the argument to a virtual register if we determined above
1025 // that we ran out of physical registers of the appropriate type
1026 if (needsLoad) {
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001027 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
1028 SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
1029 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001030 ArgOffset += StackSlotSize;
1031 }
1032
1033 ArgValues.push_back(ArgVal);
1034 }
1035
1036 // If the function takes variable number of arguments, make a frame index for
1037 // the start of the first vararg value... for expansion of llvm.va_start.
1038 if (isVarArg) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001039 VarArgsFrameIndex = MFI->CreateFixedObject(PtrVT.getSizeInBits()/8,
Scott Michel266bc8f2007-12-04 22:23:35 +00001040 ArgOffset);
1041 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1042 // If this function is vararg, store any remaining integer argument regs to
1043 // their spots on the stack so that they may be loaded by deferencing the
1044 // result of va_next.
1045 SmallVector<SDOperand, 8> MemOps;
1046 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Chris Lattner84bc5422007-12-31 04:13:23 +00001047 unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
1048 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Scott Michel266bc8f2007-12-04 22:23:35 +00001049 SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
1050 SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
1051 MemOps.push_back(Store);
1052 // Increment the address by four for the next argument to store
Duncan Sands83ec4b62008-06-06 12:08:01 +00001053 SDOperand PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001054 FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
1055 }
1056 if (!MemOps.empty())
1057 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
1058 }
1059
1060 ArgValues.push_back(Root);
1061
1062 // Return the new list of results.
Duncan Sandsf9516202008-06-30 10:19:09 +00001063 return DAG.getMergeValues(Op.Val->getVTList(), &ArgValues[0],
1064 ArgValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001065}
1066
1067/// isLSAAddress - Return the immediate to use if the specified
1068/// value is representable as a LSA address.
1069static SDNode *isLSAAddress(SDOperand Op, SelectionDAG &DAG) {
1070 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
1071 if (!C) return 0;
1072
1073 int Addr = C->getValue();
1074 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1075 (Addr << 14 >> 14) != Addr)
1076 return 0; // Top 14 bits have to be sext of immediate.
1077
1078 return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
1079}
1080
1081static
1082SDOperand
Scott Michel9de5d0d2008-01-11 02:53:15 +00001083LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001084 SDOperand Chain = Op.getOperand(0);
1085#if 0
1086 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
1087 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
1088#endif
1089 SDOperand Callee = Op.getOperand(4);
1090 unsigned NumOps = (Op.getNumOperands() - 5) / 2;
1091 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1092 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1093 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1094
1095 // Handy pointer type
Duncan Sands83ec4b62008-06-06 12:08:01 +00001096 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001097
1098 // Accumulate how many bytes are to be pushed on the stack, including the
1099 // linkage area, and parameter passing area. According to the SPU ABI,
1100 // we minimally need space for [LR] and [SP]
1101 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
1102
1103 // Set up a copy of the stack pointer for use loading and storing any
1104 // arguments that may not fit in the registers available for argument
1105 // passing.
1106 SDOperand StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
1107
1108 // Figure out which arguments are going to go in registers, and which in
1109 // memory.
1110 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1111 unsigned ArgRegIdx = 0;
1112
1113 // Keep track of registers passing arguments
1114 std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
1115 // And the arguments passed on the stack
1116 SmallVector<SDOperand, 8> MemOpChains;
1117
1118 for (unsigned i = 0; i != NumOps; ++i) {
1119 SDOperand Arg = Op.getOperand(5+2*i);
1120
1121 // PtrOff will be used to store the current argument to the stack if a
1122 // register cannot be found for it.
1123 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
1124 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1125
Duncan Sands83ec4b62008-06-06 12:08:01 +00001126 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001127 default: assert(0 && "Unexpected ValueType for argument!");
1128 case MVT::i32:
1129 case MVT::i64:
1130 case MVT::i128:
1131 if (ArgRegIdx != NumArgRegs) {
1132 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1133 } else {
1134 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001135 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001136 }
1137 break;
1138 case MVT::f32:
1139 case MVT::f64:
1140 if (ArgRegIdx != NumArgRegs) {
1141 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1142 } else {
1143 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001144 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001145 }
1146 break;
1147 case MVT::v4f32:
1148 case MVT::v4i32:
1149 case MVT::v8i16:
1150 case MVT::v16i8:
1151 if (ArgRegIdx != NumArgRegs) {
1152 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1153 } else {
1154 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001155 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001156 }
1157 break;
1158 }
1159 }
1160
1161 // Update number of stack bytes actually used, insert a call sequence start
1162 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
1163 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumStackBytes, PtrVT));
1164
1165 if (!MemOpChains.empty()) {
1166 // Adjust the stack pointer for the stack arguments.
1167 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1168 &MemOpChains[0], MemOpChains.size());
1169 }
1170
1171 // Build a sequence of copy-to-reg nodes chained together with token chain
1172 // and flag operands which copy the outgoing args into the appropriate regs.
1173 SDOperand InFlag;
1174 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1175 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1176 InFlag);
1177 InFlag = Chain.getValue(1);
1178 }
1179
Duncan Sands83ec4b62008-06-06 12:08:01 +00001180 std::vector<MVT> NodeTys;
Scott Michel266bc8f2007-12-04 22:23:35 +00001181 NodeTys.push_back(MVT::Other); // Returns a chain
1182 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
1183
1184 SmallVector<SDOperand, 8> Ops;
1185 unsigned CallOpc = SPUISD::CALL;
1186
1187 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1188 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1189 // node so that legalize doesn't hack it.
1190 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1191 GlobalValue *GV = G->getGlobal();
Duncan Sands83ec4b62008-06-06 12:08:01 +00001192 MVT CalleeVT = Callee.getValueType();
Scott Michel9de5d0d2008-01-11 02:53:15 +00001193 SDOperand Zero = DAG.getConstant(0, PtrVT);
1194 SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001195
Scott Michel9de5d0d2008-01-11 02:53:15 +00001196 if (!ST->usingLargeMem()) {
1197 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1198 // style calls, otherwise, external symbols are BRASL calls. This assumes
1199 // that declared/defined symbols are in the same compilation unit and can
1200 // be reached through PC-relative jumps.
1201 //
1202 // NOTE:
1203 // This may be an unsafe assumption for JIT and really large compilation
1204 // units.
1205 if (GV->isDeclaration()) {
1206 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1207 } else {
1208 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1209 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001210 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001211 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1212 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001213 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001214 }
1215 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
1216 Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
Scott Michel9de5d0d2008-01-11 02:53:15 +00001217 else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001218 // If this is an absolute destination address that appears to be a legal
1219 // local store address, use the munged value.
1220 Callee = SDOperand(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001221 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001222
1223 Ops.push_back(Chain);
1224 Ops.push_back(Callee);
1225
1226 // Add argument registers to the end of the list so that they are known live
1227 // into the call.
1228 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
1229 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
1230 RegsToPass[i].second.getValueType()));
1231
1232 if (InFlag.Val)
1233 Ops.push_back(InFlag);
1234 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
1235 InFlag = Chain.getValue(1);
1236
Evan Chengebaaa912008-02-05 22:44:06 +00001237 Chain = DAG.getCALLSEQ_END(Chain,
1238 DAG.getConstant(NumStackBytes, PtrVT),
1239 DAG.getConstant(0, PtrVT),
1240 InFlag);
1241 if (Op.Val->getValueType(0) != MVT::Other)
1242 InFlag = Chain.getValue(1);
1243
Scott Michel266bc8f2007-12-04 22:23:35 +00001244 SDOperand ResultVals[3];
1245 unsigned NumResults = 0;
1246 NodeTys.clear();
1247
1248 // If the call has results, copy the values out of the ret val registers.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001249 switch (Op.Val->getValueType(0).getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001250 default: assert(0 && "Unexpected ret value!");
1251 case MVT::Other: break;
1252 case MVT::i32:
1253 if (Op.Val->getValueType(1) == MVT::i32) {
1254 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1255 ResultVals[0] = Chain.getValue(0);
1256 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1257 Chain.getValue(2)).getValue(1);
1258 ResultVals[1] = Chain.getValue(0);
1259 NumResults = 2;
1260 NodeTys.push_back(MVT::i32);
1261 } else {
1262 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1263 ResultVals[0] = Chain.getValue(0);
1264 NumResults = 1;
1265 }
1266 NodeTys.push_back(MVT::i32);
1267 break;
1268 case MVT::i64:
1269 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1270 ResultVals[0] = Chain.getValue(0);
1271 NumResults = 1;
1272 NodeTys.push_back(MVT::i64);
1273 break;
1274 case MVT::f32:
1275 case MVT::f64:
1276 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1277 InFlag).getValue(1);
1278 ResultVals[0] = Chain.getValue(0);
1279 NumResults = 1;
1280 NodeTys.push_back(Op.Val->getValueType(0));
1281 break;
1282 case MVT::v2f64:
1283 case MVT::v4f32:
1284 case MVT::v4i32:
1285 case MVT::v8i16:
1286 case MVT::v16i8:
1287 Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.Val->getValueType(0),
1288 InFlag).getValue(1);
1289 ResultVals[0] = Chain.getValue(0);
1290 NumResults = 1;
1291 NodeTys.push_back(Op.Val->getValueType(0));
1292 break;
1293 }
1294
Scott Michel266bc8f2007-12-04 22:23:35 +00001295 NodeTys.push_back(MVT::Other);
1296
1297 // If the function returns void, just return the chain.
1298 if (NumResults == 0)
1299 return Chain;
1300
1301 // Otherwise, merge everything together with a MERGE_VALUES node.
1302 ResultVals[NumResults++] = Chain;
Duncan Sandsf9516202008-06-30 10:19:09 +00001303 SDOperand Res = DAG.getMergeValues(DAG.getVTList(&NodeTys[0], NodeTys.size()),
1304 ResultVals, NumResults);
Scott Michel266bc8f2007-12-04 22:23:35 +00001305 return Res.getValue(Op.ResNo);
1306}
1307
1308static SDOperand
1309LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
1310 SmallVector<CCValAssign, 16> RVLocs;
1311 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1312 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1313 CCState CCInfo(CC, isVarArg, TM, RVLocs);
1314 CCInfo.AnalyzeReturn(Op.Val, RetCC_SPU);
1315
1316 // If this is the first return lowered for this function, add the regs to the
1317 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001318 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001319 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001320 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001321 }
1322
1323 SDOperand Chain = Op.getOperand(0);
1324 SDOperand Flag;
1325
1326 // Copy the result values into the output registers.
1327 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1328 CCValAssign &VA = RVLocs[i];
1329 assert(VA.isRegLoc() && "Can only return in registers!");
1330 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1331 Flag = Chain.getValue(1);
1332 }
1333
1334 if (Flag.Val)
1335 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1336 else
1337 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1338}
1339
1340
1341//===----------------------------------------------------------------------===//
1342// Vector related lowering:
1343//===----------------------------------------------------------------------===//
1344
1345static ConstantSDNode *
1346getVecImm(SDNode *N) {
1347 SDOperand OpVal(0, 0);
1348
1349 // Check to see if this buildvec has a single non-undef value in its elements.
1350 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1351 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
1352 if (OpVal.Val == 0)
1353 OpVal = N->getOperand(i);
1354 else if (OpVal != N->getOperand(i))
1355 return 0;
1356 }
1357
1358 if (OpVal.Val != 0) {
1359 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1360 return CN;
1361 }
1362 }
1363
1364 return 0; // All UNDEF: use implicit def.; not Constant node
1365}
1366
1367/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1368/// and the value fits into an unsigned 18-bit constant, and if so, return the
1369/// constant
1370SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001371 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001372 if (ConstantSDNode *CN = getVecImm(N)) {
1373 uint64_t Value = CN->getValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001374 if (ValueType == MVT::i64) {
1375 uint64_t UValue = CN->getValue();
1376 uint32_t upper = uint32_t(UValue >> 32);
1377 uint32_t lower = uint32_t(UValue);
1378 if (upper != lower)
1379 return SDOperand();
1380 Value = Value >> 32;
1381 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001382 if (Value <= 0x3ffff)
1383 return DAG.getConstant(Value, ValueType);
1384 }
1385
1386 return SDOperand();
1387}
1388
1389/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1390/// and the value fits into a signed 16-bit constant, and if so, return the
1391/// constant
1392SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001393 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001394 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001395 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001396 if (ValueType == MVT::i64) {
1397 uint64_t UValue = CN->getValue();
1398 uint32_t upper = uint32_t(UValue >> 32);
1399 uint32_t lower = uint32_t(UValue);
1400 if (upper != lower)
1401 return SDOperand();
1402 Value = Value >> 32;
1403 }
Scott Michelad2715e2008-03-05 23:02:02 +00001404 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
1405 return DAG.getConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001406 }
1407 }
1408
1409 return SDOperand();
1410}
1411
1412/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1413/// and the value fits into a signed 10-bit constant, and if so, return the
1414/// constant
1415SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001416 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001417 if (ConstantSDNode *CN = getVecImm(N)) {
Scott Michelad2715e2008-03-05 23:02:02 +00001418 int64_t Value = CN->getSignExtended();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001419 if (ValueType == MVT::i64) {
1420 uint64_t UValue = CN->getValue();
1421 uint32_t upper = uint32_t(UValue >> 32);
1422 uint32_t lower = uint32_t(UValue);
1423 if (upper != lower)
1424 return SDOperand();
1425 Value = Value >> 32;
1426 }
Scott Michelad2715e2008-03-05 23:02:02 +00001427 if (isS10Constant(Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001428 return DAG.getConstant(Value, ValueType);
1429 }
1430
1431 return SDOperand();
1432}
1433
1434/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1435/// and the value fits into a signed 8-bit constant, and if so, return the
1436/// constant.
1437///
1438/// @note: The incoming vector is v16i8 because that's the only way we can load
1439/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1440/// same value.
1441SDOperand SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001442 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001443 if (ConstantSDNode *CN = getVecImm(N)) {
1444 int Value = (int) CN->getValue();
1445 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001446 && Value <= 0xffff /* truncated from uint64_t */
1447 && ((short) Value >> 8) == ((short) Value & 0xff))
Scott Michel266bc8f2007-12-04 22:23:35 +00001448 return DAG.getConstant(Value & 0xff, ValueType);
1449 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001450 && (Value & 0xff) == Value)
Scott Michel266bc8f2007-12-04 22:23:35 +00001451 return DAG.getConstant(Value, ValueType);
1452 }
1453
1454 return SDOperand();
1455}
1456
1457/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1458/// and the value fits into a signed 16-bit constant, and if so, return the
1459/// constant
1460SDOperand SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001461 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001462 if (ConstantSDNode *CN = getVecImm(N)) {
1463 uint64_t Value = CN->getValue();
1464 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001465 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1466 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Scott Michel266bc8f2007-12-04 22:23:35 +00001467 return DAG.getConstant(Value >> 16, ValueType);
1468 }
1469
1470 return SDOperand();
1471}
1472
1473/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
1474SDOperand SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
1475 if (ConstantSDNode *CN = getVecImm(N)) {
1476 return DAG.getConstant((unsigned) CN->getValue(), MVT::i32);
1477 }
1478
1479 return SDOperand();
1480}
1481
1482/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
1483SDOperand SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
1484 if (ConstantSDNode *CN = getVecImm(N)) {
1485 return DAG.getConstant((unsigned) CN->getValue(), MVT::i64);
1486 }
1487
1488 return SDOperand();
1489}
1490
1491// If this is a vector of constants or undefs, get the bits. A bit in
1492// UndefBits is set if the corresponding element of the vector is an
1493// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1494// zero. Return true if this is not an array of constants, false if it is.
1495//
1496static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1497 uint64_t UndefBits[2]) {
1498 // Start with zero'd results.
1499 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
1500
Duncan Sands83ec4b62008-06-06 12:08:01 +00001501 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel266bc8f2007-12-04 22:23:35 +00001502 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
1503 SDOperand OpVal = BV->getOperand(i);
1504
1505 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1506 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1507
1508 uint64_t EltBits = 0;
1509 if (OpVal.getOpcode() == ISD::UNDEF) {
1510 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1511 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1512 continue;
1513 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
1514 EltBits = CN->getValue() & (~0ULL >> (64-EltBitSize));
1515 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
1516 const APFloat &apf = CN->getValueAPF();
1517 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001518 ? FloatToBits(apf.convertToFloat())
1519 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001520 } else {
1521 // Nonconstant element.
1522 return true;
1523 }
1524
1525 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1526 }
1527
1528 //printf("%llx %llx %llx %llx\n",
1529 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1530 return false;
1531}
1532
1533/// If this is a splat (repetition) of a value across the whole vector, return
1534/// the smallest size that splats it. For example, "0x01010101010101..." is a
1535/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
1536/// SplatSize = 1 byte.
1537static bool isConstantSplat(const uint64_t Bits128[2],
1538 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001539 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001540 uint64_t &SplatBits, uint64_t &SplatUndef,
1541 int &SplatSize) {
1542 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1543 // the same as the lower 64-bits, ignoring undefs.
1544 uint64_t Bits64 = Bits128[0] | Bits128[1];
1545 uint64_t Undef64 = Undef128[0] & Undef128[1];
1546 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1547 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1548 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1549 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1550
1551 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1552 if (MinSplatBits < 64) {
1553
1554 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1555 // undefs.
1556 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001557 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001558
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001559 // If the top 16-bits are different than the lower 16-bits, ignoring
1560 // undefs, we have an i32 splat.
1561 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1562 if (MinSplatBits < 16) {
1563 // If the top 8-bits are different than the lower 8-bits, ignoring
1564 // undefs, we have an i16 splat.
1565 if ((Bits16 & (uint16_t(~Undef16) >> 8)) == ((Bits16 >> 8) & ~Undef16)) {
1566 // Otherwise, we have an 8-bit splat.
1567 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1568 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1569 SplatSize = 1;
1570 return true;
1571 }
1572 } else {
1573 SplatBits = Bits16;
1574 SplatUndef = Undef16;
1575 SplatSize = 2;
1576 return true;
1577 }
1578 }
1579 } else {
1580 SplatBits = Bits32;
1581 SplatUndef = Undef32;
1582 SplatSize = 4;
1583 return true;
1584 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001585 }
1586 } else {
1587 SplatBits = Bits128[0];
1588 SplatUndef = Undef128[0];
1589 SplatSize = 8;
1590 return true;
1591 }
1592 }
1593
1594 return false; // Can't be a splat if two pieces don't match.
1595}
1596
1597// If this is a case we can't handle, return null and let the default
1598// expansion code take care of it. If we CAN select this case, and if it
1599// selects to a single instruction, return Op. Otherwise, if we can codegen
1600// this case more efficiently than a constant pool load, lower it to the
1601// sequence of ops that should be used.
1602static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001603 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001604 // If this is a vector of constants or undefs, get the bits. A bit in
1605 // UndefBits is set if the corresponding element of the vector is an
1606 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1607 // zero.
1608 uint64_t VectorBits[2];
1609 uint64_t UndefBits[2];
1610 uint64_t SplatBits, SplatUndef;
1611 int SplatSize;
1612 if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits)
1613 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001614 VT.getVectorElementType().getSizeInBits(),
Scott Michel266bc8f2007-12-04 22:23:35 +00001615 SplatBits, SplatUndef, SplatSize))
1616 return SDOperand(); // Not a constant vector, not a splat.
1617
Duncan Sands83ec4b62008-06-06 12:08:01 +00001618 switch (VT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001619 default:
1620 case MVT::v4f32: {
1621 uint32_t Value32 = SplatBits;
1622 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001623 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001624 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1625 SDOperand T = DAG.getConstant(Value32, MVT::i32);
1626 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001627 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001628 break;
1629 }
1630 case MVT::v2f64: {
1631 uint64_t f64val = SplatBits;
1632 assert(SplatSize == 8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001633 && "LowerBUILD_VECTOR: 64-bit float vector element: unexpected size.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001634 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
1635 SDOperand T = DAG.getConstant(f64val, MVT::i64);
1636 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001637 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001638 break;
1639 }
1640 case MVT::v16i8: {
1641 // 8-bit constants have to be expanded to 16-bits
1642 unsigned short Value16 = SplatBits | (SplatBits << 8);
1643 SDOperand Ops[8];
1644 for (int i = 0; i < 8; ++i)
1645 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1646 return DAG.getNode(ISD::BIT_CONVERT, VT,
1647 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1648 }
1649 case MVT::v8i16: {
1650 unsigned short Value16;
1651 if (SplatSize == 2)
1652 Value16 = (unsigned short) (SplatBits & 0xffff);
1653 else
1654 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Duncan Sands83ec4b62008-06-06 12:08:01 +00001655 SDOperand T = DAG.getConstant(Value16, VT.getVectorElementType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001656 SDOperand Ops[8];
1657 for (int i = 0; i < 8; ++i) Ops[i] = T;
1658 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1659 }
1660 case MVT::v4i32: {
1661 unsigned int Value = SplatBits;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001662 SDOperand T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001663 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1664 }
1665 case MVT::v2i64: {
1666 uint64_t val = SplatBits;
1667 uint32_t upper = uint32_t(val >> 32);
1668 uint32_t lower = uint32_t(val);
1669
Scott Michel4cb8bd82008-03-06 04:02:54 +00001670 if (upper == lower) {
1671 // Magic constant that can be matched by IL, ILA, et. al.
1672 SDOperand Val = DAG.getTargetConstant(val, MVT::i64);
1673 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michelad2715e2008-03-05 23:02:02 +00001674 } else {
Scott Michel266bc8f2007-12-04 22:23:35 +00001675 SDOperand LO32;
1676 SDOperand HI32;
1677 SmallVector<SDOperand, 16> ShufBytes;
1678 SDOperand Result;
1679 bool upper_special, lower_special;
1680
1681 // NOTE: This code creates common-case shuffle masks that can be easily
1682 // detected as common expressions. It is not attempting to create highly
1683 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1684
1685 // Detect if the upper or lower half is a special shuffle mask pattern:
1686 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1687 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1688
1689 // Create lower vector if not a special pattern
1690 if (!lower_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001691 SDOperand LO32C = DAG.getConstant(lower, MVT::i32);
1692 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1693 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1694 LO32C, LO32C, LO32C, LO32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001695 }
1696
1697 // Create upper vector if not a special pattern
1698 if (!upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001699 SDOperand HI32C = DAG.getConstant(upper, MVT::i32);
1700 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1701 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1702 HI32C, HI32C, HI32C, HI32C));
Scott Michel266bc8f2007-12-04 22:23:35 +00001703 }
1704
1705 // If either upper or lower are special, then the two input operands are
1706 // the same (basically, one of them is a "don't care")
1707 if (lower_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001708 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001709 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001710 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001711 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001712 // Unhappy situation... both upper and lower are special, so punt with
1713 // a target constant:
Scott Michel266bc8f2007-12-04 22:23:35 +00001714 SDOperand Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001715 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001716 Zero, Zero);
1717 }
1718
1719 for (int i = 0; i < 4; ++i) {
Scott Michel8bf61e82008-06-02 22:18:03 +00001720 uint64_t val = 0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001721 for (int j = 0; j < 4; ++j) {
1722 SDOperand V;
1723 bool process_upper, process_lower;
Scott Michel8bf61e82008-06-02 22:18:03 +00001724 val <<= 8;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001725 process_upper = (upper_special && (i & 1) == 0);
1726 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001727
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001728 if (process_upper || process_lower) {
1729 if ((process_upper && upper == 0)
1730 || (process_lower && lower == 0))
Scott Michel8bf61e82008-06-02 22:18:03 +00001731 val |= 0x80;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001732 else if ((process_upper && upper == 0xffffffff)
1733 || (process_lower && lower == 0xffffffff))
Scott Michel8bf61e82008-06-02 22:18:03 +00001734 val |= 0xc0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001735 else if ((process_upper && upper == 0x80000000)
1736 || (process_lower && lower == 0x80000000))
Scott Michel8bf61e82008-06-02 22:18:03 +00001737 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001738 } else
Scott Michel8bf61e82008-06-02 22:18:03 +00001739 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001740 }
Scott Michel8bf61e82008-06-02 22:18:03 +00001741
1742 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001743 }
1744
1745 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel8bf61e82008-06-02 22:18:03 +00001746 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001747 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001748 }
1749 }
1750 }
1751
1752 return SDOperand();
1753}
1754
1755/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1756/// which the Cell can operate. The code inspects V3 to ascertain whether the
1757/// permutation vector, V3, is monotonically increasing with one "exception"
1758/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
1759/// INSERT_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
1760/// In either case, the net result is going to eventually invoke SHUFB to
1761/// permute/shuffle the bytes from V1 and V2.
1762/// \note
1763/// INSERT_MASK is eventually selected as one of the C*D instructions, generate
1764/// control word for byte/halfword/word insertion. This takes care of a single
1765/// element move from V2 into V1.
1766/// \note
1767/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
1768static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
1769 SDOperand V1 = Op.getOperand(0);
1770 SDOperand V2 = Op.getOperand(1);
1771 SDOperand PermMask = Op.getOperand(2);
1772
1773 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
1774
1775 // If we have a single element being moved from V1 to V2, this can be handled
1776 // using the C*[DX] compute mask instructions, but the vector elements have
1777 // to be monotonically increasing with one exception element.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001778 MVT EltVT = V1.getValueType().getVectorElementType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001779 unsigned EltsFromV2 = 0;
1780 unsigned V2Elt = 0;
1781 unsigned V2EltIdx0 = 0;
1782 unsigned CurrElt = 0;
1783 bool monotonic = true;
1784 if (EltVT == MVT::i8)
1785 V2EltIdx0 = 16;
1786 else if (EltVT == MVT::i16)
1787 V2EltIdx0 = 8;
1788 else if (EltVT == MVT::i32)
1789 V2EltIdx0 = 4;
1790 else
1791 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1792
1793 for (unsigned i = 0, e = PermMask.getNumOperands();
1794 EltsFromV2 <= 1 && monotonic && i != e;
1795 ++i) {
1796 unsigned SrcElt;
1797 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
1798 SrcElt = 0;
1799 else
1800 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
1801
1802 if (SrcElt >= V2EltIdx0) {
1803 ++EltsFromV2;
1804 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1805 } else if (CurrElt != SrcElt) {
1806 monotonic = false;
1807 }
1808
1809 ++CurrElt;
1810 }
1811
1812 if (EltsFromV2 == 1 && monotonic) {
1813 // Compute mask and shuffle
1814 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001815 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1816 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands83ec4b62008-06-06 12:08:01 +00001817 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001818 // Initialize temporary register to 0
1819 SDOperand InitTempReg =
1820 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
1821 // Copy register's contents as index in INSERT_MASK:
1822 SDOperand ShufMaskOp =
1823 DAG.getNode(SPUISD::INSERT_MASK, V1.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001824 DAG.getTargetConstant(V2Elt, MVT::i32),
1825 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001826 // Use shuffle mask in SHUFB synthetic instruction:
1827 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
1828 } else {
1829 // Convert the SHUFFLE_VECTOR mask's input element units to the actual bytes.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001830 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel266bc8f2007-12-04 22:23:35 +00001831
1832 SmallVector<SDOperand, 16> ResultMask;
1833 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1834 unsigned SrcElt;
1835 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001836 SrcElt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001837 else
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001838 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001839
Scott Michela59d4692008-02-23 18:41:37 +00001840 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001841 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1842 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001843 }
1844 }
1845
1846 SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001847 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001848 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1849 }
1850}
1851
1852static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001853 SDOperand Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001854
1855 if (Op0.Val->getOpcode() == ISD::Constant) {
1856 // For a constant, build the appropriate constant vector, which will
1857 // eventually simplify to a vector register load.
1858
1859 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.Val);
1860 SmallVector<SDOperand, 16> ConstVecValues;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001861 MVT VT;
Scott Michel266bc8f2007-12-04 22:23:35 +00001862 size_t n_copies;
1863
1864 // Create a constant vector:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001865 switch (Op.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001866 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001867 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001868 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1869 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1870 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1871 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1872 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1873 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1874 }
1875
1876 SDOperand CValue = DAG.getConstant(CN->getValue(), VT);
1877 for (size_t j = 0; j < n_copies; ++j)
1878 ConstVecValues.push_back(CValue);
1879
1880 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001881 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001882 } else {
1883 // Otherwise, copy the value from one register to another:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001884 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001885 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1886 case MVT::i8:
1887 case MVT::i16:
1888 case MVT::i32:
1889 case MVT::i64:
1890 case MVT::f32:
1891 case MVT::f64:
1892 return DAG.getNode(SPUISD::PROMOTE_SCALAR, Op.getValueType(), Op0, Op0);
1893 }
1894 }
1895
1896 return SDOperand();
1897}
1898
1899static SDOperand LowerVectorMUL(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001900 switch (Op.getValueType().getSimpleVT()) {
1901 default:
1902 cerr << "CellSPU: Unknown vector multiplication, got "
1903 << Op.getValueType().getMVTString()
1904 << "\n";
1905 abort();
1906 /*NOTREACHED*/
1907
Scott Michel266bc8f2007-12-04 22:23:35 +00001908 case MVT::v4i32: {
1909 SDOperand rA = Op.getOperand(0);
1910 SDOperand rB = Op.getOperand(1);
1911 SDOperand HiProd1 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rA, rB);
1912 SDOperand HiProd2 = DAG.getNode(SPUISD::MPYH, MVT::v4i32, rB, rA);
1913 SDOperand LoProd = DAG.getNode(SPUISD::MPYU, MVT::v4i32, rA, rB);
1914 SDOperand Residual1 = DAG.getNode(ISD::ADD, MVT::v4i32, LoProd, HiProd1);
1915
1916 return DAG.getNode(ISD::ADD, MVT::v4i32, Residual1, HiProd2);
1917 break;
1918 }
1919
1920 // Multiply two v8i16 vectors (pipeline friendly version):
1921 // a) multiply lower halves, mask off upper 16-bit of 32-bit product
1922 // b) multiply upper halves, rotate left by 16 bits (inserts 16 lower zeroes)
1923 // c) Use SELB to select upper and lower halves from the intermediate results
1924 //
Scott Michel8bf61e82008-06-02 22:18:03 +00001925 // NOTE: We really want to move the SELECT_MASK to earlier to actually get the
Scott Michel266bc8f2007-12-04 22:23:35 +00001926 // dual-issue. This code does manage to do this, even if it's a little on
1927 // the wacky side
1928 case MVT::v8i16: {
1929 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001930 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00001931 SDOperand Chain = Op.getOperand(0);
1932 SDOperand rA = Op.getOperand(0);
1933 SDOperand rB = Op.getOperand(1);
Chris Lattner84bc5422007-12-31 04:13:23 +00001934 unsigned FSMBIreg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
1935 unsigned HiProdReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00001936
1937 SDOperand FSMBOp =
1938 DAG.getCopyToReg(Chain, FSMBIreg,
Scott Michel8bf61e82008-06-02 22:18:03 +00001939 DAG.getNode(SPUISD::SELECT_MASK, MVT::v8i16,
Scott Michel203b2d62008-04-30 00:30:08 +00001940 DAG.getConstant(0xcccc, MVT::i16)));
Scott Michel266bc8f2007-12-04 22:23:35 +00001941
1942 SDOperand HHProd =
1943 DAG.getCopyToReg(FSMBOp, HiProdReg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001944 DAG.getNode(SPUISD::MPYHH, MVT::v8i16, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001945
1946 SDOperand HHProd_v4i32 =
1947 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001948 DAG.getCopyFromReg(HHProd, HiProdReg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001949
1950 return DAG.getNode(SPUISD::SELB, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001951 DAG.getNode(SPUISD::MPY, MVT::v8i16, rA, rB),
1952 DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(),
1953 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32,
1954 HHProd_v4i32,
1955 DAG.getConstant(16, MVT::i16))),
1956 DAG.getCopyFromReg(FSMBOp, FSMBIreg, MVT::v4i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001957 }
1958
1959 // This M00sE is N@stI! (apologies to Monty Python)
1960 //
1961 // SPU doesn't know how to do any 8-bit multiplication, so the solution
1962 // is to break it all apart, sign extend, and reassemble the various
1963 // intermediate products.
1964 case MVT::v16i8: {
Scott Michel266bc8f2007-12-04 22:23:35 +00001965 SDOperand rA = Op.getOperand(0);
1966 SDOperand rB = Op.getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00001967 SDOperand c8 = DAG.getConstant(8, MVT::i32);
1968 SDOperand c16 = DAG.getConstant(16, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001969
1970 SDOperand LLProd =
1971 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001972 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rA),
1973 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00001974
1975 SDOperand rALH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rA, c8);
1976
1977 SDOperand rBLH = DAG.getNode(SPUISD::VEC_SRA, MVT::v8i16, rB, c8);
1978
1979 SDOperand LHProd =
1980 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001981 DAG.getNode(SPUISD::MPY, MVT::v8i16, rALH, rBLH), c8);
Scott Michel266bc8f2007-12-04 22:23:35 +00001982
Scott Michel8bf61e82008-06-02 22:18:03 +00001983 SDOperand FSMBmask = DAG.getNode(SPUISD::SELECT_MASK, MVT::v8i16,
Scott Michel203b2d62008-04-30 00:30:08 +00001984 DAG.getConstant(0x2222, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001985
Scott Michela59d4692008-02-23 18:41:37 +00001986 SDOperand LoProdParts =
1987 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
1988 DAG.getNode(SPUISD::SELB, MVT::v8i16,
1989 LLProd, LHProd, FSMBmask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001990
1991 SDOperand LoProdMask = DAG.getConstant(0xffff, MVT::i32);
1992
1993 SDOperand LoProd =
1994 DAG.getNode(ISD::AND, MVT::v4i32,
Scott Michela59d4692008-02-23 18:41:37 +00001995 LoProdParts,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001996 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1997 LoProdMask, LoProdMask,
1998 LoProdMask, LoProdMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00001999
2000 SDOperand rAH =
2001 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002002 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rA), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002003
2004 SDOperand rBH =
2005 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002006 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, rB), c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002007
2008 SDOperand HLProd =
2009 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002010 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rAH),
2011 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16, rBH));
Scott Michel266bc8f2007-12-04 22:23:35 +00002012
2013 SDOperand HHProd_1 =
2014 DAG.getNode(SPUISD::MPY, MVT::v8i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002015 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2016 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rAH, c8)),
2017 DAG.getNode(ISD::BIT_CONVERT, MVT::v8i16,
2018 DAG.getNode(SPUISD::VEC_SRA, MVT::v4i32, rBH, c8)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002019
2020 SDOperand HHProd =
Scott Michela59d4692008-02-23 18:41:37 +00002021 DAG.getNode(SPUISD::SELB, MVT::v8i16,
2022 HLProd,
2023 DAG.getNode(SPUISD::VEC_SHL, MVT::v8i16, HHProd_1, c8),
2024 FSMBmask);
Scott Michel266bc8f2007-12-04 22:23:35 +00002025
2026 SDOperand HiProd =
Scott Michela59d4692008-02-23 18:41:37 +00002027 DAG.getNode(SPUISD::VEC_SHL, MVT::v4i32, HHProd, c16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002028
2029 return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002030 DAG.getNode(ISD::OR, MVT::v4i32,
2031 LoProd, HiProd));
Scott Michel266bc8f2007-12-04 22:23:35 +00002032 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002033 }
2034
2035 return SDOperand();
2036}
2037
2038static SDOperand LowerFDIVf32(SDOperand Op, SelectionDAG &DAG) {
2039 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002040 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002041
2042 SDOperand A = Op.getOperand(0);
2043 SDOperand B = Op.getOperand(1);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002044 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002045
2046 unsigned VRegBR, VRegC;
2047
2048 if (VT == MVT::f32) {
Chris Lattner84bc5422007-12-31 04:13:23 +00002049 VRegBR = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
2050 VRegC = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002051 } else {
Chris Lattner84bc5422007-12-31 04:13:23 +00002052 VRegBR = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
2053 VRegC = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002054 }
2055 // TODO: make sure we're feeding FPInterp the right arguments
2056 // Right now: fi B, frest(B)
2057
2058 // Computes BRcpl =
2059 // (Floating Interpolate (FP Reciprocal Estimate B))
2060 SDOperand BRcpl =
2061 DAG.getCopyToReg(DAG.getEntryNode(), VRegBR,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002062 DAG.getNode(SPUISD::FPInterp, VT, B,
2063 DAG.getNode(SPUISD::FPRecipEst, VT, B)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002064
2065 // Computes A * BRcpl and stores in a temporary register
2066 SDOperand AxBRcpl =
2067 DAG.getCopyToReg(BRcpl, VRegC,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002068 DAG.getNode(ISD::FMUL, VT, A,
2069 DAG.getCopyFromReg(BRcpl, VRegBR, VT)));
Scott Michel266bc8f2007-12-04 22:23:35 +00002070 // What's the Chain variable do? It's magic!
2071 // TODO: set Chain = Op(0).getEntryNode()
2072
2073 return DAG.getNode(ISD::FADD, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002074 DAG.getCopyFromReg(AxBRcpl, VRegC, VT),
2075 DAG.getNode(ISD::FMUL, VT,
2076 DAG.getCopyFromReg(AxBRcpl, VRegBR, VT),
2077 DAG.getNode(ISD::FSUB, VT, A,
2078 DAG.getNode(ISD::FMUL, VT, B,
2079 DAG.getCopyFromReg(AxBRcpl, VRegC, VT)))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002080}
2081
Scott Michel266bc8f2007-12-04 22:23:35 +00002082static SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002083 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002084 SDOperand N = Op.getOperand(0);
2085 SDOperand Elt = Op.getOperand(1);
2086 SDOperand ShufMask[16];
2087 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt);
2088
2089 assert(C != 0 && "LowerEXTRACT_VECTOR_ELT expecting constant SDNode");
2090
2091 int EltNo = (int) C->getValue();
2092
2093 // sanity checks:
2094 if (VT == MVT::i8 && EltNo >= 16)
2095 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
2096 else if (VT == MVT::i16 && EltNo >= 8)
2097 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
2098 else if (VT == MVT::i32 && EltNo >= 4)
2099 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
2100 else if (VT == MVT::i64 && EltNo >= 2)
2101 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
2102
2103 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
2104 // i32 and i64: Element 0 is the preferred slot
2105 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT, N);
2106 }
2107
2108 // Need to generate shuffle mask and extract:
Scott Michel0e5665b2007-12-19 21:17:42 +00002109 int prefslot_begin = -1, prefslot_end = -1;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002110 int elt_byte = EltNo * VT.getSizeInBits() / 8;
Scott Michel266bc8f2007-12-04 22:23:35 +00002111
Duncan Sands83ec4b62008-06-06 12:08:01 +00002112 switch (VT.getSimpleVT()) {
2113 default:
2114 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002115 case MVT::i8: {
2116 prefslot_begin = prefslot_end = 3;
2117 break;
2118 }
2119 case MVT::i16: {
2120 prefslot_begin = 2; prefslot_end = 3;
2121 break;
2122 }
2123 case MVT::i32: {
2124 prefslot_begin = 0; prefslot_end = 3;
2125 break;
2126 }
2127 case MVT::i64: {
2128 prefslot_begin = 0; prefslot_end = 7;
2129 break;
2130 }
2131 }
2132
Scott Michel0e5665b2007-12-19 21:17:42 +00002133 assert(prefslot_begin != -1 && prefslot_end != -1 &&
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002134 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
Scott Michel0e5665b2007-12-19 21:17:42 +00002135
Scott Michel266bc8f2007-12-04 22:23:35 +00002136 for (int i = 0; i < 16; ++i) {
2137 // zero fill uppper part of preferred slot, don't care about the
2138 // other slots:
2139 unsigned int mask_val;
2140
2141 if (i <= prefslot_end) {
2142 mask_val =
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002143 ((i < prefslot_begin)
2144 ? 0x80
2145 : elt_byte + (i - prefslot_begin));
Scott Michel266bc8f2007-12-04 22:23:35 +00002146
Scott Michel0e5665b2007-12-19 21:17:42 +00002147 ShufMask[i] = DAG.getConstant(mask_val, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002148 } else
2149 ShufMask[i] = ShufMask[i % (prefslot_end + 1)];
2150 }
2151
2152 SDOperand ShufMaskVec =
2153 DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002154 &ShufMask[0],
2155 sizeof(ShufMask) / sizeof(ShufMask[0]));
Scott Michel266bc8f2007-12-04 22:23:35 +00002156
2157 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002158 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2159 N, N, ShufMaskVec));
2160
Scott Michel266bc8f2007-12-04 22:23:35 +00002161}
2162
2163static SDOperand LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
2164 SDOperand VecOp = Op.getOperand(0);
2165 SDOperand ValOp = Op.getOperand(1);
2166 SDOperand IdxOp = Op.getOperand(2);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002167 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002168
2169 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2170 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2171
Duncan Sands83ec4b62008-06-06 12:08:01 +00002172 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00002173 // Use $2 because it's always 16-byte aligned and it's available:
2174 SDOperand PtrBase = DAG.getRegister(SPU::R2, PtrVT);
2175
2176 SDOperand result =
2177 DAG.getNode(SPUISD::SHUFB, VT,
2178 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
2179 VecOp,
2180 DAG.getNode(SPUISD::INSERT_MASK, VT,
2181 DAG.getNode(ISD::ADD, PtrVT,
2182 PtrBase,
2183 DAG.getConstant(CN->getValue(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002184 PtrVT))));
Scott Michel266bc8f2007-12-04 22:23:35 +00002185
2186 return result;
2187}
2188
Scott Michela59d4692008-02-23 18:41:37 +00002189static SDOperand LowerI8Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2190{
Scott Michel266bc8f2007-12-04 22:23:35 +00002191 SDOperand N0 = Op.getOperand(0); // Everything has at least one operand
2192
2193 assert(Op.getValueType() == MVT::i8);
2194 switch (Opc) {
2195 default:
2196 assert(0 && "Unhandled i8 math operator");
2197 /*NOTREACHED*/
2198 break;
2199 case ISD::SUB: {
2200 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2201 // the result:
2202 SDOperand N1 = Op.getOperand(1);
2203 N0 = (N0.getOpcode() != ISD::Constant
2204 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2205 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
2206 N1 = (N1.getOpcode() != ISD::Constant
2207 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1)
2208 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2209 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2210 DAG.getNode(Opc, MVT::i16, N0, N1));
2211 }
2212 case ISD::ROTR:
2213 case ISD::ROTL: {
2214 SDOperand N1 = Op.getOperand(1);
2215 unsigned N1Opc;
2216 N0 = (N0.getOpcode() != ISD::Constant
2217 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2218 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002219 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::ZERO_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002220 N1 = (N1.getOpcode() != ISD::Constant
2221 ? DAG.getNode(N1Opc, MVT::i16, N1)
2222 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2223 SDOperand ExpandArg =
2224 DAG.getNode(ISD::OR, MVT::i16, N0,
2225 DAG.getNode(ISD::SHL, MVT::i16,
2226 N0, DAG.getConstant(8, MVT::i16)));
2227 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2228 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2229 }
2230 case ISD::SRL:
2231 case ISD::SHL: {
2232 SDOperand N1 = Op.getOperand(1);
2233 unsigned N1Opc;
2234 N0 = (N0.getOpcode() != ISD::Constant
2235 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
2236 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002237 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::ZERO_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002238 N1 = (N1.getOpcode() != ISD::Constant
2239 ? DAG.getNode(N1Opc, MVT::i16, N1)
2240 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2241 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2242 DAG.getNode(Opc, MVT::i16, N0, N1));
2243 }
2244 case ISD::SRA: {
2245 SDOperand N1 = Op.getOperand(1);
2246 unsigned N1Opc;
2247 N0 = (N0.getOpcode() != ISD::Constant
2248 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2249 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002250 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002251 N1 = (N1.getOpcode() != ISD::Constant
2252 ? DAG.getNode(N1Opc, MVT::i16, N1)
2253 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2254 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2255 DAG.getNode(Opc, MVT::i16, N0, N1));
2256 }
2257 case ISD::MUL: {
2258 SDOperand N1 = Op.getOperand(1);
2259 unsigned N1Opc;
2260 N0 = (N0.getOpcode() != ISD::Constant
2261 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
2262 : DAG.getConstant(cast<ConstantSDNode>(N0)->getValue(), MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002263 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002264 N1 = (N1.getOpcode() != ISD::Constant
2265 ? DAG.getNode(N1Opc, MVT::i16, N1)
2266 : DAG.getConstant(cast<ConstantSDNode>(N1)->getValue(), MVT::i16));
2267 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2268 DAG.getNode(Opc, MVT::i16, N0, N1));
2269 break;
2270 }
2271 }
2272
2273 return SDOperand();
2274}
2275
Scott Michela59d4692008-02-23 18:41:37 +00002276static SDOperand LowerI64Math(SDOperand Op, SelectionDAG &DAG, unsigned Opc)
2277{
Duncan Sands83ec4b62008-06-06 12:08:01 +00002278 MVT VT = Op.getValueType();
2279 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michela59d4692008-02-23 18:41:37 +00002280
2281 SDOperand Op0 = Op.getOperand(0);
2282
2283 switch (Opc) {
2284 case ISD::ZERO_EXTEND:
2285 case ISD::SIGN_EXTEND:
2286 case ISD::ANY_EXTEND: {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002287 MVT Op0VT = Op0.getValueType();
2288 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
Scott Michela59d4692008-02-23 18:41:37 +00002289
2290 assert(Op0VT == MVT::i32
2291 && "CellSPU: Zero/sign extending something other than i32");
Scott Michel203b2d62008-04-30 00:30:08 +00002292 DEBUG(cerr << "CellSPU: LowerI64Math custom lowering zero/sign/any extend\n");
Scott Michela59d4692008-02-23 18:41:37 +00002293
2294 unsigned NewOpc = (Opc == ISD::SIGN_EXTEND
2295 ? SPUISD::ROTBYTES_RIGHT_S
2296 : SPUISD::ROTQUAD_RZ_BYTES);
2297 SDOperand PromoteScalar =
2298 DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0);
2299
2300 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2301 DAG.getNode(ISD::BIT_CONVERT, VecVT,
2302 DAG.getNode(NewOpc, Op0VecVT,
2303 PromoteScalar,
2304 DAG.getConstant(4, MVT::i32))));
2305 }
2306
Scott Michel8bf61e82008-06-02 22:18:03 +00002307 case ISD::ADD: {
2308 // Turn operands into vectors to satisfy type checking (shufb works on
2309 // vectors)
2310 SDOperand Op0 =
2311 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2312 SDOperand Op1 =
2313 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(1));
2314 SmallVector<SDOperand, 16> ShufBytes;
2315
2316 // Create the shuffle mask for "rotating" the borrow up one register slot
2317 // once the borrow is generated.
2318 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2319 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2320 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2321 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2322
2323 SDOperand CarryGen =
2324 DAG.getNode(SPUISD::CARRY_GENERATE, MVT::v2i64, Op0, Op1);
2325 SDOperand ShiftedCarry =
2326 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2327 CarryGen, CarryGen,
2328 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2329 &ShufBytes[0], ShufBytes.size()));
2330
2331 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2332 DAG.getNode(SPUISD::ADD_EXTENDED, MVT::v2i64,
2333 Op0, Op1, ShiftedCarry));
2334 }
2335
2336 case ISD::SUB: {
2337 // Turn operands into vectors to satisfy type checking (shufb works on
2338 // vectors)
2339 SDOperand Op0 =
2340 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2341 SDOperand Op1 =
2342 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(1));
2343 SmallVector<SDOperand, 16> ShufBytes;
2344
2345 // Create the shuffle mask for "rotating" the borrow up one register slot
2346 // once the borrow is generated.
2347 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2348 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2349 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2350 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2351
2352 SDOperand BorrowGen =
2353 DAG.getNode(SPUISD::BORROW_GENERATE, MVT::v2i64, Op0, Op1);
2354 SDOperand ShiftedBorrow =
2355 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2356 BorrowGen, BorrowGen,
2357 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2358 &ShufBytes[0], ShufBytes.size()));
2359
2360 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2361 DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64,
2362 Op0, Op1, ShiftedBorrow));
2363 }
2364
Scott Michela59d4692008-02-23 18:41:37 +00002365 case ISD::SHL: {
2366 SDOperand ShiftAmt = Op.getOperand(1);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002367 MVT ShiftAmtVT = ShiftAmt.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002368 SDOperand Op0Vec = DAG.getNode(SPUISD::PROMOTE_SCALAR, VecVT, Op0);
2369 SDOperand MaskLower =
2370 DAG.getNode(SPUISD::SELB, VecVT,
2371 Op0Vec,
2372 DAG.getConstant(0, VecVT),
Scott Michel8bf61e82008-06-02 22:18:03 +00002373 DAG.getNode(SPUISD::SELECT_MASK, VecVT,
Scott Michela59d4692008-02-23 18:41:37 +00002374 DAG.getConstant(0xff00ULL, MVT::i16)));
2375 SDOperand ShiftAmtBytes =
2376 DAG.getNode(ISD::SRL, ShiftAmtVT,
2377 ShiftAmt,
2378 DAG.getConstant(3, ShiftAmtVT));
2379 SDOperand ShiftAmtBits =
2380 DAG.getNode(ISD::AND, ShiftAmtVT,
2381 ShiftAmt,
2382 DAG.getConstant(7, ShiftAmtVT));
2383
2384 return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
2385 DAG.getNode(SPUISD::SHLQUAD_L_BITS, VecVT,
2386 DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT,
2387 MaskLower, ShiftAmtBytes),
2388 ShiftAmtBits));
2389 }
2390
2391 case ISD::SRL: {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002392 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002393 SDOperand ShiftAmt = Op.getOperand(1);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002394 MVT ShiftAmtVT = ShiftAmt.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002395 SDOperand ShiftAmtBytes =
2396 DAG.getNode(ISD::SRL, ShiftAmtVT,
2397 ShiftAmt,
2398 DAG.getConstant(3, ShiftAmtVT));
2399 SDOperand ShiftAmtBits =
2400 DAG.getNode(ISD::AND, ShiftAmtVT,
2401 ShiftAmt,
2402 DAG.getConstant(7, ShiftAmtVT));
2403
2404 return DAG.getNode(SPUISD::ROTQUAD_RZ_BITS, VT,
2405 DAG.getNode(SPUISD::ROTQUAD_RZ_BYTES, VT,
2406 Op0, ShiftAmtBytes),
2407 ShiftAmtBits);
2408 }
Scott Michel8bf61e82008-06-02 22:18:03 +00002409
2410 case ISD::SRA: {
2411 // Promote Op0 to vector
2412 SDOperand Op0 =
2413 DAG.getNode(SPUISD::PROMOTE_SCALAR, MVT::v2i64, Op.getOperand(0));
2414 SDOperand ShiftAmt = Op.getOperand(1);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002415 MVT ShiftVT = ShiftAmt.getValueType();
Scott Michel8bf61e82008-06-02 22:18:03 +00002416
2417 // Negate variable shift amounts
2418 if (!isa<ConstantSDNode>(ShiftAmt)) {
2419 ShiftAmt = DAG.getNode(ISD::SUB, ShiftVT,
2420 DAG.getConstant(0, ShiftVT), ShiftAmt);
2421 }
2422
2423 SDOperand UpperHalfSign =
2424 DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i32,
2425 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32,
2426 DAG.getNode(SPUISD::VEC_SRA, MVT::v2i64,
2427 Op0, DAG.getConstant(31, MVT::i32))));
2428 SDOperand UpperHalfSignMask =
2429 DAG.getNode(SPUISD::SELECT_MASK, MVT::v2i64, UpperHalfSign);
2430 SDOperand UpperLowerMask =
2431 DAG.getNode(SPUISD::SELECT_MASK, MVT::v2i64,
2432 DAG.getConstant(0xff00, MVT::i16));
2433 SDOperand UpperLowerSelect =
2434 DAG.getNode(SPUISD::SELB, MVT::v2i64,
2435 UpperHalfSignMask, Op0, UpperLowerMask);
2436 SDOperand RotateLeftBytes =
2437 DAG.getNode(SPUISD::ROTBYTES_LEFT_BITS, MVT::v2i64,
2438 UpperLowerSelect, ShiftAmt);
2439 SDOperand RotateLeftBits =
2440 DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v2i64,
2441 RotateLeftBytes, ShiftAmt);
2442
2443 return DAG.getNode(SPUISD::EXTRACT_ELT0, MVT::i64,
2444 RotateLeftBits);
2445 }
Scott Michela59d4692008-02-23 18:41:37 +00002446 }
2447
2448 return SDOperand();
2449}
2450
Scott Michel266bc8f2007-12-04 22:23:35 +00002451//! Lower byte immediate operations for v16i8 vectors:
2452static SDOperand
2453LowerByteImmed(SDOperand Op, SelectionDAG &DAG) {
2454 SDOperand ConstVec;
2455 SDOperand Arg;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002456 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002457
2458 ConstVec = Op.getOperand(0);
2459 Arg = Op.getOperand(1);
2460 if (ConstVec.Val->getOpcode() != ISD::BUILD_VECTOR) {
2461 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
2462 ConstVec = ConstVec.getOperand(0);
2463 } else {
2464 ConstVec = Op.getOperand(1);
2465 Arg = Op.getOperand(0);
2466 if (ConstVec.Val->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002467 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002468 }
2469 }
2470 }
2471
2472 if (ConstVec.Val->getOpcode() == ISD::BUILD_VECTOR) {
2473 uint64_t VectorBits[2];
2474 uint64_t UndefBits[2];
2475 uint64_t SplatBits, SplatUndef;
2476 int SplatSize;
2477
2478 if (!GetConstantBuildVectorBits(ConstVec.Val, VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002479 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002480 VT.getVectorElementType().getSizeInBits(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002481 SplatBits, SplatUndef, SplatSize)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002482 SDOperand tcVec[16];
2483 SDOperand tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
2484 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2485
2486 // Turn the BUILD_VECTOR into a set of target constants:
2487 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002488 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002489
2490 return DAG.getNode(Op.Val->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002491 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002492 }
2493 }
2494
2495 return SDOperand();
2496}
2497
2498//! Lower i32 multiplication
Duncan Sands83ec4b62008-06-06 12:08:01 +00002499static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG, MVT VT,
Scott Michel266bc8f2007-12-04 22:23:35 +00002500 unsigned Opc) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002501 switch (VT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002502 default:
2503 cerr << "CellSPU: Unknown LowerMUL value type, got "
Duncan Sands83ec4b62008-06-06 12:08:01 +00002504 << Op.getValueType().getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002505 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002506 abort();
2507 /*NOTREACHED*/
2508
2509 case MVT::i32: {
2510 SDOperand rA = Op.getOperand(0);
2511 SDOperand rB = Op.getOperand(1);
2512
2513 return DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002514 DAG.getNode(ISD::ADD, MVT::i32,
2515 DAG.getNode(SPUISD::MPYH, MVT::i32, rA, rB),
2516 DAG.getNode(SPUISD::MPYH, MVT::i32, rB, rA)),
2517 DAG.getNode(SPUISD::MPYU, MVT::i32, rA, rB));
Scott Michel266bc8f2007-12-04 22:23:35 +00002518 }
2519 }
2520
2521 return SDOperand();
2522}
2523
2524//! Custom lowering for CTPOP (count population)
2525/*!
2526 Custom lowering code that counts the number ones in the input
2527 operand. SPU has such an instruction, but it counts the number of
2528 ones per byte, which then have to be accumulated.
2529*/
2530static SDOperand LowerCTPOP(SDOperand Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002531 MVT VT = Op.getValueType();
2532 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +00002533
Duncan Sands83ec4b62008-06-06 12:08:01 +00002534 switch (VT.getSimpleVT()) {
2535 default:
2536 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002537 case MVT::i8: {
2538 SDOperand N = Op.getOperand(0);
2539 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2540
2541 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2542 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2543
2544 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2545 }
2546
2547 case MVT::i16: {
2548 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002549 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002550
Chris Lattner84bc5422007-12-31 04:13:23 +00002551 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002552
2553 SDOperand N = Op.getOperand(0);
2554 SDOperand Elt0 = DAG.getConstant(0, MVT::i16);
2555 SDOperand Mask0 = DAG.getConstant(0x0f, MVT::i16);
2556 SDOperand Shift1 = DAG.getConstant(8, MVT::i16);
2557
2558 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2559 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2560
2561 // CNTB_result becomes the chain to which all of the virtual registers
2562 // CNTB_reg, SUM1_reg become associated:
2563 SDOperand CNTB_result =
2564 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002565
Scott Michel266bc8f2007-12-04 22:23:35 +00002566 SDOperand CNTB_rescopy =
2567 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2568
2569 SDOperand Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
2570
2571 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002572 DAG.getNode(ISD::ADD, MVT::i16,
2573 DAG.getNode(ISD::SRL, MVT::i16,
2574 Tmp1, Shift1),
2575 Tmp1),
2576 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002577 }
2578
2579 case MVT::i32: {
2580 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002581 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002582
Chris Lattner84bc5422007-12-31 04:13:23 +00002583 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2584 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002585
2586 SDOperand N = Op.getOperand(0);
2587 SDOperand Elt0 = DAG.getConstant(0, MVT::i32);
2588 SDOperand Mask0 = DAG.getConstant(0xff, MVT::i32);
2589 SDOperand Shift1 = DAG.getConstant(16, MVT::i32);
2590 SDOperand Shift2 = DAG.getConstant(8, MVT::i32);
2591
2592 SDOperand Promote = DAG.getNode(SPUISD::PROMOTE_SCALAR, vecVT, N, N);
2593 SDOperand CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
2594
2595 // CNTB_result becomes the chain to which all of the virtual registers
2596 // CNTB_reg, SUM1_reg become associated:
2597 SDOperand CNTB_result =
2598 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002599
Scott Michel266bc8f2007-12-04 22:23:35 +00002600 SDOperand CNTB_rescopy =
2601 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2602
2603 SDOperand Comp1 =
2604 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002605 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002606
2607 SDOperand Sum1 =
2608 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002609 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002610
2611 SDOperand Sum1_rescopy =
2612 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2613
2614 SDOperand Comp2 =
2615 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002616 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2617 Shift2);
Scott Michel266bc8f2007-12-04 22:23:35 +00002618 SDOperand Sum2 =
2619 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002620 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002621
2622 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2623 }
2624
2625 case MVT::i64:
2626 break;
2627 }
2628
2629 return SDOperand();
2630}
2631
2632/// LowerOperation - Provide custom lowering hooks for some operations.
2633///
2634SDOperand
2635SPUTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG)
2636{
Scott Michela59d4692008-02-23 18:41:37 +00002637 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002638 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002639
2640 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002641 default: {
2642 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002643 cerr << "Op.getOpcode() = " << Opc << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +00002644 cerr << "*Op.Val:\n";
2645 Op.Val->dump();
2646 abort();
2647 }
2648 case ISD::LOAD:
2649 case ISD::SEXTLOAD:
2650 case ISD::ZEXTLOAD:
2651 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2652 case ISD::STORE:
2653 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2654 case ISD::ConstantPool:
2655 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2656 case ISD::GlobalAddress:
2657 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2658 case ISD::JumpTable:
2659 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2660 case ISD::Constant:
2661 return LowerConstant(Op, DAG);
2662 case ISD::ConstantFP:
2663 return LowerConstantFP(Op, DAG);
Scott Michel58c58182008-01-17 20:38:41 +00002664 case ISD::BRCOND:
2665 return LowerBRCOND(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002666 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002667 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002668 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002669 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002670 case ISD::RET:
2671 return LowerRET(Op, DAG, getTargetMachine());
2672
Scott Michela59d4692008-02-23 18:41:37 +00002673
2674 // i8, i64 math ops:
2675 case ISD::ZERO_EXTEND:
2676 case ISD::SIGN_EXTEND:
2677 case ISD::ANY_EXTEND:
Scott Michel8bf61e82008-06-02 22:18:03 +00002678 case ISD::ADD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002679 case ISD::SUB:
2680 case ISD::ROTR:
2681 case ISD::ROTL:
2682 case ISD::SRL:
2683 case ISD::SHL:
Scott Michel8bf61e82008-06-02 22:18:03 +00002684 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002685 if (VT == MVT::i8)
2686 return LowerI8Math(Op, DAG, Opc);
2687 else if (VT == MVT::i64)
2688 return LowerI64Math(Op, DAG, Opc);
2689 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002690 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002691
2692 // Vector-related lowering.
2693 case ISD::BUILD_VECTOR:
2694 return LowerBUILD_VECTOR(Op, DAG);
2695 case ISD::SCALAR_TO_VECTOR:
2696 return LowerSCALAR_TO_VECTOR(Op, DAG);
2697 case ISD::VECTOR_SHUFFLE:
2698 return LowerVECTOR_SHUFFLE(Op, DAG);
2699 case ISD::EXTRACT_VECTOR_ELT:
2700 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2701 case ISD::INSERT_VECTOR_ELT:
2702 return LowerINSERT_VECTOR_ELT(Op, DAG);
2703
2704 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2705 case ISD::AND:
2706 case ISD::OR:
2707 case ISD::XOR:
2708 return LowerByteImmed(Op, DAG);
2709
2710 // Vector and i8 multiply:
2711 case ISD::MUL:
Duncan Sands83ec4b62008-06-06 12:08:01 +00002712 if (VT.isVector())
Scott Michel266bc8f2007-12-04 22:23:35 +00002713 return LowerVectorMUL(Op, DAG);
Scott Michela59d4692008-02-23 18:41:37 +00002714 else if (VT == MVT::i8)
2715 return LowerI8Math(Op, DAG, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002716 else
Scott Michela59d4692008-02-23 18:41:37 +00002717 return LowerMUL(Op, DAG, VT, Opc);
Scott Michel266bc8f2007-12-04 22:23:35 +00002718
2719 case ISD::FDIV:
Scott Michela59d4692008-02-23 18:41:37 +00002720 if (VT == MVT::f32 || VT == MVT::v4f32)
Scott Michel266bc8f2007-12-04 22:23:35 +00002721 return LowerFDIVf32(Op, DAG);
2722// else if (Op.getValueType() == MVT::f64)
2723// return LowerFDIVf64(Op, DAG);
2724 else
2725 assert(0 && "Calling FDIV on unsupported MVT");
2726
2727 case ISD::CTPOP:
2728 return LowerCTPOP(Op, DAG);
2729 }
2730
2731 return SDOperand();
2732}
2733
2734//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002735// Target Optimization Hooks
2736//===----------------------------------------------------------------------===//
2737
2738SDOperand
2739SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2740{
2741#if 0
2742 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002743#endif
2744 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002745 SelectionDAG &DAG = DCI.DAG;
Scott Michela59d4692008-02-23 18:41:37 +00002746 SDOperand Op0 = N->getOperand(0); // everything has at least one operand
2747 SDOperand Result; // Initially, NULL result
Scott Michel266bc8f2007-12-04 22:23:35 +00002748
2749 switch (N->getOpcode()) {
2750 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002751 case ISD::ADD: {
Scott Michel053c1da2008-01-29 02:16:57 +00002752 SDOperand Op1 = N->getOperand(1);
2753
Scott Michel8bf61e82008-06-02 22:18:03 +00002754 if (isa<ConstantSDNode>(Op1) && Op0.getOpcode() == SPUISD::IndirectAddr) {
Scott Michel053c1da2008-01-29 02:16:57 +00002755 SDOperand Op01 = Op0.getOperand(1);
2756 if (Op01.getOpcode() == ISD::Constant
2757 || Op01.getOpcode() == ISD::TargetConstant) {
2758 // (add <const>, (SPUindirect <arg>, <const>)) ->
2759 // (SPUindirect <arg>, <const + const>)
2760 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op1);
2761 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op01);
2762 SDOperand combinedConst =
2763 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2764 Op0.getValueType());
2765
2766 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2767 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2768 DEBUG(cerr << "With: (SPUindirect <arg>, "
2769 << CN0->getValue() + CN1->getValue() << ")\n");
2770 return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(),
2771 Op0.getOperand(0), combinedConst);
2772 }
Scott Michel8bf61e82008-06-02 22:18:03 +00002773 } else if (isa<ConstantSDNode>(Op0)
Scott Michel053c1da2008-01-29 02:16:57 +00002774 && Op1.getOpcode() == SPUISD::IndirectAddr) {
2775 SDOperand Op11 = Op1.getOperand(1);
2776 if (Op11.getOpcode() == ISD::Constant
2777 || Op11.getOpcode() == ISD::TargetConstant) {
2778 // (add (SPUindirect <arg>, <const>), <const>) ->
2779 // (SPUindirect <arg>, <const + const>)
2780 ConstantSDNode *CN0 = cast<ConstantSDNode>(Op0);
2781 ConstantSDNode *CN1 = cast<ConstantSDNode>(Op11);
2782 SDOperand combinedConst =
2783 DAG.getConstant(CN0->getValue() + CN1->getValue(),
2784 Op0.getValueType());
2785
2786 DEBUG(cerr << "Replace: (add " << CN0->getValue() << ", "
2787 << "(SPUindirect <arg>, " << CN1->getValue() << "))\n");
2788 DEBUG(cerr << "With: (SPUindirect <arg>, "
2789 << CN0->getValue() + CN1->getValue() << ")\n");
2790
2791 return DAG.getNode(SPUISD::IndirectAddr, Op1.getValueType(),
2792 Op1.getOperand(0), combinedConst);
2793 }
2794 }
Scott Michela59d4692008-02-23 18:41:37 +00002795 break;
2796 }
2797 case ISD::SIGN_EXTEND:
2798 case ISD::ZERO_EXTEND:
2799 case ISD::ANY_EXTEND: {
2800 if (Op0.getOpcode() == SPUISD::EXTRACT_ELT0 &&
2801 N->getValueType(0) == Op0.getValueType()) {
2802 // (any_extend (SPUextract_elt0 <arg>)) ->
2803 // (SPUextract_elt0 <arg>)
2804 // Types must match, however...
2805 DEBUG(cerr << "Replace: ");
2806 DEBUG(N->dump(&DAG));
2807 DEBUG(cerr << "\nWith: ");
2808 DEBUG(Op0.Val->dump(&DAG));
2809 DEBUG(cerr << "\n");
2810
2811 return Op0;
2812 }
2813 break;
2814 }
2815 case SPUISD::IndirectAddr: {
2816 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2817 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
2818 if (CN->getValue() == 0) {
2819 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2820 // (SPUaform <addr>, 0)
2821
2822 DEBUG(cerr << "Replace: ");
2823 DEBUG(N->dump(&DAG));
2824 DEBUG(cerr << "\nWith: ");
2825 DEBUG(Op0.Val->dump(&DAG));
2826 DEBUG(cerr << "\n");
2827
2828 return Op0;
2829 }
2830 }
2831 break;
2832 }
2833 case SPUISD::SHLQUAD_L_BITS:
2834 case SPUISD::SHLQUAD_L_BYTES:
2835 case SPUISD::VEC_SHL:
2836 case SPUISD::VEC_SRL:
2837 case SPUISD::VEC_SRA:
2838 case SPUISD::ROTQUAD_RZ_BYTES:
2839 case SPUISD::ROTQUAD_RZ_BITS: {
2840 SDOperand Op1 = N->getOperand(1);
2841
2842 if (isa<ConstantSDNode>(Op1)) {
2843 // Kill degenerate vector shifts:
2844 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
2845
2846 if (CN->getValue() == 0) {
2847 Result = Op0;
2848 }
2849 }
2850 break;
2851 }
2852 case SPUISD::PROMOTE_SCALAR: {
2853 switch (Op0.getOpcode()) {
2854 default:
2855 break;
2856 case ISD::ANY_EXTEND:
2857 case ISD::ZERO_EXTEND:
2858 case ISD::SIGN_EXTEND: {
2859 // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 <arg>))) ->
2860 // <arg>
2861 // but only if the SPUpromote_scalar and <arg> types match.
2862 SDOperand Op00 = Op0.getOperand(0);
2863 if (Op00.getOpcode() == SPUISD::EXTRACT_ELT0) {
2864 SDOperand Op000 = Op00.getOperand(0);
2865 if (Op000.getValueType() == N->getValueType(0)) {
2866 Result = Op000;
2867 }
2868 }
2869 break;
2870 }
2871 case SPUISD::EXTRACT_ELT0: {
2872 // (SPUpromote_scalar (SPUextract_elt0 <arg>)) ->
2873 // <arg>
2874 Result = Op0.getOperand(0);
2875 break;
2876 }
2877 }
2878 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002879 }
2880 }
Scott Michel58c58182008-01-17 20:38:41 +00002881 // Otherwise, return unchanged.
Scott Michel203b2d62008-04-30 00:30:08 +00002882#if 1
Scott Michela59d4692008-02-23 18:41:37 +00002883 if (Result.Val) {
2884 DEBUG(cerr << "\nReplace.SPU: ");
2885 DEBUG(N->dump(&DAG));
2886 DEBUG(cerr << "\nWith: ");
2887 DEBUG(Result.Val->dump(&DAG));
2888 DEBUG(cerr << "\n");
2889 }
2890#endif
2891
2892 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002893}
2894
2895//===----------------------------------------------------------------------===//
2896// Inline Assembly Support
2897//===----------------------------------------------------------------------===//
2898
2899/// getConstraintType - Given a constraint letter, return the type of
2900/// constraint it is for this target.
2901SPUTargetLowering::ConstraintType
2902SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2903 if (ConstraintLetter.size() == 1) {
2904 switch (ConstraintLetter[0]) {
2905 default: break;
2906 case 'b':
2907 case 'r':
2908 case 'f':
2909 case 'v':
2910 case 'y':
2911 return C_RegisterClass;
2912 }
2913 }
2914 return TargetLowering::getConstraintType(ConstraintLetter);
2915}
2916
2917std::pair<unsigned, const TargetRegisterClass*>
2918SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002919 MVT VT) const
Scott Michel266bc8f2007-12-04 22:23:35 +00002920{
2921 if (Constraint.size() == 1) {
2922 // GCC RS6000 Constraint Letters
2923 switch (Constraint[0]) {
2924 case 'b': // R1-R31
2925 case 'r': // R0-R31
2926 if (VT == MVT::i64)
2927 return std::make_pair(0U, SPU::R64CRegisterClass);
2928 return std::make_pair(0U, SPU::R32CRegisterClass);
2929 case 'f':
2930 if (VT == MVT::f32)
2931 return std::make_pair(0U, SPU::R32FPRegisterClass);
2932 else if (VT == MVT::f64)
2933 return std::make_pair(0U, SPU::R64FPRegisterClass);
2934 break;
2935 case 'v':
2936 return std::make_pair(0U, SPU::GPRCRegisterClass);
2937 }
2938 }
2939
2940 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2941}
2942
Scott Michela59d4692008-02-23 18:41:37 +00002943//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002944void
2945SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002946 const APInt &Mask,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002947 APInt &KnownZero,
2948 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002949 const SelectionDAG &DAG,
2950 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00002951#if 0
Scott Michela59d4692008-02-23 18:41:37 +00002952 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michel203b2d62008-04-30 00:30:08 +00002953#endif
Scott Michela59d4692008-02-23 18:41:37 +00002954
2955 switch (Op.getOpcode()) {
2956 default:
2957 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2958 break;
2959
2960#if 0
2961 case CALL:
2962 case SHUFB:
2963 case INSERT_MASK:
2964 case CNTB:
2965#endif
2966
2967 case SPUISD::PROMOTE_SCALAR: {
2968 SDOperand Op0 = Op.getOperand(0);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002969 MVT Op0VT = Op0.getValueType();
2970 unsigned Op0VTBits = Op0VT.getSizeInBits();
2971 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michel203b2d62008-04-30 00:30:08 +00002972 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2973 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002974 break;
2975 }
2976
2977 case SPUISD::LDRESULT:
2978 case SPUISD::EXTRACT_ELT0:
2979 case SPUISD::EXTRACT_ELT0_CHAINED: {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002980 MVT OpVT = Op.getValueType();
2981 unsigned OpVTBits = OpVT.getSizeInBits();
2982 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michel203b2d62008-04-30 00:30:08 +00002983 KnownZero |= APInt(OpVTBits, ~InMask, false);
2984 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002985 break;
2986 }
2987
2988#if 0
2989 case EXTRACT_I1_ZEXT:
2990 case EXTRACT_I1_SEXT:
2991 case EXTRACT_I8_ZEXT:
2992 case EXTRACT_I8_SEXT:
2993 case MPY:
2994 case MPYU:
2995 case MPYH:
2996 case MPYHH:
Scott Michel203b2d62008-04-30 00:30:08 +00002997 case SPUISD::SHLQUAD_L_BITS:
2998 case SPUISD::SHLQUAD_L_BYTES:
2999 case SPUISD::VEC_SHL:
3000 case SPUISD::VEC_SRL:
3001 case SPUISD::VEC_SRA:
3002 case SPUISD::VEC_ROTL:
3003 case SPUISD::VEC_ROTR:
3004 case SPUISD::ROTQUAD_RZ_BYTES:
3005 case SPUISD::ROTQUAD_RZ_BITS:
3006 case SPUISD::ROTBYTES_RIGHT_S:
3007 case SPUISD::ROTBYTES_LEFT:
3008 case SPUISD::ROTBYTES_LEFT_CHAINED:
Scott Michel8bf61e82008-06-02 22:18:03 +00003009 case SPUISD::SELECT_MASK:
3010 case SPUISD::SELB:
3011 case SPUISD::FPInterp:
3012 case SPUISD::FPRecipEst:
3013 case SPUISD::SEXT32TO64:
Scott Michela59d4692008-02-23 18:41:37 +00003014#endif
3015 }
Scott Michel266bc8f2007-12-04 22:23:35 +00003016}
3017
Scott Michel203b2d62008-04-30 00:30:08 +00003018// LowerAsmOperandForConstraint
3019void
3020SPUTargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
3021 char ConstraintLetter,
3022 std::vector<SDOperand> &Ops,
3023 SelectionDAG &DAG) const {
3024 // Default, for the time being, to the base class handler
3025 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, Ops, DAG);
3026}
3027
Scott Michel266bc8f2007-12-04 22:23:35 +00003028/// isLegalAddressImmediate - Return true if the integer value can be used
3029/// as the offset of the target addressing mode.
3030bool SPUTargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
3031 // SPU's addresses are 256K:
3032 return (V > -(1 << 18) && V < (1 << 18) - 1);
3033}
3034
3035bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
3036 return false;
3037}