blob: 9dd98558509b618b82f388aeb7d878028e6e2fd5 [file] [log] [blame]
Scott Michel6e22c652007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-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 Michel6e22c652007-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 Michelc3a19102008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel82335272008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel6e22c652007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michel6e22c652007-12-04 22:23:35 +000020#include "llvm/CodeGen/CallingConvLower.h"
21#include "llvm/CodeGen/MachineFrameInfo.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattnera10fff52007-12-31 04:13:23 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel6e22c652007-12-04 22:23:35 +000025#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel6e22c652007-12-04 22:23:35 +000026#include "llvm/Constants.h"
27#include "llvm/Function.h"
28#include "llvm/Intrinsics.h"
29#include "llvm/Support/Debug.h"
30#include "llvm/Support/MathExtras.h"
31#include "llvm/Target/TargetOptions.h"
32
33#include <map>
34
35using namespace llvm;
36
37// Used in getTargetNodeName() below
38namespace {
39 std::map<unsigned, const char *> node_names;
40
Duncan Sands13237ac2008-06-06 12:08:01 +000041 //! MVT mapping to useful data for Cell SPU
Scott Michel6e22c652007-12-04 22:23:35 +000042 struct valtype_map_s {
Scott Michel0be03392008-11-22 23:50:42 +000043 const MVT valtype;
44 const int prefslot_byte;
Scott Michel6e22c652007-12-04 22:23:35 +000045 };
Scott Michelfe095082008-07-16 17:17:29 +000046
Scott Michel6e22c652007-12-04 22:23:35 +000047 const valtype_map_s valtype_map[] = {
48 { MVT::i1, 3 },
49 { MVT::i8, 3 },
50 { MVT::i16, 2 },
51 { MVT::i32, 0 },
52 { MVT::f32, 0 },
53 { MVT::i64, 0 },
54 { MVT::f64, 0 },
55 { MVT::i128, 0 }
56 };
57
58 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
59
Duncan Sands13237ac2008-06-06 12:08:01 +000060 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel6e22c652007-12-04 22:23:35 +000061 const valtype_map_s *retval = 0;
62
63 for (size_t i = 0; i < n_valtype_map; ++i) {
64 if (valtype_map[i].valtype == VT) {
Scott Michelbb713ae2008-01-30 02:55:46 +000065 retval = valtype_map + i;
66 break;
Scott Michel6e22c652007-12-04 22:23:35 +000067 }
68 }
69
70#ifndef NDEBUG
71 if (retval == 0) {
72 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands13237ac2008-06-06 12:08:01 +000073 << VT.getMVTString()
Scott Michelbb713ae2008-01-30 02:55:46 +000074 << "\n";
Scott Michel6e22c652007-12-04 22:23:35 +000075 abort();
76 }
77#endif
78
79 return retval;
80 }
Scott Michel6e22c652007-12-04 22:23:35 +000081}
82
83SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
84 : TargetLowering(TM),
85 SPUTM(TM)
86{
87 // Fold away setcc operations if possible.
88 setPow2DivIsCheap();
89
90 // Use _setjmp/_longjmp instead of setjmp/longjmp.
91 setUseUnderscoreSetJmp(true);
92 setUseUnderscoreLongJmp(true);
Scott Michelfe095082008-07-16 17:17:29 +000093
Scott Michel6e22c652007-12-04 22:23:35 +000094 // Set up the SPU's register classes:
Scott Michelc5cccb92007-12-17 22:32:34 +000095 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
96 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
97 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
98 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
99 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
100 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel6e22c652007-12-04 22:23:35 +0000101 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michelfe095082008-07-16 17:17:29 +0000102
Scott Michel6e22c652007-12-04 22:23:35 +0000103 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng07d53b12008-10-14 21:26:46 +0000104 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
105 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
106 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +0000107
Scott Michel82335272008-12-27 04:51:36 +0000108 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
109 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michel73640252008-12-02 19:53:53 +0000110
Scott Michel6e22c652007-12-04 22:23:35 +0000111 // SPU constant load actions are custom lowered:
112 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begeman4b3210a2008-02-14 18:43:04 +0000113 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000114 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
115
116 // SPU's loads and stores have to be custom lowered:
Scott Michel6887caf2009-01-06 03:36:14 +0000117 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel6e22c652007-12-04 22:23:35 +0000118 ++sctype) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000119 MVT VT = (MVT::SimpleValueType)sctype;
120
Scott Michel82335272008-12-27 04:51:36 +0000121 setOperationAction(ISD::LOAD, VT, Custom);
122 setOperationAction(ISD::STORE, VT, Custom);
123 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
124 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
125 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
126
Scott Michelb8ee30d2008-12-29 03:23:36 +0000127 // SMUL_LOHI, UMUL_LOHI are not legal for Cell:
128 setOperationAction(ISD::SMUL_LOHI, VT, Expand);
129 setOperationAction(ISD::UMUL_LOHI, VT, Expand);
130
Scott Michel82335272008-12-27 04:51:36 +0000131 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
132 MVT StoreVT = (MVT::SimpleValueType) stype;
133 setTruncStoreAction(VT, StoreVT, Expand);
134 }
Scott Michel6e22c652007-12-04 22:23:35 +0000135 }
136
Scott Michel82335272008-12-27 04:51:36 +0000137 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
138 ++sctype) {
139 MVT VT = (MVT::SimpleValueType) sctype;
140
141 setOperationAction(ISD::LOAD, VT, Custom);
142 setOperationAction(ISD::STORE, VT, Custom);
143
144 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
145 MVT StoreVT = (MVT::SimpleValueType) stype;
146 setTruncStoreAction(VT, StoreVT, Expand);
147 }
148 }
149
Scott Michel6e22c652007-12-04 22:23:35 +0000150 // Expand the jumptable branches
151 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
152 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel0be03392008-11-22 23:50:42 +0000153
154 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michelfe095082008-07-16 17:17:29 +0000155 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel0be03392008-11-22 23:50:42 +0000156 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
157 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
158 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
159 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000160
161 // SPU has no intrinsics for these particular operations:
Andrew Lenharthfedcf472008-02-16 14:46:26 +0000162 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
163
Scott Michel82335272008-12-27 04:51:36 +0000164 // SPU has no SREM/UREM instructions
Scott Michel6e22c652007-12-04 22:23:35 +0000165 setOperationAction(ISD::SREM, MVT::i32, Expand);
166 setOperationAction(ISD::UREM, MVT::i32, Expand);
167 setOperationAction(ISD::SREM, MVT::i64, Expand);
168 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000169
Scott Michel6e22c652007-12-04 22:23:35 +0000170 // We don't support sin/cos/sqrt/fmod
171 setOperationAction(ISD::FSIN , MVT::f64, Expand);
172 setOperationAction(ISD::FCOS , MVT::f64, Expand);
173 setOperationAction(ISD::FREM , MVT::f64, Expand);
174 setOperationAction(ISD::FSIN , MVT::f32, Expand);
175 setOperationAction(ISD::FCOS , MVT::f32, Expand);
176 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000177
Scott Michel6e22c652007-12-04 22:23:35 +0000178 // If we're enabling GP optimizations, use hardware square root
179 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
180 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000181
Scott Michel6e22c652007-12-04 22:23:35 +0000182 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
183 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
184
185 // SPU can do rotate right and left, so legalize it... but customize for i8
186 // because instructions don't exist.
Bill Wendlingaebd2662008-08-31 02:59:23 +0000187
188 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
189 // .td files.
190 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
191 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
192 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
193
Scott Michel6e22c652007-12-04 22:23:35 +0000194 setOperationAction(ISD::ROTL, MVT::i32, Legal);
195 setOperationAction(ISD::ROTL, MVT::i16, Legal);
196 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Michel3726019a2008-11-20 16:36:33 +0000197
Scott Michel6e22c652007-12-04 22:23:35 +0000198 // SPU has no native version of shift left/right for i8
199 setOperationAction(ISD::SHL, MVT::i8, Custom);
200 setOperationAction(ISD::SRL, MVT::i8, Custom);
201 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michelc6918c12008-11-21 02:56:16 +0000202
Scott Michel41236c02008-12-30 23:28:25 +0000203 // Make these operations legal and handle them during instruction selection:
204 setOperationAction(ISD::SHL, MVT::i64, Legal);
205 setOperationAction(ISD::SRL, MVT::i64, Legal);
206 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000207
Scott Michelfe095082008-07-16 17:17:29 +0000208 // Custom lower i8, i32 and i64 multiplications
209 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000210 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michelc6918c12008-11-21 02:56:16 +0000211 setOperationAction(ISD::MUL, MVT::i64, Expand); // libcall
212
Scott Micheld831cc42008-06-02 22:18:03 +0000213 // Need to custom handle (some) common i8, i64 math ops
Scott Michel41236c02008-12-30 23:28:25 +0000214 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Micheld831cc42008-06-02 22:18:03 +0000215 setOperationAction(ISD::ADD, MVT::i64, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000216 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Micheld831cc42008-06-02 22:18:03 +0000217 setOperationAction(ISD::SUB, MVT::i64, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000218
Scott Michel6e22c652007-12-04 22:23:35 +0000219 // SPU does not have BSWAP. It does have i32 support CTLZ.
220 // CTPOP has to be custom lowered.
221 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
222 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
223
224 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
225 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
226 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
227 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
228
229 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
230 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
231
232 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michelfe095082008-07-16 17:17:29 +0000233
Scott Micheld831cc42008-06-02 22:18:03 +0000234 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel92275422008-03-10 23:49:09 +0000235 // select ought to work:
Scott Michel48e33752008-03-10 16:58:52 +0000236 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel42f56b42008-03-05 23:02:02 +0000237 setOperationAction(ISD::SELECT, MVT::i16, Legal);
238 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel82335272008-12-27 04:51:36 +0000239 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000240
Scott Michel48e33752008-03-10 16:58:52 +0000241 setOperationAction(ISD::SETCC, MVT::i8, Legal);
242 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000243 setOperationAction(ISD::SETCC, MVT::i32, Legal);
244 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel42f56b42008-03-05 23:02:02 +0000245
Scott Michel7d5eaec2008-02-23 18:41:37 +0000246 // Zero extension and sign extension for i64 have to be
247 // custom legalized
248 setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000249 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000250
Scott Michel82335272008-12-27 04:51:36 +0000251 // Custom lower i128 -> i64 truncates
Scott Michel73640252008-12-02 19:53:53 +0000252 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
253
Scott Michel6e22c652007-12-04 22:23:35 +0000254 // SPU has a legal FP -> signed INT instruction
255 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
256 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
257 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
258 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
259
260 // FDIV on SPU requires custom lowering
Scott Michel82335272008-12-27 04:51:36 +0000261 setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall
Scott Michel6e22c652007-12-04 22:23:35 +0000262
263 // SPU has [U|S]INT_TO_FP
264 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
265 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
266 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
267 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
268 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
269 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
270 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
271 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
272
Scott Michel5f1470f2007-12-20 00:44:13 +0000273 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
274 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
275 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
276 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000277
278 // We cannot sextinreg(i1). Expand to shifts.
279 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000280
Scott Michel6e22c652007-12-04 22:23:35 +0000281 // Support label based line numbers.
Dan Gohman5c73a882008-06-30 20:59:49 +0000282 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000283 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000284
285 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel6e22c652007-12-04 22:23:35 +0000286 // appropriate instructions to materialize the address.
Scott Michelc6918c12008-11-21 02:56:16 +0000287 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelceae3bb2008-01-29 02:16:57 +0000288 ++sctype) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000289 MVT VT = (MVT::SimpleValueType)sctype;
290
Scott Michelb8ee30d2008-12-29 03:23:36 +0000291 setOperationAction(ISD::GlobalAddress, VT, Custom);
292 setOperationAction(ISD::ConstantPool, VT, Custom);
293 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelceae3bb2008-01-29 02:16:57 +0000294 }
Scott Michel6e22c652007-12-04 22:23:35 +0000295
296 // RET must be custom lowered, to meet ABI requirements
297 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000298
Scott Michel6e22c652007-12-04 22:23:35 +0000299 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
300 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000301
Scott Michel6e22c652007-12-04 22:23:35 +0000302 // Use the default implementation.
303 setOperationAction(ISD::VAARG , MVT::Other, Expand);
304 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
305 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000306 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000307 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
308 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
309 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
310
311 // Cell SPU has instructions for converting between i64 and fp.
312 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
313 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000314
Scott Michel6e22c652007-12-04 22:23:35 +0000315 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
316 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
317
318 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
319 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
320
321 // First set operation action for all vector types to expand. Then we
322 // will selectively turn on ones that can be effectively codegen'd.
323 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
324 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
325 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
326 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
327 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
328 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
329
Scott Michel494daa72009-01-06 23:10:38 +0000330 // "Odd size" vector classes that we're willing to support:
331 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
332
Duncan Sands13237ac2008-06-06 12:08:01 +0000333 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
334 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
335 MVT VT = (MVT::SimpleValueType)i;
Scott Michel6e22c652007-12-04 22:23:35 +0000336
Duncan Sands13237ac2008-06-06 12:08:01 +0000337 // add/sub are legal for all supported vector VT's.
338 setOperationAction(ISD::ADD , VT, Legal);
339 setOperationAction(ISD::SUB , VT, Legal);
340 // mul has to be custom lowered.
Scott Michel41236c02008-12-30 23:28:25 +0000341 // TODO: v2i64 vector multiply
342 setOperationAction(ISD::MUL , VT, Legal);
Duncan Sands13237ac2008-06-06 12:08:01 +0000343
344 setOperationAction(ISD::AND , VT, Legal);
345 setOperationAction(ISD::OR , VT, Legal);
346 setOperationAction(ISD::XOR , VT, Legal);
347 setOperationAction(ISD::LOAD , VT, Legal);
348 setOperationAction(ISD::SELECT, VT, Legal);
349 setOperationAction(ISD::STORE, VT, Legal);
Scott Michelfe095082008-07-16 17:17:29 +0000350
Scott Michel6e22c652007-12-04 22:23:35 +0000351 // These operations need to be expanded:
Duncan Sands13237ac2008-06-06 12:08:01 +0000352 setOperationAction(ISD::SDIV, VT, Expand);
353 setOperationAction(ISD::SREM, VT, Expand);
354 setOperationAction(ISD::UDIV, VT, Expand);
355 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000356
357 // Custom lower build_vector, constant pool spills, insert and
358 // extract vector elements:
Duncan Sands13237ac2008-06-06 12:08:01 +0000359 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
360 setOperationAction(ISD::ConstantPool, VT, Custom);
361 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
362 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
363 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
364 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000365 }
366
Scott Michel6e22c652007-12-04 22:23:35 +0000367 setOperationAction(ISD::AND, MVT::v16i8, Custom);
368 setOperationAction(ISD::OR, MVT::v16i8, Custom);
369 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
370 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel8d5841a2008-01-11 02:53:15 +0000371
Scott Michel41236c02008-12-30 23:28:25 +0000372 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000373
Scott Michel6e22c652007-12-04 22:23:35 +0000374 setShiftAmountType(MVT::i32);
Scott Michel82335272008-12-27 04:51:36 +0000375 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michelfe095082008-07-16 17:17:29 +0000376
Scott Michel6e22c652007-12-04 22:23:35 +0000377 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michelfe095082008-07-16 17:17:29 +0000378
Scott Michel6e22c652007-12-04 22:23:35 +0000379 // We have target-specific dag combine patterns for the following nodes:
Scott Michelceae3bb2008-01-29 02:16:57 +0000380 setTargetDAGCombine(ISD::ADD);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000381 setTargetDAGCombine(ISD::ZERO_EXTEND);
382 setTargetDAGCombine(ISD::SIGN_EXTEND);
383 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michelfe095082008-07-16 17:17:29 +0000384
Scott Michel6e22c652007-12-04 22:23:35 +0000385 computeRegisterProperties();
Scott Michel0be03392008-11-22 23:50:42 +0000386
Scott Michel8deac5d2008-12-09 03:37:19 +0000387 // Set pre-RA register scheduler default to BURR, which produces slightly
388 // better code than the default (could also be TDRR, but TargetLowering.h
389 // needs a mod to support that model):
390 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel6e22c652007-12-04 22:23:35 +0000391}
392
393const char *
394SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
395{
396 if (node_names.empty()) {
397 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
398 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
399 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
400 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel8d5841a2008-01-11 02:53:15 +0000401 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelceae3bb2008-01-29 02:16:57 +0000402 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel6e22c652007-12-04 22:23:35 +0000403 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
404 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
405 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel0be03392008-11-22 23:50:42 +0000406 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel6e22c652007-12-04 22:23:35 +0000407 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelb8ee30d2008-12-29 03:23:36 +0000408 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelefc8c7a2008-11-24 17:11:17 +0000409 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel7d5eaec2008-02-23 18:41:37 +0000410 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
411 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel6e22c652007-12-04 22:23:35 +0000412 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
413 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
414 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
415 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
416 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Micheld831cc42008-06-02 22:18:03 +0000417 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel6e22c652007-12-04 22:23:35 +0000418 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Micheld831cc42008-06-02 22:18:03 +0000419 node_names[(unsigned) SPUISD::ADD_EXTENDED] = "SPUISD::ADD_EXTENDED";
420 node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
421 node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
422 node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
Scott Michel6e22c652007-12-04 22:23:35 +0000423 }
424
425 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
426
427 return ((i != node_names.end()) ? i->second : 0);
428}
429
Scott Michel82335272008-12-27 04:51:36 +0000430//===----------------------------------------------------------------------===//
431// Return the Cell SPU's SETCC result type
432//===----------------------------------------------------------------------===//
433
Duncan Sands8feb6942009-01-01 15:52:00 +0000434MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel82335272008-12-27 04:51:36 +0000435 // i16 and i32 are valid SETCC result types
436 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel48e33752008-03-10 16:58:52 +0000437}
438
Scott Michel6e22c652007-12-04 22:23:35 +0000439//===----------------------------------------------------------------------===//
440// Calling convention code:
441//===----------------------------------------------------------------------===//
442
443#include "SPUGenCallingConv.inc"
444
445//===----------------------------------------------------------------------===//
446// LowerOperation implementation
447//===----------------------------------------------------------------------===//
448
449/// Custom lower loads for CellSPU
450/*!
451 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
452 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel40f54d22008-12-04 03:02:42 +0000453
454 For extending loads, we also want to ensure that the following sequence is
455 emitted, e.g. for MVT::f32 extending load to MVT::f64:
456
457\verbatim
Scott Michelb8ee30d2008-12-29 03:23:36 +0000458%1 v16i8,ch = load
Scott Michel40f54d22008-12-04 03:02:42 +0000459%2 v16i8,ch = rotate %1
Scott Michelb8ee30d2008-12-29 03:23:36 +0000460%3 v4f8, ch = bitconvert %2
Scott Michel40f54d22008-12-04 03:02:42 +0000461%4 f32 = vec2perfslot %3
462%5 f64 = fp_extend %4
463\endverbatim
464*/
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000465static SDValue
466LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel6e22c652007-12-04 22:23:35 +0000467 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000468 SDValue the_chain = LN->getChain();
Scott Michel82335272008-12-27 04:51:36 +0000469 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel40f54d22008-12-04 03:02:42 +0000470 MVT InVT = LN->getMemoryVT();
471 MVT OutVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000472 ISD::LoadExtType ExtType = LN->getExtensionType();
473 unsigned alignment = LN->getAlignment();
Scott Michel82335272008-12-27 04:51:36 +0000474 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel6e22c652007-12-04 22:23:35 +0000475
Scott Michel6e22c652007-12-04 22:23:35 +0000476 switch (LN->getAddressingMode()) {
477 case ISD::UNINDEXED: {
Scott Michel82335272008-12-27 04:51:36 +0000478 SDValue result;
479 SDValue basePtr = LN->getBasePtr();
480 SDValue rotate;
Scott Michel6e22c652007-12-04 22:23:35 +0000481
Scott Michel82335272008-12-27 04:51:36 +0000482 if (alignment == 16) {
483 ConstantSDNode *CN;
Scott Michel8d5841a2008-01-11 02:53:15 +0000484
Scott Michel82335272008-12-27 04:51:36 +0000485 // Special cases for a known aligned load to simplify the base pointer
486 // and the rotation amount:
487 if (basePtr.getOpcode() == ISD::ADD
488 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
489 // Known offset into basePtr
490 int64_t offset = CN->getSExtValue();
491 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Michel8d5841a2008-01-11 02:53:15 +0000492
Scott Michel82335272008-12-27 04:51:36 +0000493 if (rotamt < 0)
494 rotamt += 16;
495
496 rotate = DAG.getConstant(rotamt, MVT::i16);
497
498 // Simplify the base pointer for this case:
499 basePtr = basePtr.getOperand(0);
500 if ((offset & ~0xf) > 0) {
501 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
502 basePtr,
503 DAG.getConstant((offset & ~0xf), PtrVT));
504 }
505 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
506 || (basePtr.getOpcode() == SPUISD::IndirectAddr
507 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
508 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
509 // Plain aligned a-form address: rotate into preferred slot
510 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
511 int64_t rotamt = -vtm->prefslot_byte;
512 if (rotamt < 0)
513 rotamt += 16;
514 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Michel8d5841a2008-01-11 02:53:15 +0000515 } else {
Scott Michel82335272008-12-27 04:51:36 +0000516 // Offset the rotate amount by the basePtr and the preferred slot
517 // byte offset
518 int64_t rotamt = -vtm->prefslot_byte;
519 if (rotamt < 0)
520 rotamt += 16;
521 rotate = DAG.getNode(ISD::ADD, PtrVT,
522 basePtr,
Scott Michelbb713ae2008-01-30 02:55:46 +0000523 DAG.getConstant(rotamt, PtrVT));
Scott Michel8d5841a2008-01-11 02:53:15 +0000524 }
Scott Michel82335272008-12-27 04:51:36 +0000525 } else {
526 // Unaligned load: must be more pessimistic about addressing modes:
527 if (basePtr.getOpcode() == ISD::ADD) {
528 MachineFunction &MF = DAG.getMachineFunction();
529 MachineRegisterInfo &RegInfo = MF.getRegInfo();
530 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
531 SDValue Flag;
Scott Michel8d5841a2008-01-11 02:53:15 +0000532
Scott Michel82335272008-12-27 04:51:36 +0000533 SDValue Op0 = basePtr.getOperand(0);
534 SDValue Op1 = basePtr.getOperand(1);
535
536 if (isa<ConstantSDNode>(Op1)) {
537 // Convert the (add <ptr>, <const>) to an indirect address contained
538 // in a register. Note that this is done because we need to avoid
539 // creating a 0(reg) d-form address due to the SPU's block loads.
540 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
541 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
542 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
543 } else {
544 // Convert the (add <arg1>, <arg2>) to an indirect address, which
545 // will likely be lowered as a reg(reg) x-form address.
546 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
547 }
548 } else {
549 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
550 basePtr,
551 DAG.getConstant(0, PtrVT));
552 }
553
554 // Offset the rotate amount by the basePtr and the preferred slot
555 // byte offset
556 rotate = DAG.getNode(ISD::ADD, PtrVT,
557 basePtr,
558 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel6e22c652007-12-04 22:23:35 +0000559 }
Scott Michel8d5841a2008-01-11 02:53:15 +0000560
Scott Michel82335272008-12-27 04:51:36 +0000561 // Re-emit as a v16i8 vector load
562 result = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
563 LN->getSrcValue(), LN->getSrcValueOffset(),
564 LN->isVolatile(), 16);
565
566 // Update the chain
567 the_chain = result.getValue(1);
568
569 // Rotate into the preferred slot:
570 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8,
571 result.getValue(0), rotate);
572
Scott Michel40f54d22008-12-04 03:02:42 +0000573 // Convert the loaded v16i8 vector to the appropriate vector type
574 // specified by the operand:
575 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
576 result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
577 DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
Scott Michelfe095082008-07-16 17:17:29 +0000578
Scott Michel40f54d22008-12-04 03:02:42 +0000579 // Handle extending loads by extending the scalar result:
580 if (ExtType == ISD::SEXTLOAD) {
581 result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result);
582 } else if (ExtType == ISD::ZEXTLOAD) {
583 result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result);
584 } else if (ExtType == ISD::EXTLOAD) {
585 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Michel8d5841a2008-01-11 02:53:15 +0000586
Scott Michel40f54d22008-12-04 03:02:42 +0000587 if (OutVT.isFloatingPoint())
588 NewOpc = ISD::FP_EXTEND;
Scott Michel8d5841a2008-01-11 02:53:15 +0000589
Scott Michel40f54d22008-12-04 03:02:42 +0000590 result = DAG.getNode(NewOpc, OutVT, result);
Scott Michel8d5841a2008-01-11 02:53:15 +0000591 }
592
Scott Michel40f54d22008-12-04 03:02:42 +0000593 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000594 SDValue retops[2] = {
Scott Michele4d3e3c2008-01-17 20:38:41 +0000595 result,
Scott Michelbb713ae2008-01-30 02:55:46 +0000596 the_chain
Scott Michele4d3e3c2008-01-17 20:38:41 +0000597 };
Scott Michel8d5841a2008-01-11 02:53:15 +0000598
Scott Michele4d3e3c2008-01-17 20:38:41 +0000599 result = DAG.getNode(SPUISD::LDRESULT, retvts,
600 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel8d5841a2008-01-11 02:53:15 +0000601 return result;
Scott Michel6e22c652007-12-04 22:23:35 +0000602 }
603 case ISD::PRE_INC:
604 case ISD::PRE_DEC:
605 case ISD::POST_INC:
606 case ISD::POST_DEC:
607 case ISD::LAST_INDEXED_MODE:
608 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
609 "UNINDEXED\n";
610 cerr << (unsigned) LN->getAddressingMode() << "\n";
611 abort();
612 /*NOTREACHED*/
613 }
614
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000615 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000616}
617
618/// Custom lower stores for CellSPU
619/*!
620 All CellSPU stores are aligned to 16-byte boundaries, so for elements
621 within a 16-byte block, we have to generate a shuffle to insert the
622 requested element into its place, then store the resulting block.
623 */
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000624static SDValue
625LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel6e22c652007-12-04 22:23:35 +0000626 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000627 SDValue Value = SN->getValue();
Duncan Sands13237ac2008-06-06 12:08:01 +0000628 MVT VT = Value.getValueType();
629 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
630 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8d5841a2008-01-11 02:53:15 +0000631 unsigned alignment = SN->getAlignment();
Scott Michel6e22c652007-12-04 22:23:35 +0000632
633 switch (SN->getAddressingMode()) {
634 case ISD::UNINDEXED: {
Scott Michelc6918c12008-11-21 02:56:16 +0000635 // The vector type we really want to load from the 16-byte chunk.
Scott Michelef5e6932008-11-19 17:45:08 +0000636 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
637 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel6e22c652007-12-04 22:23:35 +0000638
Scott Michel82335272008-12-27 04:51:36 +0000639 SDValue alignLoadVec;
640 SDValue basePtr = SN->getBasePtr();
641 SDValue the_chain = SN->getChain();
642 SDValue insertEltOffs;
Scott Michel6e22c652007-12-04 22:23:35 +0000643
Scott Michel82335272008-12-27 04:51:36 +0000644 if (alignment == 16) {
645 ConstantSDNode *CN;
646
647 // Special cases for a known aligned load to simplify the base pointer
648 // and insertion byte:
649 if (basePtr.getOpcode() == ISD::ADD
650 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
651 // Known offset into basePtr
652 int64_t offset = CN->getSExtValue();
653
654 // Simplify the base pointer for this case:
655 basePtr = basePtr.getOperand(0);
656 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
657 basePtr,
658 DAG.getConstant((offset & 0xf), PtrVT));
659
660 if ((offset & ~0xf) > 0) {
661 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
662 basePtr,
663 DAG.getConstant((offset & ~0xf), PtrVT));
664 }
665 } else {
666 // Otherwise, assume it's at byte 0 of basePtr
667 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
668 basePtr,
669 DAG.getConstant(0, PtrVT));
670 }
671 } else {
672 // Unaligned load: must be more pessimistic about addressing modes:
673 if (basePtr.getOpcode() == ISD::ADD) {
674 MachineFunction &MF = DAG.getMachineFunction();
675 MachineRegisterInfo &RegInfo = MF.getRegInfo();
676 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
677 SDValue Flag;
678
679 SDValue Op0 = basePtr.getOperand(0);
680 SDValue Op1 = basePtr.getOperand(1);
681
682 if (isa<ConstantSDNode>(Op1)) {
683 // Convert the (add <ptr>, <const>) to an indirect address contained
684 // in a register. Note that this is done because we need to avoid
685 // creating a 0(reg) d-form address due to the SPU's block loads.
686 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
687 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
688 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
689 } else {
690 // Convert the (add <arg1>, <arg2>) to an indirect address, which
691 // will likely be lowered as a reg(reg) x-form address.
692 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
693 }
694 } else {
695 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
696 basePtr,
697 DAG.getConstant(0, PtrVT));
698 }
699
700 // Insertion point is solely determined by basePtr's contents
701 insertEltOffs = DAG.getNode(ISD::ADD, PtrVT,
702 basePtr,
703 DAG.getConstant(0, PtrVT));
704 }
705
706 // Re-emit as a v16i8 vector load
707 alignLoadVec = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
708 SN->getSrcValue(), SN->getSrcValueOffset(),
709 SN->isVolatile(), 16);
710
711 // Update the chain
712 the_chain = alignLoadVec.getValue(1);
Scott Michel6e22c652007-12-04 22:23:35 +0000713
Scott Michel8d5841a2008-01-11 02:53:15 +0000714 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000715 SDValue theValue = SN->getValue();
716 SDValue result;
Scott Michel6e22c652007-12-04 22:23:35 +0000717
718 if (StVT != VT
Scott Michelbb713ae2008-01-30 02:55:46 +0000719 && (theValue.getOpcode() == ISD::AssertZext
720 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel6e22c652007-12-04 22:23:35 +0000721 // Drill down and get the value for zero- and sign-extended
722 // quantities
Scott Michelfe095082008-07-16 17:17:29 +0000723 theValue = theValue.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +0000724 }
725
Scott Michel8d5841a2008-01-11 02:53:15 +0000726 // If the base pointer is already a D-form address, then just create
727 // a new D-form address with a slot offset and the orignal base pointer.
728 // Otherwise generate a D-form address with the slot offset relative
729 // to the stack pointer, which is always aligned.
Scott Michel82335272008-12-27 04:51:36 +0000730#if !defined(NDEBUG)
731 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
732 cerr << "CellSPU LowerSTORE: basePtr = ";
733 basePtr.getNode()->dump(&DAG);
734 cerr << "\n";
735 }
736#endif
Scott Michel8d5841a2008-01-11 02:53:15 +0000737
Scott Michel3462c8e2008-11-19 15:24:16 +0000738 SDValue insertEltOp =
Scott Michel82335272008-12-27 04:51:36 +0000739 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michelef5e6932008-11-19 17:45:08 +0000740 SDValue vectorizeOp =
741 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michel3462c8e2008-11-19 15:24:16 +0000742
Scott Michel08a4e202008-12-01 17:56:02 +0000743 result = DAG.getNode(SPUISD::SHUFB, vecVT,
744 vectorizeOp, alignLoadVec,
745 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
Scott Michel6e22c652007-12-04 22:23:35 +0000746
Scott Michel8d5841a2008-01-11 02:53:15 +0000747 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel6e22c652007-12-04 22:23:35 +0000748 LN->getSrcValue(), LN->getSrcValueOffset(),
749 LN->isVolatile(), LN->getAlignment());
750
Scott Michel187250b2008-12-04 17:16:59 +0000751#if 0 && !defined(NDEBUG)
Scott Michel3462c8e2008-11-19 15:24:16 +0000752 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
753 const SDValue &currentRoot = DAG.getRoot();
754
755 DAG.setRoot(result);
756 cerr << "------- CellSPU:LowerStore result:\n";
757 DAG.dump();
758 cerr << "-------\n";
759 DAG.setRoot(currentRoot);
760 }
761#endif
Scott Michel73640252008-12-02 19:53:53 +0000762
Scott Michel6e22c652007-12-04 22:23:35 +0000763 return result;
764 /*UNREACHED*/
765 }
766 case ISD::PRE_INC:
767 case ISD::PRE_DEC:
768 case ISD::POST_INC:
769 case ISD::POST_DEC:
770 case ISD::LAST_INDEXED_MODE:
771 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
772 "UNINDEXED\n";
773 cerr << (unsigned) SN->getAddressingMode() << "\n";
774 abort();
775 /*NOTREACHED*/
776 }
777
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000778 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000779}
780
781/// Generate the address of a constant pool entry.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000782static SDValue
783LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000784 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000785 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
786 Constant *C = CP->getConstVal();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000787 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
788 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8d5841a2008-01-11 02:53:15 +0000789 const TargetMachine &TM = DAG.getTarget();
Scott Michel6e22c652007-12-04 22:23:35 +0000790
791 if (TM.getRelocationModel() == Reloc::Static) {
792 if (!ST->usingLargeMem()) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000793 // Just return the SDValue with the constant pool address in it.
Scott Michele4d3e3c2008-01-17 20:38:41 +0000794 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel6e22c652007-12-04 22:23:35 +0000795 } else {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000796 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
797 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000798 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel6e22c652007-12-04 22:23:35 +0000799 }
800 }
801
802 assert(0 &&
Gabor Greif81d6a382008-08-31 15:37:04 +0000803 "LowerConstantPool: Relocation model other than static"
804 " not supported.");
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000805 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000806}
807
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000808static SDValue
809LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000810 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000811 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000812 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
813 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel6e22c652007-12-04 22:23:35 +0000814 const TargetMachine &TM = DAG.getTarget();
815
816 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel7d5eaec2008-02-23 18:41:37 +0000817 if (!ST->usingLargeMem()) {
818 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
819 } else {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000820 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
821 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000822 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
823 }
Scott Michel6e22c652007-12-04 22:23:35 +0000824 }
825
826 assert(0 &&
827 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000828 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000829}
830
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000831static SDValue
832LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000833 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000834 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
835 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000836 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel6e22c652007-12-04 22:23:35 +0000837 const TargetMachine &TM = DAG.getTarget();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000838 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michelfe095082008-07-16 17:17:29 +0000839
Scott Michel6e22c652007-12-04 22:23:35 +0000840 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelceae3bb2008-01-29 02:16:57 +0000841 if (!ST->usingLargeMem()) {
842 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
843 } else {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000844 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
845 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
Scott Michelceae3bb2008-01-29 02:16:57 +0000846 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
847 }
Scott Michel6e22c652007-12-04 22:23:35 +0000848 } else {
849 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michelbb713ae2008-01-30 02:55:46 +0000850 << "supported.\n";
Scott Michel6e22c652007-12-04 22:23:35 +0000851 abort();
852 /*NOTREACHED*/
853 }
854
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000855 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000856}
857
858//! Custom lower i64 integer constants
859/*!
860 This code inserts all of the necessary juggling that needs to occur to load
861 a 64-bit constant into a register.
862 */
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000863static SDValue
864LowerConstant(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000865 MVT VT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000866
867 if (VT == MVT::i64) {
Scott Michel08a4e202008-12-01 17:56:02 +0000868 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
869 SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michelefc8c7a2008-11-24 17:11:17 +0000870 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michelbb713ae2008-01-30 02:55:46 +0000871 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel6e22c652007-12-04 22:23:35 +0000872 } else {
873 cerr << "LowerConstant: unhandled constant type "
Duncan Sands13237ac2008-06-06 12:08:01 +0000874 << VT.getMVTString()
Scott Michelbb713ae2008-01-30 02:55:46 +0000875 << "\n";
Scott Michel6e22c652007-12-04 22:23:35 +0000876 abort();
877 /*NOTREACHED*/
878 }
879
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000880 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000881}
882
Nate Begeman4b3210a2008-02-14 18:43:04 +0000883//! Custom lower double precision floating point constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000884static SDValue
885LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000886 MVT VT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000887
Nate Begeman4b3210a2008-02-14 18:43:04 +0000888 if (VT == MVT::f64) {
Scott Michel08a4e202008-12-01 17:56:02 +0000889 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
890
891 assert((FP != 0) &&
892 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelb8ee30d2008-12-29 03:23:36 +0000893
Scott Michel098c1132007-12-19 20:15:47 +0000894 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel08a4e202008-12-01 17:56:02 +0000895 SDValue T = DAG.getConstant(dbits, MVT::i64);
896 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T);
897 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
898 DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec));
Scott Michel6e22c652007-12-04 22:23:35 +0000899 }
900
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000901 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000902}
903
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000904static SDValue
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000905LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel6e22c652007-12-04 22:23:35 +0000906{
907 MachineFunction &MF = DAG.getMachineFunction();
908 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera10fff52007-12-31 04:13:23 +0000909 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel487c4342008-10-30 01:51:48 +0000910 SmallVector<SDValue, 48> ArgValues;
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000911 SDValue Root = Op.getOperand(0);
Dan Gohmaneffb8942008-09-12 16:56:44 +0000912 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel6e22c652007-12-04 22:23:35 +0000913
914 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
915 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michelfe095082008-07-16 17:17:29 +0000916
Scott Michel6e22c652007-12-04 22:23:35 +0000917 unsigned ArgOffset = SPUFrameInfo::minStackSize();
918 unsigned ArgRegIdx = 0;
919 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michelfe095082008-07-16 17:17:29 +0000920
Duncan Sands13237ac2008-06-06 12:08:01 +0000921 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michelfe095082008-07-16 17:17:29 +0000922
Scott Michel6e22c652007-12-04 22:23:35 +0000923 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif81d6a382008-08-31 15:37:04 +0000924 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
925 ArgNo != e; ++ArgNo) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000926 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
927 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michel487c4342008-10-30 01:51:48 +0000928 SDValue ArgVal;
Scott Michel6e22c652007-12-04 22:23:35 +0000929
Scott Michel487c4342008-10-30 01:51:48 +0000930 if (ArgRegIdx < NumArgRegs) {
931 const TargetRegisterClass *ArgRegClass;
Scott Michelfe095082008-07-16 17:17:29 +0000932
Scott Michel487c4342008-10-30 01:51:48 +0000933 switch (ObjectVT.getSimpleVT()) {
934 default: {
Scott Michelc6918c12008-11-21 02:56:16 +0000935 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
936 << ObjectVT.getMVTString()
937 << "\n";
938 abort();
Scott Michel487c4342008-10-30 01:51:48 +0000939 }
940 case MVT::i8:
Scott Michelc6918c12008-11-21 02:56:16 +0000941 ArgRegClass = &SPU::R8CRegClass;
942 break;
Scott Michel487c4342008-10-30 01:51:48 +0000943 case MVT::i16:
Scott Michelc6918c12008-11-21 02:56:16 +0000944 ArgRegClass = &SPU::R16CRegClass;
945 break;
Scott Michel487c4342008-10-30 01:51:48 +0000946 case MVT::i32:
Scott Michelc6918c12008-11-21 02:56:16 +0000947 ArgRegClass = &SPU::R32CRegClass;
948 break;
Scott Michel487c4342008-10-30 01:51:48 +0000949 case MVT::i64:
Scott Michelc6918c12008-11-21 02:56:16 +0000950 ArgRegClass = &SPU::R64CRegClass;
951 break;
Scott Michel6887caf2009-01-06 03:36:14 +0000952 case MVT::i128:
953 ArgRegClass = &SPU::GPRCRegClass;
954 break;
Scott Michel487c4342008-10-30 01:51:48 +0000955 case MVT::f32:
Scott Michelc6918c12008-11-21 02:56:16 +0000956 ArgRegClass = &SPU::R32FPRegClass;
957 break;
Scott Michel487c4342008-10-30 01:51:48 +0000958 case MVT::f64:
Scott Michelc6918c12008-11-21 02:56:16 +0000959 ArgRegClass = &SPU::R64FPRegClass;
960 break;
Scott Michel487c4342008-10-30 01:51:48 +0000961 case MVT::v2f64:
962 case MVT::v4f32:
963 case MVT::v2i64:
964 case MVT::v4i32:
965 case MVT::v8i16:
966 case MVT::v16i8:
Scott Michelc6918c12008-11-21 02:56:16 +0000967 ArgRegClass = &SPU::VECREGRegClass;
968 break;
Scott Michel487c4342008-10-30 01:51:48 +0000969 }
970
971 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
972 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
973 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
974 ++ArgRegIdx;
975 } else {
976 // We need to load the argument to a virtual register if we determined
977 // above that we ran out of physical registers of the appropriate type
978 // or we're forced to do vararg
Chris Lattnerf6518cf2008-02-13 07:35:30 +0000979 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000980 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattnerf6518cf2008-02-13 07:35:30 +0000981 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel6e22c652007-12-04 22:23:35 +0000982 ArgOffset += StackSlotSize;
983 }
Scott Michelfe095082008-07-16 17:17:29 +0000984
Scott Michel6e22c652007-12-04 22:23:35 +0000985 ArgValues.push_back(ArgVal);
Scott Michel487c4342008-10-30 01:51:48 +0000986 // Update the chain
987 Root = ArgVal.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +0000988 }
Scott Michelfe095082008-07-16 17:17:29 +0000989
Scott Michel487c4342008-10-30 01:51:48 +0000990 // vararg handling:
Scott Michel6e22c652007-12-04 22:23:35 +0000991 if (isVarArg) {
Scott Michel487c4342008-10-30 01:51:48 +0000992 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
993 // We will spill (79-3)+1 registers to the stack
994 SmallVector<SDValue, 79-3+1> MemOps;
995
996 // Create the frame slot
997
Scott Michel6e22c652007-12-04 22:23:35 +0000998 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michel487c4342008-10-30 01:51:48 +0000999 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1000 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1001 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
1002 SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
1003 Root = Store.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +00001004 MemOps.push_back(Store);
Scott Michel487c4342008-10-30 01:51:48 +00001005
1006 // Increment address by stack slot size for the next stored argument
1007 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001008 }
1009 if (!MemOps.empty())
Scott Michel487c4342008-10-30 01:51:48 +00001010 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001011 }
Scott Michelfe095082008-07-16 17:17:29 +00001012
Scott Michel6e22c652007-12-04 22:23:35 +00001013 ArgValues.push_back(Root);
Scott Michelfe095082008-07-16 17:17:29 +00001014
Scott Michel6e22c652007-12-04 22:23:35 +00001015 // Return the new list of results.
Duncan Sands3d960942008-12-01 11:41:29 +00001016 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1017 &ArgValues[0], ArgValues.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001018}
1019
1020/// isLSAAddress - Return the immediate to use if the specified
1021/// value is representable as a LSA address.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001022static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michelaab89ca2008-11-11 03:06:06 +00001023 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel6e22c652007-12-04 22:23:35 +00001024 if (!C) return 0;
Scott Michelfe095082008-07-16 17:17:29 +00001025
Dan Gohmaneffb8942008-09-12 16:56:44 +00001026 int Addr = C->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001027 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1028 (Addr << 14 >> 14) != Addr)
1029 return 0; // Top 14 bits have to be sext of immediate.
Scott Michelfe095082008-07-16 17:17:29 +00001030
Dan Gohmaneffb8942008-09-12 16:56:44 +00001031 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel6e22c652007-12-04 22:23:35 +00001032}
1033
Scott Michel494daa72009-01-06 23:10:38 +00001034static SDValue
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001035LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohmand3fe1742008-09-13 01:54:27 +00001036 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1037 SDValue Chain = TheCall->getChain();
Dan Gohmand3fe1742008-09-13 01:54:27 +00001038 SDValue Callee = TheCall->getCallee();
1039 unsigned NumOps = TheCall->getNumArgs();
Scott Michel6e22c652007-12-04 22:23:35 +00001040 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1041 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1042 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1043
1044 // Handy pointer type
Duncan Sands13237ac2008-06-06 12:08:01 +00001045 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michelfe095082008-07-16 17:17:29 +00001046
Scott Michel6e22c652007-12-04 22:23:35 +00001047 // Accumulate how many bytes are to be pushed on the stack, including the
1048 // linkage area, and parameter passing area. According to the SPU ABI,
1049 // we minimally need space for [LR] and [SP]
1050 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michelfe095082008-07-16 17:17:29 +00001051
Scott Michel6e22c652007-12-04 22:23:35 +00001052 // Set up a copy of the stack pointer for use loading and storing any
1053 // arguments that may not fit in the registers available for argument
1054 // passing.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001055 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michelfe095082008-07-16 17:17:29 +00001056
Scott Michel6e22c652007-12-04 22:23:35 +00001057 // Figure out which arguments are going to go in registers, and which in
1058 // memory.
1059 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1060 unsigned ArgRegIdx = 0;
1061
1062 // Keep track of registers passing arguments
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001063 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel6e22c652007-12-04 22:23:35 +00001064 // And the arguments passed on the stack
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001065 SmallVector<SDValue, 8> MemOpChains;
Scott Michel6e22c652007-12-04 22:23:35 +00001066
1067 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohmand3fe1742008-09-13 01:54:27 +00001068 SDValue Arg = TheCall->getArg(i);
Scott Michelfe095082008-07-16 17:17:29 +00001069
Scott Michel6e22c652007-12-04 22:23:35 +00001070 // PtrOff will be used to store the current argument to the stack if a
1071 // register cannot be found for it.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001072 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel6e22c652007-12-04 22:23:35 +00001073 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1074
Duncan Sands13237ac2008-06-06 12:08:01 +00001075 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001076 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel6887caf2009-01-06 03:36:14 +00001077 case MVT::i8:
1078 case MVT::i16:
Scott Michel6e22c652007-12-04 22:23:35 +00001079 case MVT::i32:
1080 case MVT::i64:
1081 case MVT::i128:
1082 if (ArgRegIdx != NumArgRegs) {
1083 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1084 } else {
1085 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001086 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001087 }
1088 break;
1089 case MVT::f32:
1090 case MVT::f64:
1091 if (ArgRegIdx != NumArgRegs) {
1092 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1093 } else {
1094 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001095 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001096 }
1097 break;
Scott Michelea3c49d2008-12-04 21:01:44 +00001098 case MVT::v2i64:
1099 case MVT::v2f64:
Scott Michel6e22c652007-12-04 22:23:35 +00001100 case MVT::v4f32:
1101 case MVT::v4i32:
1102 case MVT::v8i16:
1103 case MVT::v16i8:
1104 if (ArgRegIdx != NumArgRegs) {
1105 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1106 } else {
1107 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001108 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001109 }
1110 break;
1111 }
1112 }
1113
1114 // Update number of stack bytes actually used, insert a call sequence start
1115 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattner27539552008-10-11 22:08:30 +00001116 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1117 true));
Scott Michel6e22c652007-12-04 22:23:35 +00001118
1119 if (!MemOpChains.empty()) {
1120 // Adjust the stack pointer for the stack arguments.
1121 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1122 &MemOpChains[0], MemOpChains.size());
1123 }
Scott Michelfe095082008-07-16 17:17:29 +00001124
Scott Michel6e22c652007-12-04 22:23:35 +00001125 // Build a sequence of copy-to-reg nodes chained together with token chain
1126 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001127 SDValue InFlag;
Scott Michel6e22c652007-12-04 22:23:35 +00001128 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1129 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1130 InFlag);
1131 InFlag = Chain.getValue(1);
1132 }
Scott Michelfe095082008-07-16 17:17:29 +00001133
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001134 SmallVector<SDValue, 8> Ops;
Scott Michel6e22c652007-12-04 22:23:35 +00001135 unsigned CallOpc = SPUISD::CALL;
Scott Michelfe095082008-07-16 17:17:29 +00001136
Bill Wendling24c79f22008-09-16 21:48:12 +00001137 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1138 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1139 // node so that legalize doesn't hack it.
Scott Michelaab89ca2008-11-11 03:06:06 +00001140 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001141 GlobalValue *GV = G->getGlobal();
Duncan Sands13237ac2008-06-06 12:08:01 +00001142 MVT CalleeVT = Callee.getValueType();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001143 SDValue Zero = DAG.getConstant(0, PtrVT);
1144 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel6e22c652007-12-04 22:23:35 +00001145
Scott Michel8d5841a2008-01-11 02:53:15 +00001146 if (!ST->usingLargeMem()) {
1147 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1148 // style calls, otherwise, external symbols are BRASL calls. This assumes
1149 // that declared/defined symbols are in the same compilation unit and can
1150 // be reached through PC-relative jumps.
1151 //
1152 // NOTE:
1153 // This may be an unsafe assumption for JIT and really large compilation
1154 // units.
1155 if (GV->isDeclaration()) {
1156 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1157 } else {
1158 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1159 }
Scott Michel6e22c652007-12-04 22:23:35 +00001160 } else {
Scott Michel8d5841a2008-01-11 02:53:15 +00001161 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1162 // address pairs:
Scott Michelceae3bb2008-01-29 02:16:57 +00001163 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel6e22c652007-12-04 22:23:35 +00001164 }
Scott Michelb8ee30d2008-12-29 03:23:36 +00001165 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1166 MVT CalleeVT = Callee.getValueType();
1167 SDValue Zero = DAG.getConstant(0, PtrVT);
1168 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1169 Callee.getValueType());
1170
1171 if (!ST->usingLargeMem()) {
1172 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, ExtSym, Zero);
1173 } else {
1174 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, ExtSym, Zero);
1175 }
1176 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001177 // If this is an absolute destination address that appears to be a legal
1178 // local store address, use the munged value.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001179 Callee = SDValue(Dest, 0);
Scott Michel8d5841a2008-01-11 02:53:15 +00001180 }
Scott Michel6e22c652007-12-04 22:23:35 +00001181
1182 Ops.push_back(Chain);
1183 Ops.push_back(Callee);
Scott Michelfe095082008-07-16 17:17:29 +00001184
Scott Michel6e22c652007-12-04 22:23:35 +00001185 // Add argument registers to the end of the list so that they are known live
1186 // into the call.
1187 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michelfe095082008-07-16 17:17:29 +00001188 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel6e22c652007-12-04 22:23:35 +00001189 RegsToPass[i].second.getValueType()));
Scott Michelfe095082008-07-16 17:17:29 +00001190
Gabor Greiff304a7a2008-08-28 21:40:38 +00001191 if (InFlag.getNode())
Scott Michel6e22c652007-12-04 22:23:35 +00001192 Ops.push_back(InFlag);
Duncan Sands739a0542008-07-02 17:40:58 +00001193 // Returns a chain and a flag for retval copy to use.
1194 Chain = DAG.getNode(CallOpc, DAG.getVTList(MVT::Other, MVT::Flag),
1195 &Ops[0], Ops.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001196 InFlag = Chain.getValue(1);
1197
Chris Lattner27539552008-10-11 22:08:30 +00001198 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1199 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohmand3fe1742008-09-13 01:54:27 +00001200 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng0f329162008-02-05 22:44:06 +00001201 InFlag = Chain.getValue(1);
1202
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001203 SDValue ResultVals[3];
Scott Michel6e22c652007-12-04 22:23:35 +00001204 unsigned NumResults = 0;
Scott Michelfe095082008-07-16 17:17:29 +00001205
Scott Michel6e22c652007-12-04 22:23:35 +00001206 // If the call has results, copy the values out of the ret val registers.
Dan Gohmand3fe1742008-09-13 01:54:27 +00001207 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001208 default: assert(0 && "Unexpected ret value!");
1209 case MVT::Other: break;
1210 case MVT::i32:
Dan Gohmand3fe1742008-09-13 01:54:27 +00001211 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel6e22c652007-12-04 22:23:35 +00001212 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1213 ResultVals[0] = Chain.getValue(0);
1214 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1215 Chain.getValue(2)).getValue(1);
1216 ResultVals[1] = Chain.getValue(0);
1217 NumResults = 2;
Scott Michel6e22c652007-12-04 22:23:35 +00001218 } else {
1219 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1220 ResultVals[0] = Chain.getValue(0);
1221 NumResults = 1;
1222 }
Scott Michel6e22c652007-12-04 22:23:35 +00001223 break;
1224 case MVT::i64:
1225 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1226 ResultVals[0] = Chain.getValue(0);
1227 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001228 break;
Scott Michel6887caf2009-01-06 03:36:14 +00001229 case MVT::i128:
1230 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
1231 ResultVals[0] = Chain.getValue(0);
1232 NumResults = 1;
1233 break;
Scott Michel6e22c652007-12-04 22:23:35 +00001234 case MVT::f32:
1235 case MVT::f64:
Dan Gohmand3fe1742008-09-13 01:54:27 +00001236 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel6e22c652007-12-04 22:23:35 +00001237 InFlag).getValue(1);
1238 ResultVals[0] = Chain.getValue(0);
1239 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001240 break;
1241 case MVT::v2f64:
Scott Michelea3c49d2008-12-04 21:01:44 +00001242 case MVT::v2i64:
Scott Michel6e22c652007-12-04 22:23:35 +00001243 case MVT::v4f32:
1244 case MVT::v4i32:
1245 case MVT::v8i16:
1246 case MVT::v16i8:
Dan Gohmand3fe1742008-09-13 01:54:27 +00001247 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel6e22c652007-12-04 22:23:35 +00001248 InFlag).getValue(1);
1249 ResultVals[0] = Chain.getValue(0);
1250 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001251 break;
1252 }
Duncan Sands739a0542008-07-02 17:40:58 +00001253
Scott Michel6e22c652007-12-04 22:23:35 +00001254 // If the function returns void, just return the chain.
1255 if (NumResults == 0)
1256 return Chain;
Scott Michelfe095082008-07-16 17:17:29 +00001257
Scott Michel6e22c652007-12-04 22:23:35 +00001258 // Otherwise, merge everything together with a MERGE_VALUES node.
1259 ResultVals[NumResults++] = Chain;
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001260 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greifabfdf922008-08-26 22:36:50 +00001261 return Res.getValue(Op.getResNo());
Scott Michel6e22c652007-12-04 22:23:35 +00001262}
1263
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001264static SDValue
1265LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel6e22c652007-12-04 22:23:35 +00001266 SmallVector<CCValAssign, 16> RVLocs;
1267 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1268 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1269 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greiff304a7a2008-08-28 21:40:38 +00001270 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michelfe095082008-07-16 17:17:29 +00001271
Scott Michel6e22c652007-12-04 22:23:35 +00001272 // If this is the first return lowered for this function, add the regs to the
1273 // liveout set for the function.
Chris Lattnera10fff52007-12-31 04:13:23 +00001274 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001275 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattnera10fff52007-12-31 04:13:23 +00001276 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel6e22c652007-12-04 22:23:35 +00001277 }
1278
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001279 SDValue Chain = Op.getOperand(0);
1280 SDValue Flag;
Scott Michelfe095082008-07-16 17:17:29 +00001281
Scott Michel6e22c652007-12-04 22:23:35 +00001282 // Copy the result values into the output registers.
1283 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1284 CCValAssign &VA = RVLocs[i];
1285 assert(VA.isRegLoc() && "Can only return in registers!");
1286 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1287 Flag = Chain.getValue(1);
1288 }
1289
Gabor Greiff304a7a2008-08-28 21:40:38 +00001290 if (Flag.getNode())
Scott Michel6e22c652007-12-04 22:23:35 +00001291 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1292 else
1293 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1294}
1295
1296
1297//===----------------------------------------------------------------------===//
1298// Vector related lowering:
1299//===----------------------------------------------------------------------===//
1300
1301static ConstantSDNode *
1302getVecImm(SDNode *N) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001303 SDValue OpVal(0, 0);
Scott Michelfe095082008-07-16 17:17:29 +00001304
Scott Michel6e22c652007-12-04 22:23:35 +00001305 // Check to see if this buildvec has a single non-undef value in its elements.
1306 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1307 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greiff304a7a2008-08-28 21:40:38 +00001308 if (OpVal.getNode() == 0)
Scott Michel6e22c652007-12-04 22:23:35 +00001309 OpVal = N->getOperand(i);
1310 else if (OpVal != N->getOperand(i))
1311 return 0;
1312 }
Scott Michelfe095082008-07-16 17:17:29 +00001313
Gabor Greiff304a7a2008-08-28 21:40:38 +00001314 if (OpVal.getNode() != 0) {
Scott Michelaab89ca2008-11-11 03:06:06 +00001315 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001316 return CN;
1317 }
1318 }
1319
1320 return 0; // All UNDEF: use implicit def.; not Constant node
1321}
1322
1323/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1324/// and the value fits into an unsigned 18-bit constant, and if so, return the
1325/// constant
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001326SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001327 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001328 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001329 uint64_t Value = CN->getZExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001330 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001331 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001332 uint32_t upper = uint32_t(UValue >> 32);
1333 uint32_t lower = uint32_t(UValue);
1334 if (upper != lower)
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001335 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001336 Value = Value >> 32;
1337 }
Scott Michel6e22c652007-12-04 22:23:35 +00001338 if (Value <= 0x3ffff)
Dan Gohmanfd820522008-11-05 02:06:09 +00001339 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001340 }
1341
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001342 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001343}
1344
1345/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1346/// and the value fits into a signed 16-bit constant, and if so, return the
1347/// constant
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001348SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001349 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001350 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman6e054832008-09-26 21:54:37 +00001351 int64_t Value = CN->getSExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001352 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001353 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001354 uint32_t upper = uint32_t(UValue >> 32);
1355 uint32_t lower = uint32_t(UValue);
1356 if (upper != lower)
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001357 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001358 Value = Value >> 32;
1359 }
Scott Michel42f56b42008-03-05 23:02:02 +00001360 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001361 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001362 }
1363 }
1364
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001365 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001366}
1367
1368/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1369/// and the value fits into a signed 10-bit constant, and if so, return the
1370/// constant
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001371SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001372 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001373 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman6e054832008-09-26 21:54:37 +00001374 int64_t Value = CN->getSExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001375 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001376 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001377 uint32_t upper = uint32_t(UValue >> 32);
1378 uint32_t lower = uint32_t(UValue);
1379 if (upper != lower)
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001380 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001381 Value = Value >> 32;
1382 }
Scott Michel42f56b42008-03-05 23:02:02 +00001383 if (isS10Constant(Value))
Dan Gohmanfd820522008-11-05 02:06:09 +00001384 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001385 }
1386
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001387 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001388}
1389
1390/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1391/// and the value fits into a signed 8-bit constant, and if so, return the
1392/// constant.
1393///
1394/// @note: The incoming vector is v16i8 because that's the only way we can load
1395/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1396/// same value.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001397SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001398 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001399 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001400 int Value = (int) CN->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001401 if (ValueType == MVT::i16
Scott Michelbb713ae2008-01-30 02:55:46 +00001402 && Value <= 0xffff /* truncated from uint64_t */
1403 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfd820522008-11-05 02:06:09 +00001404 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001405 else if (ValueType == MVT::i8
Scott Michelbb713ae2008-01-30 02:55:46 +00001406 && (Value & 0xff) == Value)
Dan Gohmanfd820522008-11-05 02:06:09 +00001407 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001408 }
1409
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001410 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001411}
1412
1413/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1414/// and the value fits into a signed 16-bit constant, and if so, return the
1415/// constant
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001416SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001417 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001418 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001419 uint64_t Value = CN->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001420 if ((ValueType == MVT::i32
Scott Michelbb713ae2008-01-30 02:55:46 +00001421 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1422 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfd820522008-11-05 02:06:09 +00001423 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001424 }
1425
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001426 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001427}
1428
1429/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001430SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel6e22c652007-12-04 22:23:35 +00001431 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001432 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00001433 }
1434
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001435 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001436}
1437
1438/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001439SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel6e22c652007-12-04 22:23:35 +00001440 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001441 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel6e22c652007-12-04 22:23:35 +00001442 }
1443
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001444 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001445}
1446
1447// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michelfe095082008-07-16 17:17:29 +00001448// UndefBits is set if the corresponding element of the vector is an
Scott Michel6e22c652007-12-04 22:23:35 +00001449// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1450// zero. Return true if this is not an array of constants, false if it is.
1451//
1452static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1453 uint64_t UndefBits[2]) {
1454 // Start with zero'd results.
1455 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
Scott Michelfe095082008-07-16 17:17:29 +00001456
Duncan Sands13237ac2008-06-06 12:08:01 +00001457 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel6e22c652007-12-04 22:23:35 +00001458 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001459 SDValue OpVal = BV->getOperand(i);
Scott Michelfe095082008-07-16 17:17:29 +00001460
Scott Michel6e22c652007-12-04 22:23:35 +00001461 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1462 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1463
1464 uint64_t EltBits = 0;
1465 if (OpVal.getOpcode() == ISD::UNDEF) {
1466 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1467 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1468 continue;
Scott Michelaab89ca2008-11-11 03:06:06 +00001469 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001470 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michelaab89ca2008-11-11 03:06:06 +00001471 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001472 const APFloat &apf = CN->getValueAPF();
1473 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michelbb713ae2008-01-30 02:55:46 +00001474 ? FloatToBits(apf.convertToFloat())
1475 : DoubleToBits(apf.convertToDouble()));
Scott Michel6e22c652007-12-04 22:23:35 +00001476 } else {
1477 // Nonconstant element.
1478 return true;
1479 }
Scott Michelfe095082008-07-16 17:17:29 +00001480
Scott Michel6e22c652007-12-04 22:23:35 +00001481 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1482 }
Scott Michelfe095082008-07-16 17:17:29 +00001483
1484 //printf("%llx %llx %llx %llx\n",
Scott Michel6e22c652007-12-04 22:23:35 +00001485 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1486 return false;
1487}
1488
1489/// If this is a splat (repetition) of a value across the whole vector, return
1490/// the smallest size that splats it. For example, "0x01010101010101..." is a
Scott Michelfe095082008-07-16 17:17:29 +00001491/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel6e22c652007-12-04 22:23:35 +00001492/// SplatSize = 1 byte.
Scott Michelfe095082008-07-16 17:17:29 +00001493static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel6e22c652007-12-04 22:23:35 +00001494 const uint64_t Undef128[2],
Scott Michelbb713ae2008-01-30 02:55:46 +00001495 int MinSplatBits,
Scott Michel6e22c652007-12-04 22:23:35 +00001496 uint64_t &SplatBits, uint64_t &SplatUndef,
1497 int &SplatSize) {
1498 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1499 // the same as the lower 64-bits, ignoring undefs.
1500 uint64_t Bits64 = Bits128[0] | Bits128[1];
1501 uint64_t Undef64 = Undef128[0] & Undef128[1];
1502 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1503 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1504 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1505 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1506
1507 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1508 if (MinSplatBits < 64) {
Scott Michelfe095082008-07-16 17:17:29 +00001509
Scott Michel6e22c652007-12-04 22:23:35 +00001510 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1511 // undefs.
1512 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michelbb713ae2008-01-30 02:55:46 +00001513 if (MinSplatBits < 32) {
Scott Michel6e22c652007-12-04 22:23:35 +00001514
Scott Michelbb713ae2008-01-30 02:55:46 +00001515 // If the top 16-bits are different than the lower 16-bits, ignoring
1516 // undefs, we have an i32 splat.
1517 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1518 if (MinSplatBits < 16) {
1519 // If the top 8-bits are different than the lower 8-bits, ignoring
1520 // undefs, we have an i16 splat.
Gabor Greif81d6a382008-08-31 15:37:04 +00001521 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1522 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michelbb713ae2008-01-30 02:55:46 +00001523 // Otherwise, we have an 8-bit splat.
1524 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1525 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1526 SplatSize = 1;
1527 return true;
1528 }
1529 } else {
1530 SplatBits = Bits16;
1531 SplatUndef = Undef16;
1532 SplatSize = 2;
1533 return true;
1534 }
1535 }
1536 } else {
1537 SplatBits = Bits32;
1538 SplatUndef = Undef32;
1539 SplatSize = 4;
1540 return true;
1541 }
Scott Michel6e22c652007-12-04 22:23:35 +00001542 }
1543 } else {
1544 SplatBits = Bits128[0];
1545 SplatUndef = Undef128[0];
1546 SplatSize = 8;
1547 return true;
1548 }
1549 }
1550
1551 return false; // Can't be a splat if two pieces don't match.
1552}
1553
1554// If this is a case we can't handle, return null and let the default
1555// expansion code take care of it. If we CAN select this case, and if it
1556// selects to a single instruction, return Op. Otherwise, if we can codegen
1557// this case more efficiently than a constant pool load, lower it to the
1558// sequence of ops that should be used.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001559static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00001560 MVT VT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +00001561 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michelfe095082008-07-16 17:17:29 +00001562 // UndefBits is set if the corresponding element of the vector is an
Scott Michel6e22c652007-12-04 22:23:35 +00001563 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michelfe095082008-07-16 17:17:29 +00001564 // zero.
Scott Michel6e22c652007-12-04 22:23:35 +00001565 uint64_t VectorBits[2];
1566 uint64_t UndefBits[2];
1567 uint64_t SplatBits, SplatUndef;
1568 int SplatSize;
Gabor Greiff304a7a2008-08-28 21:40:38 +00001569 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel6e22c652007-12-04 22:23:35 +00001570 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands13237ac2008-06-06 12:08:01 +00001571 VT.getVectorElementType().getSizeInBits(),
Scott Michel6e22c652007-12-04 22:23:35 +00001572 SplatBits, SplatUndef, SplatSize))
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001573 return SDValue(); // Not a constant vector, not a splat.
Scott Michelfe095082008-07-16 17:17:29 +00001574
Duncan Sands13237ac2008-06-06 12:08:01 +00001575 switch (VT.getSimpleVT()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001576 default:
1577 case MVT::v4f32: {
1578 uint32_t Value32 = SplatBits;
1579 assert(SplatSize == 4
Scott Michelbb713ae2008-01-30 02:55:46 +00001580 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel6e22c652007-12-04 22:23:35 +00001581 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001582 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00001583 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michelbb713ae2008-01-30 02:55:46 +00001584 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel6e22c652007-12-04 22:23:35 +00001585 break;
1586 }
1587 case MVT::v2f64: {
1588 uint64_t f64val = SplatBits;
1589 assert(SplatSize == 8
Scott Michelefc8c7a2008-11-24 17:11:17 +00001590 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel6e22c652007-12-04 22:23:35 +00001591 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001592 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel6e22c652007-12-04 22:23:35 +00001593 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michelbb713ae2008-01-30 02:55:46 +00001594 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel6e22c652007-12-04 22:23:35 +00001595 break;
1596 }
1597 case MVT::v16i8: {
1598 // 8-bit constants have to be expanded to 16-bits
1599 unsigned short Value16 = SplatBits | (SplatBits << 8);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001600 SDValue Ops[8];
Scott Michel6e22c652007-12-04 22:23:35 +00001601 for (int i = 0; i < 8; ++i)
1602 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1603 return DAG.getNode(ISD::BIT_CONVERT, VT,
1604 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1605 }
1606 case MVT::v8i16: {
1607 unsigned short Value16;
Scott Michelfe095082008-07-16 17:17:29 +00001608 if (SplatSize == 2)
Scott Michel6e22c652007-12-04 22:23:35 +00001609 Value16 = (unsigned short) (SplatBits & 0xffff);
1610 else
1611 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001612 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1613 SDValue Ops[8];
Scott Michel6e22c652007-12-04 22:23:35 +00001614 for (int i = 0; i < 8; ++i) Ops[i] = T;
1615 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1616 }
1617 case MVT::v4i32: {
1618 unsigned int Value = SplatBits;
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001619 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel6e22c652007-12-04 22:23:35 +00001620 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1621 }
Scott Michel494daa72009-01-06 23:10:38 +00001622 case MVT::v2i32: {
1623 unsigned int Value = SplatBits;
1624 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
1625 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
1626 }
Scott Michel6e22c652007-12-04 22:23:35 +00001627 case MVT::v2i64: {
1628 uint64_t val = SplatBits;
1629 uint32_t upper = uint32_t(val >> 32);
1630 uint32_t lower = uint32_t(val);
1631
Scott Michele9b690b2008-03-06 04:02:54 +00001632 if (upper == lower) {
1633 // Magic constant that can be matched by IL, ILA, et. al.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001634 SDValue Val = DAG.getTargetConstant(val, MVT::i64);
Scott Michele9b690b2008-03-06 04:02:54 +00001635 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel42f56b42008-03-05 23:02:02 +00001636 } else {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001637 SDValue LO32;
1638 SDValue HI32;
1639 SmallVector<SDValue, 16> ShufBytes;
1640 SDValue Result;
Scott Michel6e22c652007-12-04 22:23:35 +00001641 bool upper_special, lower_special;
1642
1643 // NOTE: This code creates common-case shuffle masks that can be easily
1644 // detected as common expressions. It is not attempting to create highly
1645 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1646
1647 // Detect if the upper or lower half is a special shuffle mask pattern:
Scott Michelefc8c7a2008-11-24 17:11:17 +00001648 upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
1649 lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
Scott Michel6e22c652007-12-04 22:23:35 +00001650
1651 // Create lower vector if not a special pattern
1652 if (!lower_special) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001653 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Scott Michelbb713ae2008-01-30 02:55:46 +00001654 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1655 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1656 LO32C, LO32C, LO32C, LO32C));
Scott Michel6e22c652007-12-04 22:23:35 +00001657 }
1658
1659 // Create upper vector if not a special pattern
1660 if (!upper_special) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001661 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Scott Michelbb713ae2008-01-30 02:55:46 +00001662 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1663 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1664 HI32C, HI32C, HI32C, HI32C));
Scott Michel6e22c652007-12-04 22:23:35 +00001665 }
1666
1667 // If either upper or lower are special, then the two input operands are
1668 // the same (basically, one of them is a "don't care")
1669 if (lower_special)
Scott Michelbb713ae2008-01-30 02:55:46 +00001670 LO32 = HI32;
Scott Michel6e22c652007-12-04 22:23:35 +00001671 if (upper_special)
Scott Michelbb713ae2008-01-30 02:55:46 +00001672 HI32 = LO32;
Scott Michel6e22c652007-12-04 22:23:35 +00001673 if (lower_special && upper_special) {
Scott Michelbb713ae2008-01-30 02:55:46 +00001674 // Unhappy situation... both upper and lower are special, so punt with
1675 // a target constant:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001676 SDValue Zero = DAG.getConstant(0, MVT::i32);
Scott Michelbb713ae2008-01-30 02:55:46 +00001677 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel6e22c652007-12-04 22:23:35 +00001678 Zero, Zero);
1679 }
1680
1681 for (int i = 0; i < 4; ++i) {
Scott Micheld831cc42008-06-02 22:18:03 +00001682 uint64_t val = 0;
Scott Michelbb713ae2008-01-30 02:55:46 +00001683 for (int j = 0; j < 4; ++j) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001684 SDValue V;
Scott Michelbb713ae2008-01-30 02:55:46 +00001685 bool process_upper, process_lower;
Scott Micheld831cc42008-06-02 22:18:03 +00001686 val <<= 8;
Scott Michelbb713ae2008-01-30 02:55:46 +00001687 process_upper = (upper_special && (i & 1) == 0);
1688 process_lower = (lower_special && (i & 1) == 1);
Scott Michel6e22c652007-12-04 22:23:35 +00001689
Scott Michelbb713ae2008-01-30 02:55:46 +00001690 if (process_upper || process_lower) {
1691 if ((process_upper && upper == 0)
1692 || (process_lower && lower == 0))
Scott Micheld831cc42008-06-02 22:18:03 +00001693 val |= 0x80;
Scott Michelbb713ae2008-01-30 02:55:46 +00001694 else if ((process_upper && upper == 0xffffffff)
1695 || (process_lower && lower == 0xffffffff))
Scott Micheld831cc42008-06-02 22:18:03 +00001696 val |= 0xc0;
Scott Michelbb713ae2008-01-30 02:55:46 +00001697 else if ((process_upper && upper == 0x80000000)
1698 || (process_lower && lower == 0x80000000))
Scott Micheld831cc42008-06-02 22:18:03 +00001699 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michelbb713ae2008-01-30 02:55:46 +00001700 } else
Scott Micheld831cc42008-06-02 22:18:03 +00001701 val |= i * 4 + j + ((i & 1) * 16);
Scott Michelbb713ae2008-01-30 02:55:46 +00001702 }
Scott Micheld831cc42008-06-02 22:18:03 +00001703
1704 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel6e22c652007-12-04 22:23:35 +00001705 }
1706
1707 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Micheld831cc42008-06-02 22:18:03 +00001708 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00001709 &ShufBytes[0], ShufBytes.size()));
Scott Michel6e22c652007-12-04 22:23:35 +00001710 }
1711 }
1712 }
Scott Michelfe095082008-07-16 17:17:29 +00001713
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001714 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001715}
1716
1717/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1718/// which the Cell can operate. The code inspects V3 to ascertain whether the
1719/// permutation vector, V3, is monotonically increasing with one "exception"
1720/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel0be03392008-11-22 23:50:42 +00001721/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel6e22c652007-12-04 22:23:35 +00001722/// In either case, the net result is going to eventually invoke SHUFB to
1723/// permute/shuffle the bytes from V1 and V2.
1724/// \note
Scott Michel0be03392008-11-22 23:50:42 +00001725/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel6e22c652007-12-04 22:23:35 +00001726/// control word for byte/halfword/word insertion. This takes care of a single
1727/// element move from V2 into V1.
1728/// \note
1729/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001730static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
1731 SDValue V1 = Op.getOperand(0);
1732 SDValue V2 = Op.getOperand(1);
1733 SDValue PermMask = Op.getOperand(2);
Scott Michelfe095082008-07-16 17:17:29 +00001734
Scott Michel6e22c652007-12-04 22:23:35 +00001735 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michelfe095082008-07-16 17:17:29 +00001736
Scott Michel6e22c652007-12-04 22:23:35 +00001737 // If we have a single element being moved from V1 to V2, this can be handled
1738 // using the C*[DX] compute mask instructions, but the vector elements have
1739 // to be monotonically increasing with one exception element.
Scott Michelea3c49d2008-12-04 21:01:44 +00001740 MVT VecVT = V1.getValueType();
1741 MVT EltVT = VecVT.getVectorElementType();
Scott Michel6e22c652007-12-04 22:23:35 +00001742 unsigned EltsFromV2 = 0;
1743 unsigned V2Elt = 0;
1744 unsigned V2EltIdx0 = 0;
1745 unsigned CurrElt = 0;
Scott Michelea3c49d2008-12-04 21:01:44 +00001746 unsigned MaxElts = VecVT.getVectorNumElements();
1747 unsigned PrevElt = 0;
1748 unsigned V0Elt = 0;
Scott Michel6e22c652007-12-04 22:23:35 +00001749 bool monotonic = true;
Scott Michelea3c49d2008-12-04 21:01:44 +00001750 bool rotate = true;
1751
1752 if (EltVT == MVT::i8) {
Scott Michel6e22c652007-12-04 22:23:35 +00001753 V2EltIdx0 = 16;
Scott Michelea3c49d2008-12-04 21:01:44 +00001754 } else if (EltVT == MVT::i16) {
Scott Michel6e22c652007-12-04 22:23:35 +00001755 V2EltIdx0 = 8;
Scott Michelea3c49d2008-12-04 21:01:44 +00001756 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel6e22c652007-12-04 22:23:35 +00001757 V2EltIdx0 = 4;
Scott Michelea3c49d2008-12-04 21:01:44 +00001758 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1759 V2EltIdx0 = 2;
1760 } else
Scott Michel6e22c652007-12-04 22:23:35 +00001761 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1762
Scott Michelea3c49d2008-12-04 21:01:44 +00001763 for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) {
1764 if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) {
1765 unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001766
Scott Michelea3c49d2008-12-04 21:01:44 +00001767 if (monotonic) {
1768 if (SrcElt >= V2EltIdx0) {
1769 if (1 >= (++EltsFromV2)) {
1770 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1771 }
1772 } else if (CurrElt != SrcElt) {
1773 monotonic = false;
1774 }
1775
1776 ++CurrElt;
1777 }
1778
1779 if (rotate) {
1780 if (PrevElt > 0 && SrcElt < MaxElts) {
1781 if ((PrevElt == SrcElt - 1)
1782 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
1783 PrevElt = SrcElt;
1784 if (SrcElt == 0)
1785 V0Elt = i;
1786 } else {
1787 rotate = false;
1788 }
1789 } else if (PrevElt == 0) {
1790 // First time through, need to keep track of previous element
1791 PrevElt = SrcElt;
1792 } else {
1793 // This isn't a rotation, takes elements from vector 2
1794 rotate = false;
1795 }
1796 }
Scott Michel6e22c652007-12-04 22:23:35 +00001797 }
Scott Michel6e22c652007-12-04 22:23:35 +00001798 }
1799
1800 if (EltsFromV2 == 1 && monotonic) {
1801 // Compute mask and shuffle
1802 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00001803 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1804 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands13237ac2008-06-06 12:08:01 +00001805 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6e22c652007-12-04 22:23:35 +00001806 // Initialize temporary register to 0
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001807 SDValue InitTempReg =
Scott Michel6e22c652007-12-04 22:23:35 +00001808 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel0be03392008-11-22 23:50:42 +00001809 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001810 SDValue ShufMaskOp =
Scott Michel08a4e202008-12-01 17:56:02 +00001811 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00001812 DAG.getTargetConstant(V2Elt, MVT::i32),
1813 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel6e22c652007-12-04 22:23:35 +00001814 // Use shuffle mask in SHUFB synthetic instruction:
1815 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
Scott Michelea3c49d2008-12-04 21:01:44 +00001816 } else if (rotate) {
1817 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelb8ee30d2008-12-29 03:23:36 +00001818
Scott Michelea3c49d2008-12-04 21:01:44 +00001819 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1820 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel6e22c652007-12-04 22:23:35 +00001821 } else {
Gabor Greif81d6a382008-08-31 15:37:04 +00001822 // Convert the SHUFFLE_VECTOR mask's input element units to the
1823 // actual bytes.
Duncan Sands13237ac2008-06-06 12:08:01 +00001824 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michelfe095082008-07-16 17:17:29 +00001825
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001826 SmallVector<SDValue, 16> ResultMask;
Scott Michel6e22c652007-12-04 22:23:35 +00001827 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1828 unsigned SrcElt;
1829 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michelbb713ae2008-01-30 02:55:46 +00001830 SrcElt = 0;
Scott Michelfe095082008-07-16 17:17:29 +00001831 else
Dan Gohmaneffb8942008-09-12 16:56:44 +00001832 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michelfe095082008-07-16 17:17:29 +00001833
Scott Michel7d5eaec2008-02-23 18:41:37 +00001834 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michelbb713ae2008-01-30 02:55:46 +00001835 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1836 MVT::i8));
Scott Michel6e22c652007-12-04 22:23:35 +00001837 }
1838 }
Scott Michelfe095082008-07-16 17:17:29 +00001839
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001840 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel08a4e202008-12-01 17:56:02 +00001841 &ResultMask[0], ResultMask.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001842 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1843 }
1844}
1845
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001846static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1847 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel6e22c652007-12-04 22:23:35 +00001848
Gabor Greiff304a7a2008-08-28 21:40:38 +00001849 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel6e22c652007-12-04 22:23:35 +00001850 // For a constant, build the appropriate constant vector, which will
1851 // eventually simplify to a vector register load.
1852
Gabor Greiff304a7a2008-08-28 21:40:38 +00001853 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001854 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands13237ac2008-06-06 12:08:01 +00001855 MVT VT;
Scott Michel6e22c652007-12-04 22:23:35 +00001856 size_t n_copies;
1857
1858 // Create a constant vector:
Duncan Sands13237ac2008-06-06 12:08:01 +00001859 switch (Op.getValueType().getSimpleVT()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001860 default: assert(0 && "Unexpected constant value type in "
Scott Michelbb713ae2008-01-30 02:55:46 +00001861 "LowerSCALAR_TO_VECTOR");
Scott Michel6e22c652007-12-04 22:23:35 +00001862 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1863 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1864 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1865 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1866 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1867 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1868 }
1869
Dan Gohmaneffb8942008-09-12 16:56:44 +00001870 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel6e22c652007-12-04 22:23:35 +00001871 for (size_t j = 0; j < n_copies; ++j)
1872 ConstVecValues.push_back(CValue);
1873
1874 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michelbb713ae2008-01-30 02:55:46 +00001875 &ConstVecValues[0], ConstVecValues.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001876 } else {
1877 // Otherwise, copy the value from one register to another:
Duncan Sands13237ac2008-06-06 12:08:01 +00001878 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001879 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1880 case MVT::i8:
1881 case MVT::i16:
1882 case MVT::i32:
1883 case MVT::i64:
1884 case MVT::f32:
1885 case MVT::f64:
Scott Michel82335272008-12-27 04:51:36 +00001886 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel6e22c652007-12-04 22:23:35 +00001887 }
1888 }
1889
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001890 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001891}
1892
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001893static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00001894 MVT VT = Op.getValueType();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001895 SDValue N = Op.getOperand(0);
1896 SDValue Elt = Op.getOperand(1);
Scott Michel0be03392008-11-22 23:50:42 +00001897 SDValue retval;
Scott Michel6e22c652007-12-04 22:23:35 +00001898
Scott Michel0be03392008-11-22 23:50:42 +00001899 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1900 // Constant argument:
1901 int EltNo = (int) C->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001902
Scott Michel0be03392008-11-22 23:50:42 +00001903 // sanity checks:
1904 if (VT == MVT::i8 && EltNo >= 16)
1905 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1906 else if (VT == MVT::i16 && EltNo >= 8)
1907 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1908 else if (VT == MVT::i32 && EltNo >= 4)
1909 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1910 else if (VT == MVT::i64 && EltNo >= 2)
1911 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel6e22c652007-12-04 22:23:35 +00001912
Scott Michel0be03392008-11-22 23:50:42 +00001913 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1914 // i32 and i64: Element 0 is the preferred slot
Scott Michelefc8c7a2008-11-24 17:11:17 +00001915 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel0be03392008-11-22 23:50:42 +00001916 }
Scott Michel6e22c652007-12-04 22:23:35 +00001917
Scott Michel0be03392008-11-22 23:50:42 +00001918 // Need to generate shuffle mask and extract:
1919 int prefslot_begin = -1, prefslot_end = -1;
1920 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1921
1922 switch (VT.getSimpleVT()) {
1923 default:
1924 assert(false && "Invalid value type!");
1925 case MVT::i8: {
1926 prefslot_begin = prefslot_end = 3;
1927 break;
1928 }
1929 case MVT::i16: {
1930 prefslot_begin = 2; prefslot_end = 3;
1931 break;
1932 }
1933 case MVT::i32:
1934 case MVT::f32: {
1935 prefslot_begin = 0; prefslot_end = 3;
1936 break;
1937 }
1938 case MVT::i64:
1939 case MVT::f64: {
1940 prefslot_begin = 0; prefslot_end = 7;
1941 break;
1942 }
1943 }
1944
1945 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1946 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1947
1948 unsigned int ShufBytes[16];
1949 for (int i = 0; i < 16; ++i) {
1950 // zero fill uppper part of preferred slot, don't care about the
1951 // other slots:
1952 unsigned int mask_val;
1953 if (i <= prefslot_end) {
1954 mask_val =
1955 ((i < prefslot_begin)
1956 ? 0x80
1957 : elt_byte + (i - prefslot_begin));
1958
1959 ShufBytes[i] = mask_val;
1960 } else
1961 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1962 }
1963
1964 SDValue ShufMask[4];
1965 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michelea3c49d2008-12-04 21:01:44 +00001966 unsigned bidx = i * 4;
Scott Michel0be03392008-11-22 23:50:42 +00001967 unsigned int bits = ((ShufBytes[bidx] << 24) |
1968 (ShufBytes[bidx+1] << 16) |
1969 (ShufBytes[bidx+2] << 8) |
1970 ShufBytes[bidx+3]);
1971 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1972 }
1973
1974 SDValue ShufMaskVec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1975 &ShufMask[0],
1976 sizeof(ShufMask) / sizeof(ShufMask[0]));
1977
Scott Michelefc8c7a2008-11-24 17:11:17 +00001978 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel0be03392008-11-22 23:50:42 +00001979 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
1980 N, N, ShufMaskVec));
1981 } else {
1982 // Variable index: Rotate the requested element into slot 0, then replicate
1983 // slot 0 across the vector
1984 MVT VecVT = N.getValueType();
1985 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
1986 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
1987 abort();
1988 }
1989
1990 // Make life easier by making sure the index is zero-extended to i32
1991 if (Elt.getValueType() != MVT::i32)
1992 Elt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Elt);
1993
1994 // Scale the index to a bit/byte shift quantity
1995 APInt scaleFactor =
Scott Michelefc8c7a2008-11-24 17:11:17 +00001996 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1997 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel0be03392008-11-22 23:50:42 +00001998 SDValue vecShift;
Scott Michel0be03392008-11-22 23:50:42 +00001999
Scott Michelefc8c7a2008-11-24 17:11:17 +00002000 if (scaleShift > 0) {
2001 // Scale the shift factor:
Scott Michel0be03392008-11-22 23:50:42 +00002002 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel08a4e202008-12-01 17:56:02 +00002003 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel0be03392008-11-22 23:50:42 +00002004 }
2005
Scott Michelefc8c7a2008-11-24 17:11:17 +00002006 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt);
2007
2008 // Replicate the bytes starting at byte 0 across the entire vector (for
2009 // consistency with the notion of a unified register set)
Scott Michel0be03392008-11-22 23:50:42 +00002010 SDValue replicate;
2011
2012 switch (VT.getSimpleVT()) {
2013 default:
2014 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
2015 abort();
2016 /*NOTREACHED*/
2017 case MVT::i8: {
Scott Michelefc8c7a2008-11-24 17:11:17 +00002018 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel0be03392008-11-22 23:50:42 +00002019 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2020 factor, factor);
2021 break;
2022 }
2023 case MVT::i16: {
Scott Michelefc8c7a2008-11-24 17:11:17 +00002024 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel0be03392008-11-22 23:50:42 +00002025 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2026 factor, factor);
2027 break;
2028 }
2029 case MVT::i32:
2030 case MVT::f32: {
2031 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
2032 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2033 factor, factor);
2034 break;
2035 }
2036 case MVT::i64:
2037 case MVT::f64: {
2038 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2039 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
2040 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, loFactor, hiFactor,
2041 loFactor, hiFactor);
2042 break;
2043 }
2044 }
2045
Scott Michelefc8c7a2008-11-24 17:11:17 +00002046 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel08a4e202008-12-01 17:56:02 +00002047 DAG.getNode(SPUISD::SHUFB, VecVT,
2048 vecShift, vecShift, replicate));
Scott Michel6e22c652007-12-04 22:23:35 +00002049 }
2050
Scott Michel0be03392008-11-22 23:50:42 +00002051 return retval;
Scott Michel6e22c652007-12-04 22:23:35 +00002052}
2053
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002054static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2055 SDValue VecOp = Op.getOperand(0);
2056 SDValue ValOp = Op.getOperand(1);
2057 SDValue IdxOp = Op.getOperand(2);
Duncan Sands13237ac2008-06-06 12:08:01 +00002058 MVT VT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +00002059
2060 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2061 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2062
Duncan Sands13237ac2008-06-06 12:08:01 +00002063 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel08a4e202008-12-01 17:56:02 +00002064 // Use $sp ($1) because it's always 16-byte aligned and it's available:
2065 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
2066 DAG.getRegister(SPU::R1, PtrVT),
2067 DAG.getConstant(CN->getSExtValue(), PtrVT));
2068 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer);
Scott Michel6e22c652007-12-04 22:23:35 +00002069
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002070 SDValue result =
Scott Michel6e22c652007-12-04 22:23:35 +00002071 DAG.getNode(SPUISD::SHUFB, VT,
2072 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michelb8ee30d2008-12-29 03:23:36 +00002073 VecOp,
Scott Michel08a4e202008-12-01 17:56:02 +00002074 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel6e22c652007-12-04 22:23:35 +00002075
2076 return result;
2077}
2078
Scott Michel82335272008-12-27 04:51:36 +00002079static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2080 const TargetLowering &TLI)
Scott Michel7d5eaec2008-02-23 18:41:37 +00002081{
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002082 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michel82335272008-12-27 04:51:36 +00002083 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel6e22c652007-12-04 22:23:35 +00002084
2085 assert(Op.getValueType() == MVT::i8);
2086 switch (Opc) {
2087 default:
2088 assert(0 && "Unhandled i8 math operator");
2089 /*NOTREACHED*/
2090 break;
Scott Michel41236c02008-12-30 23:28:25 +00002091 case ISD::ADD: {
2092 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2093 // the result:
2094 SDValue N1 = Op.getOperand(1);
2095 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2096 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
2097 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2098 DAG.getNode(Opc, MVT::i16, N0, N1));
2099
2100 }
2101
Scott Michel6e22c652007-12-04 22:23:35 +00002102 case ISD::SUB: {
2103 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2104 // the result:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002105 SDValue N1 = Op.getOperand(1);
Scott Michel41236c02008-12-30 23:28:25 +00002106 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2107 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
Scott Michelfe095082008-07-16 17:17:29 +00002108 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel6e22c652007-12-04 22:23:35 +00002109 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michelfe095082008-07-16 17:17:29 +00002110 }
Scott Michel6e22c652007-12-04 22:23:35 +00002111 case ISD::ROTR:
2112 case ISD::ROTL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002113 SDValue N1 = Op.getOperand(1);
Scott Michel6e22c652007-12-04 22:23:35 +00002114 unsigned N1Opc;
2115 N0 = (N0.getOpcode() != ISD::Constant
2116 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmaneffb8942008-09-12 16:56:44 +00002117 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2118 MVT::i16));
Scott Michel82335272008-12-27 04:51:36 +00002119 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif81d6a382008-08-31 15:37:04 +00002120 ? ISD::ZERO_EXTEND
2121 : ISD::TRUNCATE;
Scott Michel6e22c652007-12-04 22:23:35 +00002122 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel82335272008-12-27 04:51:36 +00002123 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmaneffb8942008-09-12 16:56:44 +00002124 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel82335272008-12-27 04:51:36 +00002125 TLI.getShiftAmountTy()));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002126 SDValue ExpandArg =
Scott Michel6e22c652007-12-04 22:23:35 +00002127 DAG.getNode(ISD::OR, MVT::i16, N0,
2128 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sands0852f482008-10-30 19:24:28 +00002129 N0, DAG.getConstant(8, MVT::i32)));
Scott Michelfe095082008-07-16 17:17:29 +00002130 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel6e22c652007-12-04 22:23:35 +00002131 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2132 }
2133 case ISD::SRL:
2134 case ISD::SHL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002135 SDValue N1 = Op.getOperand(1);
Scott Michel6e22c652007-12-04 22:23:35 +00002136 unsigned N1Opc;
2137 N0 = (N0.getOpcode() != ISD::Constant
2138 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmaneffb8942008-09-12 16:56:44 +00002139 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michel82335272008-12-27 04:51:36 +00002140 MVT::i32));
2141 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif81d6a382008-08-31 15:37:04 +00002142 ? ISD::ZERO_EXTEND
2143 : ISD::TRUNCATE;
Scott Michel6e22c652007-12-04 22:23:35 +00002144 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel82335272008-12-27 04:51:36 +00002145 ? DAG.getNode(N1Opc, ShiftVT, N1)
2146 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michelfe095082008-07-16 17:17:29 +00002147 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel6e22c652007-12-04 22:23:35 +00002148 DAG.getNode(Opc, MVT::i16, N0, N1));
2149 }
2150 case ISD::SRA: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002151 SDValue N1 = Op.getOperand(1);
Scott Michel6e22c652007-12-04 22:23:35 +00002152 unsigned N1Opc;
2153 N0 = (N0.getOpcode() != ISD::Constant
2154 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michel82335272008-12-27 04:51:36 +00002155 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmaneffb8942008-09-12 16:56:44 +00002156 MVT::i16));
Scott Michel82335272008-12-27 04:51:36 +00002157 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif81d6a382008-08-31 15:37:04 +00002158 ? ISD::SIGN_EXTEND
2159 : ISD::TRUNCATE;
Scott Michel6e22c652007-12-04 22:23:35 +00002160 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel82335272008-12-27 04:51:36 +00002161 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmaneffb8942008-09-12 16:56:44 +00002162 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel82335272008-12-27 04:51:36 +00002163 ShiftVT));
Scott Michelfe095082008-07-16 17:17:29 +00002164 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel6e22c652007-12-04 22:23:35 +00002165 DAG.getNode(Opc, MVT::i16, N0, N1));
2166 }
2167 case ISD::MUL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002168 SDValue N1 = Op.getOperand(1);
Scott Michel6e22c652007-12-04 22:23:35 +00002169 unsigned N1Opc;
2170 N0 = (N0.getOpcode() != ISD::Constant
2171 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmaneffb8942008-09-12 16:56:44 +00002172 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2173 MVT::i16));
Duncan Sands11dd4242008-06-08 20:54:56 +00002174 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel6e22c652007-12-04 22:23:35 +00002175 N1 = (N1.getOpcode() != ISD::Constant
2176 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michel82335272008-12-27 04:51:36 +00002177 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmaneffb8942008-09-12 16:56:44 +00002178 MVT::i16));
Scott Michelfe095082008-07-16 17:17:29 +00002179 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel6e22c652007-12-04 22:23:35 +00002180 DAG.getNode(Opc, MVT::i16, N0, N1));
2181 break;
2182 }
2183 }
2184
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002185 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002186}
2187
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002188static SDValue LowerI64Math(SDValue Op, SelectionDAG &DAG, unsigned Opc)
Scott Michel7d5eaec2008-02-23 18:41:37 +00002189{
Duncan Sands13237ac2008-06-06 12:08:01 +00002190 MVT VT = Op.getValueType();
2191 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002192
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002193 SDValue Op0 = Op.getOperand(0);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002194
2195 switch (Opc) {
2196 case ISD::ZERO_EXTEND:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002197 case ISD::ANY_EXTEND: {
Duncan Sands13237ac2008-06-06 12:08:01 +00002198 MVT Op0VT = Op0.getValueType();
2199 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002200
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002201 SDValue PromoteScalar =
Scott Michel82335272008-12-27 04:51:36 +00002202 DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002203
Scott Michel41236c02008-12-30 23:28:25 +00002204 // Use a shuffle to zero extend the i32 to i64 directly:
Scott Michel6887caf2009-01-06 03:36:14 +00002205 SDValue shufMask;
Scott Michel2e5df902008-11-24 18:20:46 +00002206
Scott Michel6887caf2009-01-06 03:36:14 +00002207 switch (Op0VT.getSimpleVT()) {
2208 default:
2209 cerr << "CellSPU LowerI64Math: Unhandled zero/any extend MVT\n";
2210 abort();
2211 /*NOTREACHED*/
2212 break;
2213 case MVT::i32:
2214 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2215 DAG.getConstant(0x80808080, MVT::i32),
2216 DAG.getConstant(0x00010203, MVT::i32),
2217 DAG.getConstant(0x80808080, MVT::i32),
2218 DAG.getConstant(0x08090a0b, MVT::i32));
2219 break;
2220
2221 case MVT::i16:
2222 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2223 DAG.getConstant(0x80808080, MVT::i32),
2224 DAG.getConstant(0x80800203, MVT::i32),
2225 DAG.getConstant(0x80808080, MVT::i32),
2226 DAG.getConstant(0x80800a0b, MVT::i32));
2227 break;
2228
2229 case MVT::i8:
2230 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2231 DAG.getConstant(0x80808080, MVT::i32),
2232 DAG.getConstant(0x80808003, MVT::i32),
2233 DAG.getConstant(0x80808080, MVT::i32),
2234 DAG.getConstant(0x8080800b, MVT::i32));
2235 break;
2236 }
2237
2238 SDValue zextShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2239 PromoteScalar, PromoteScalar, shufMask);
2240
2241 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2242 DAG.getNode(ISD::BIT_CONVERT, VecVT, zextShuffle));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002243 }
2244
Scott Micheld831cc42008-06-02 22:18:03 +00002245 case ISD::ADD: {
2246 // Turn operands into vectors to satisfy type checking (shufb works on
2247 // vectors)
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002248 SDValue Op0 =
Scott Michel82335272008-12-27 04:51:36 +00002249 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002250 SDValue Op1 =
Scott Michel82335272008-12-27 04:51:36 +00002251 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002252 SmallVector<SDValue, 16> ShufBytes;
Scott Micheld831cc42008-06-02 22:18:03 +00002253
2254 // Create the shuffle mask for "rotating" the borrow up one register slot
2255 // once the borrow is generated.
2256 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2257 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2258 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2259 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2260
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002261 SDValue CarryGen =
Scott Micheld831cc42008-06-02 22:18:03 +00002262 DAG.getNode(SPUISD::CARRY_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002263 SDValue ShiftedCarry =
Scott Micheld831cc42008-06-02 22:18:03 +00002264 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2265 CarryGen, CarryGen,
2266 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2267 &ShufBytes[0], ShufBytes.size()));
2268
Scott Michelefc8c7a2008-11-24 17:11:17 +00002269 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Micheld831cc42008-06-02 22:18:03 +00002270 DAG.getNode(SPUISD::ADD_EXTENDED, MVT::v2i64,
2271 Op0, Op1, ShiftedCarry));
2272 }
2273
2274 case ISD::SUB: {
2275 // Turn operands into vectors to satisfy type checking (shufb works on
2276 // vectors)
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002277 SDValue Op0 =
Scott Michel82335272008-12-27 04:51:36 +00002278 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002279 SDValue Op1 =
Scott Michel82335272008-12-27 04:51:36 +00002280 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002281 SmallVector<SDValue, 16> ShufBytes;
Scott Micheld831cc42008-06-02 22:18:03 +00002282
2283 // Create the shuffle mask for "rotating" the borrow up one register slot
2284 // once the borrow is generated.
2285 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2286 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2287 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2288 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2289
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002290 SDValue BorrowGen =
Scott Micheld831cc42008-06-02 22:18:03 +00002291 DAG.getNode(SPUISD::BORROW_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002292 SDValue ShiftedBorrow =
Scott Micheld831cc42008-06-02 22:18:03 +00002293 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2294 BorrowGen, BorrowGen,
2295 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2296 &ShufBytes[0], ShufBytes.size()));
2297
Scott Michelefc8c7a2008-11-24 17:11:17 +00002298 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Micheld831cc42008-06-02 22:18:03 +00002299 DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64,
2300 Op0, Op1, ShiftedBorrow));
2301 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002302 }
2303
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002304 return SDValue();
Scott Michel7d5eaec2008-02-23 18:41:37 +00002305}
2306
Scott Michel6e22c652007-12-04 22:23:35 +00002307//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002308static SDValue
2309LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2310 SDValue ConstVec;
2311 SDValue Arg;
Duncan Sands13237ac2008-06-06 12:08:01 +00002312 MVT VT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +00002313
2314 ConstVec = Op.getOperand(0);
2315 Arg = Op.getOperand(1);
Gabor Greiff304a7a2008-08-28 21:40:38 +00002316 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2317 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel6e22c652007-12-04 22:23:35 +00002318 ConstVec = ConstVec.getOperand(0);
2319 } else {
2320 ConstVec = Op.getOperand(1);
2321 Arg = Op.getOperand(0);
Gabor Greiff304a7a2008-08-28 21:40:38 +00002322 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michelbb713ae2008-01-30 02:55:46 +00002323 ConstVec = ConstVec.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +00002324 }
2325 }
2326 }
2327
Gabor Greiff304a7a2008-08-28 21:40:38 +00002328 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel6e22c652007-12-04 22:23:35 +00002329 uint64_t VectorBits[2];
2330 uint64_t UndefBits[2];
2331 uint64_t SplatBits, SplatUndef;
2332 int SplatSize;
2333
Gabor Greiff304a7a2008-08-28 21:40:38 +00002334 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michelbb713ae2008-01-30 02:55:46 +00002335 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands13237ac2008-06-06 12:08:01 +00002336 VT.getVectorElementType().getSizeInBits(),
Scott Michelbb713ae2008-01-30 02:55:46 +00002337 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002338 SDValue tcVec[16];
2339 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel6e22c652007-12-04 22:23:35 +00002340 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2341
2342 // Turn the BUILD_VECTOR into a set of target constants:
2343 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michelbb713ae2008-01-30 02:55:46 +00002344 tcVec[i] = tc;
Scott Michel6e22c652007-12-04 22:23:35 +00002345
Gabor Greiff304a7a2008-08-28 21:40:38 +00002346 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michelbb713ae2008-01-30 02:55:46 +00002347 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel6e22c652007-12-04 22:23:35 +00002348 }
2349 }
Nate Begeman82f19252008-07-29 19:07:27 +00002350 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2351 // lowered. Return the operation, rather than a null SDValue.
2352 return Op;
Scott Michel6e22c652007-12-04 22:23:35 +00002353}
2354
Scott Michel6e22c652007-12-04 22:23:35 +00002355//! Custom lowering for CTPOP (count population)
2356/*!
2357 Custom lowering code that counts the number ones in the input
2358 operand. SPU has such an instruction, but it counts the number of
2359 ones per byte, which then have to be accumulated.
2360*/
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002361static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00002362 MVT VT = Op.getValueType();
2363 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel6e22c652007-12-04 22:23:35 +00002364
Duncan Sands13237ac2008-06-06 12:08:01 +00002365 switch (VT.getSimpleVT()) {
2366 default:
2367 assert(false && "Invalid value type!");
Scott Michel6e22c652007-12-04 22:23:35 +00002368 case MVT::i8: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002369 SDValue N = Op.getOperand(0);
2370 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00002371
Scott Michel82335272008-12-27 04:51:36 +00002372 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002373 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +00002374
2375 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2376 }
2377
2378 case MVT::i16: {
2379 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00002380 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel6e22c652007-12-04 22:23:35 +00002381
Chris Lattnera10fff52007-12-31 04:13:23 +00002382 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel6e22c652007-12-04 22:23:35 +00002383
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002384 SDValue N = Op.getOperand(0);
2385 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2386 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sands0852f482008-10-30 19:24:28 +00002387 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00002388
Scott Michel82335272008-12-27 04:51:36 +00002389 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002390 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +00002391
2392 // CNTB_result becomes the chain to which all of the virtual registers
2393 // CNTB_reg, SUM1_reg become associated:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002394 SDValue CNTB_result =
Scott Michel6e22c652007-12-04 22:23:35 +00002395 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michelfe095082008-07-16 17:17:29 +00002396
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002397 SDValue CNTB_rescopy =
Scott Michel6e22c652007-12-04 22:23:35 +00002398 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2399
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002400 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel6e22c652007-12-04 22:23:35 +00002401
2402 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michelbb713ae2008-01-30 02:55:46 +00002403 DAG.getNode(ISD::ADD, MVT::i16,
2404 DAG.getNode(ISD::SRL, MVT::i16,
2405 Tmp1, Shift1),
2406 Tmp1),
2407 Mask0);
Scott Michel6e22c652007-12-04 22:23:35 +00002408 }
2409
2410 case MVT::i32: {
2411 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00002412 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel6e22c652007-12-04 22:23:35 +00002413
Chris Lattnera10fff52007-12-31 04:13:23 +00002414 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2415 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel6e22c652007-12-04 22:23:35 +00002416
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002417 SDValue N = Op.getOperand(0);
2418 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2419 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2420 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2421 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00002422
Scott Michel82335272008-12-27 04:51:36 +00002423 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002424 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +00002425
2426 // CNTB_result becomes the chain to which all of the virtual registers
2427 // CNTB_reg, SUM1_reg become associated:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002428 SDValue CNTB_result =
Scott Michel6e22c652007-12-04 22:23:35 +00002429 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michelfe095082008-07-16 17:17:29 +00002430
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002431 SDValue CNTB_rescopy =
Scott Michel6e22c652007-12-04 22:23:35 +00002432 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2433
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002434 SDValue Comp1 =
Scott Michel6e22c652007-12-04 22:23:35 +00002435 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00002436 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel6e22c652007-12-04 22:23:35 +00002437
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002438 SDValue Sum1 =
Scott Michel6e22c652007-12-04 22:23:35 +00002439 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00002440 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel6e22c652007-12-04 22:23:35 +00002441
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002442 SDValue Sum1_rescopy =
Scott Michel6e22c652007-12-04 22:23:35 +00002443 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2444
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002445 SDValue Comp2 =
Scott Michel6e22c652007-12-04 22:23:35 +00002446 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00002447 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2448 Shift2);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002449 SDValue Sum2 =
Scott Michel6e22c652007-12-04 22:23:35 +00002450 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michelbb713ae2008-01-30 02:55:46 +00002451 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel6e22c652007-12-04 22:23:35 +00002452
2453 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2454 }
2455
2456 case MVT::i64:
2457 break;
2458 }
2459
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002460 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002461}
2462
Scott Michel0be03392008-11-22 23:50:42 +00002463//! Lower ISD::SELECT_CC
2464/*!
2465 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2466 SELB instruction.
2467
2468 \note Need to revisit this in the future: if the code path through the true
2469 and false value computations is longer than the latency of a branch (6
2470 cycles), then it would be more advantageous to branch and insert a new basic
2471 block and branch on the condition. However, this code does not make that
2472 assumption, given the simplisitc uses so far.
2473 */
2474
Scott Michel82335272008-12-27 04:51:36 +00002475static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2476 const TargetLowering &TLI) {
Scott Michel0be03392008-11-22 23:50:42 +00002477 MVT VT = Op.getValueType();
2478 SDValue lhs = Op.getOperand(0);
2479 SDValue rhs = Op.getOperand(1);
2480 SDValue trueval = Op.getOperand(2);
2481 SDValue falseval = Op.getOperand(3);
2482 SDValue condition = Op.getOperand(4);
2483
Scott Michel82335272008-12-27 04:51:36 +00002484 // NOTE: SELB's arguments: $rA, $rB, $mask
2485 //
2486 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2487 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2488 // condition was true and 0s where the condition was false. Hence, the
2489 // arguments to SELB get reversed.
2490
Scott Michel0be03392008-11-22 23:50:42 +00002491 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2492 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2493 // with another "cannot select select_cc" assert:
2494
Duncan Sands8feb6942009-01-01 15:52:00 +00002495 SDValue compare = DAG.getNode(ISD::SETCC,
2496 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel82335272008-12-27 04:51:36 +00002497 lhs, rhs, condition);
2498 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel0be03392008-11-22 23:50:42 +00002499}
2500
Scott Michel73640252008-12-02 19:53:53 +00002501//! Custom lower ISD::TRUNCATE
2502static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2503{
2504 MVT VT = Op.getValueType();
2505 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2506 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
2507
2508 SDValue Op0 = Op.getOperand(0);
2509 MVT Op0VT = Op0.getValueType();
2510 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
2511
Scott Michel82335272008-12-27 04:51:36 +00002512 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel6a1f6272009-01-03 00:27:53 +00002513 // Create shuffle mask, least significant doubleword of quadword
Scott Michel82335272008-12-27 04:51:36 +00002514 unsigned maskHigh = 0x08090a0b;
2515 unsigned maskLow = 0x0c0d0e0f;
2516 // Use a shuffle to perform the truncation
2517 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2518 DAG.getConstant(maskHigh, MVT::i32),
2519 DAG.getConstant(maskLow, MVT::i32),
2520 DAG.getConstant(maskHigh, MVT::i32),
2521 DAG.getConstant(maskLow, MVT::i32));
2522
2523
2524 SDValue PromoteScalar = DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
2525
2526 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2527 PromoteScalar, PromoteScalar, shufMask);
2528
2529 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2530 DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle));
Scott Michel73640252008-12-02 19:53:53 +00002531 }
2532
Scott Michel82335272008-12-27 04:51:36 +00002533 return SDValue(); // Leave the truncate unmolested
Scott Michel73640252008-12-02 19:53:53 +00002534}
2535
Scott Michel0be03392008-11-22 23:50:42 +00002536//! Custom (target-specific) lowering entry point
2537/*!
2538 This is where LLVM's DAG selection process calls to do target-specific
2539 lowering of nodes.
2540 */
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002541SDValue
2542SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel6e22c652007-12-04 22:23:35 +00002543{
Scott Michel7d5eaec2008-02-23 18:41:37 +00002544 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands13237ac2008-06-06 12:08:01 +00002545 MVT VT = Op.getValueType();
Scott Michel7d5eaec2008-02-23 18:41:37 +00002546
2547 switch (Opc) {
Scott Michel6e22c652007-12-04 22:23:35 +00002548 default: {
2549 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel7d5eaec2008-02-23 18:41:37 +00002550 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greiff304a7a2008-08-28 21:40:38 +00002551 cerr << "*Op.getNode():\n";
2552 Op.getNode()->dump();
Scott Michel6e22c652007-12-04 22:23:35 +00002553 abort();
2554 }
2555 case ISD::LOAD:
Scott Michel73640252008-12-02 19:53:53 +00002556 case ISD::EXTLOAD:
Scott Michel6e22c652007-12-04 22:23:35 +00002557 case ISD::SEXTLOAD:
2558 case ISD::ZEXTLOAD:
2559 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2560 case ISD::STORE:
2561 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2562 case ISD::ConstantPool:
2563 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2564 case ISD::GlobalAddress:
2565 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2566 case ISD::JumpTable:
2567 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2568 case ISD::Constant:
2569 return LowerConstant(Op, DAG);
2570 case ISD::ConstantFP:
2571 return LowerConstantFP(Op, DAG);
2572 case ISD::FORMAL_ARGUMENTS:
Scott Michele4d3e3c2008-01-17 20:38:41 +00002573 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel6e22c652007-12-04 22:23:35 +00002574 case ISD::CALL:
Scott Michel8d5841a2008-01-11 02:53:15 +00002575 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel6e22c652007-12-04 22:23:35 +00002576 case ISD::RET:
2577 return LowerRET(Op, DAG, getTargetMachine());
2578
Scott Michel7d5eaec2008-02-23 18:41:37 +00002579
Scott Michel7d5eaec2008-02-23 18:41:37 +00002580 case ISD::ZERO_EXTEND:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002581 case ISD::ANY_EXTEND:
Scott Michel41236c02008-12-30 23:28:25 +00002582 return LowerI64Math(Op, DAG, Opc);
2583
2584 // i8, i64 math ops:
Scott Micheld831cc42008-06-02 22:18:03 +00002585 case ISD::ADD:
Scott Michel6e22c652007-12-04 22:23:35 +00002586 case ISD::SUB:
2587 case ISD::ROTR:
2588 case ISD::ROTL:
2589 case ISD::SRL:
2590 case ISD::SHL:
Scott Micheld831cc42008-06-02 22:18:03 +00002591 case ISD::SRA: {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002592 if (VT == MVT::i8)
Scott Michel82335272008-12-27 04:51:36 +00002593 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002594 else if (VT == MVT::i64)
2595 return LowerI64Math(Op, DAG, Opc);
2596 break;
Scott Micheld831cc42008-06-02 22:18:03 +00002597 }
Scott Michel6e22c652007-12-04 22:23:35 +00002598
2599 // Vector-related lowering.
2600 case ISD::BUILD_VECTOR:
2601 return LowerBUILD_VECTOR(Op, DAG);
2602 case ISD::SCALAR_TO_VECTOR:
2603 return LowerSCALAR_TO_VECTOR(Op, DAG);
2604 case ISD::VECTOR_SHUFFLE:
2605 return LowerVECTOR_SHUFFLE(Op, DAG);
2606 case ISD::EXTRACT_VECTOR_ELT:
2607 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2608 case ISD::INSERT_VECTOR_ELT:
2609 return LowerINSERT_VECTOR_ELT(Op, DAG);
2610
2611 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2612 case ISD::AND:
2613 case ISD::OR:
2614 case ISD::XOR:
2615 return LowerByteImmed(Op, DAG);
2616
2617 // Vector and i8 multiply:
2618 case ISD::MUL:
Scott Michel41236c02008-12-30 23:28:25 +00002619 if (VT == MVT::i8)
Scott Michel82335272008-12-27 04:51:36 +00002620 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel6e22c652007-12-04 22:23:35 +00002621
Scott Michel6e22c652007-12-04 22:23:35 +00002622 case ISD::CTPOP:
2623 return LowerCTPOP(Op, DAG);
Scott Michel0be03392008-11-22 23:50:42 +00002624
2625 case ISD::SELECT_CC:
Scott Michel82335272008-12-27 04:51:36 +00002626 return LowerSELECT_CC(Op, DAG, *this);
Scott Michel73640252008-12-02 19:53:53 +00002627
2628 case ISD::TRUNCATE:
2629 return LowerTRUNCATE(Op, DAG);
Scott Michel6e22c652007-12-04 22:23:35 +00002630 }
2631
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002632 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002633}
2634
Duncan Sands6ed40142008-12-01 11:39:25 +00002635void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2636 SmallVectorImpl<SDValue>&Results,
2637 SelectionDAG &DAG)
Scott Michelabad22c2008-11-10 23:43:06 +00002638{
2639#if 0
2640 unsigned Opc = (unsigned) N->getOpcode();
2641 MVT OpVT = N->getValueType(0);
2642
2643 switch (Opc) {
2644 default: {
2645 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2646 cerr << "Op.getOpcode() = " << Opc << "\n";
2647 cerr << "*Op.getNode():\n";
2648 N->dump();
2649 abort();
2650 /*NOTREACHED*/
2651 }
2652 }
2653#endif
2654
2655 /* Otherwise, return unchanged */
Scott Michelabad22c2008-11-10 23:43:06 +00002656}
2657
Scott Michel6e22c652007-12-04 22:23:35 +00002658//===----------------------------------------------------------------------===//
Scott Michel6e22c652007-12-04 22:23:35 +00002659// Target Optimization Hooks
2660//===----------------------------------------------------------------------===//
2661
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002662SDValue
Scott Michel6e22c652007-12-04 22:23:35 +00002663SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2664{
2665#if 0
2666 TargetMachine &TM = getTargetMachine();
Scott Michelceae3bb2008-01-29 02:16:57 +00002667#endif
2668 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel6e22c652007-12-04 22:23:35 +00002669 SelectionDAG &DAG = DCI.DAG;
Scott Michel08a4e202008-12-01 17:56:02 +00002670 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2671 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michel82335272008-12-27 04:51:36 +00002672 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel08a4e202008-12-01 17:56:02 +00002673 SDValue Result; // Initially, empty result
Scott Michel6e22c652007-12-04 22:23:35 +00002674
2675 switch (N->getOpcode()) {
2676 default: break;
Scott Michelceae3bb2008-01-29 02:16:57 +00002677 case ISD::ADD: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002678 SDValue Op1 = N->getOperand(1);
Scott Michelceae3bb2008-01-29 02:16:57 +00002679
Scott Michel82335272008-12-27 04:51:36 +00002680 if (Op0.getOpcode() == SPUISD::IndirectAddr
2681 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2682 // Normalize the operands to reduce repeated code
2683 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michelb8ee30d2008-12-29 03:23:36 +00002684
Scott Michel82335272008-12-27 04:51:36 +00002685 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2686 IndirectArg = Op1;
2687 AddArg = Op0;
2688 }
2689
2690 if (isa<ConstantSDNode>(AddArg)) {
2691 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2692 SDValue IndOp1 = IndirectArg.getOperand(1);
2693
2694 if (CN0->isNullValue()) {
2695 // (add (SPUindirect <arg>, <arg>), 0) ->
2696 // (SPUindirect <arg>, <arg>)
Scott Michelceae3bb2008-01-29 02:16:57 +00002697
Scott Michel187250b2008-12-04 17:16:59 +00002698#if !defined(NDEBUG)
Scott Michel82335272008-12-27 04:51:36 +00002699 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel40f54d22008-12-04 03:02:42 +00002700 cerr << "\n"
Scott Michel82335272008-12-27 04:51:36 +00002701 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2702 << "With: (SPUindirect <arg>, <arg>)\n";
2703 }
Scott Michel40f54d22008-12-04 03:02:42 +00002704#endif
2705
Scott Michel82335272008-12-27 04:51:36 +00002706 return IndirectArg;
2707 } else if (isa<ConstantSDNode>(IndOp1)) {
2708 // (add (SPUindirect <arg>, <const>), <const>) ->
2709 // (SPUindirect <arg>, <const + const>)
2710 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2711 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2712 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michelceae3bb2008-01-29 02:16:57 +00002713
Scott Michel82335272008-12-27 04:51:36 +00002714#if !defined(NDEBUG)
2715 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2716 cerr << "\n"
2717 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2718 << "), " << CN0->getSExtValue() << ")\n"
2719 << "With: (SPUindirect <arg>, "
2720 << combinedConst << ")\n";
2721 }
2722#endif
Scott Michelceae3bb2008-01-29 02:16:57 +00002723
Scott Michel82335272008-12-27 04:51:36 +00002724 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2725 IndirectArg, combinedValue);
2726 }
Scott Michelceae3bb2008-01-29 02:16:57 +00002727 }
2728 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002729 break;
2730 }
2731 case ISD::SIGN_EXTEND:
2732 case ISD::ZERO_EXTEND:
2733 case ISD::ANY_EXTEND: {
Scott Michel08a4e202008-12-01 17:56:02 +00002734 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002735 // (any_extend (SPUextract_elt0 <arg>)) ->
2736 // (SPUextract_elt0 <arg>)
2737 // Types must match, however...
Scott Michel187250b2008-12-04 17:16:59 +00002738#if !defined(NDEBUG)
2739 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel40f54d22008-12-04 03:02:42 +00002740 cerr << "\nReplace: ";
2741 N->dump(&DAG);
2742 cerr << "\nWith: ";
2743 Op0.getNode()->dump(&DAG);
2744 cerr << "\n";
Scott Michel187250b2008-12-04 17:16:59 +00002745 }
Scott Michel40f54d22008-12-04 03:02:42 +00002746#endif
Scott Michel7d5eaec2008-02-23 18:41:37 +00002747
2748 return Op0;
2749 }
2750 break;
2751 }
2752 case SPUISD::IndirectAddr: {
2753 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2754 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
Dan Gohmaneffb8942008-09-12 16:56:44 +00002755 if (CN->getZExtValue() == 0) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002756 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2757 // (SPUaform <addr>, 0)
2758
2759 DEBUG(cerr << "Replace: ");
2760 DEBUG(N->dump(&DAG));
2761 DEBUG(cerr << "\nWith: ");
Gabor Greiff304a7a2008-08-28 21:40:38 +00002762 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002763 DEBUG(cerr << "\n");
2764
2765 return Op0;
2766 }
Scott Michel82335272008-12-27 04:51:36 +00002767 } else if (Op0.getOpcode() == ISD::ADD) {
2768 SDValue Op1 = N->getOperand(1);
2769 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2770 // (SPUindirect (add <arg>, <arg>), 0) ->
2771 // (SPUindirect <arg>, <arg>)
2772 if (CN1->isNullValue()) {
2773
2774#if !defined(NDEBUG)
2775 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2776 cerr << "\n"
2777 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2778 << "With: (SPUindirect <arg>, <arg>)\n";
2779 }
2780#endif
2781
2782 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2783 Op0.getOperand(0), Op0.getOperand(1));
2784 }
2785 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002786 }
2787 break;
2788 }
2789 case SPUISD::SHLQUAD_L_BITS:
2790 case SPUISD::SHLQUAD_L_BYTES:
2791 case SPUISD::VEC_SHL:
2792 case SPUISD::VEC_SRL:
2793 case SPUISD::VEC_SRA:
Scott Michel82335272008-12-27 04:51:36 +00002794 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002795 SDValue Op1 = N->getOperand(1);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002796
Scott Michel82335272008-12-27 04:51:36 +00002797 // Kill degenerate vector shifts:
2798 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2799 if (CN->isNullValue()) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002800 Result = Op0;
2801 }
2802 }
2803 break;
2804 }
Scott Michel82335272008-12-27 04:51:36 +00002805 case SPUISD::PREFSLOT2VEC: {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002806 switch (Op0.getOpcode()) {
2807 default:
2808 break;
2809 case ISD::ANY_EXTEND:
2810 case ISD::ZERO_EXTEND:
2811 case ISD::SIGN_EXTEND: {
Scott Michelb8ee30d2008-12-29 03:23:36 +00002812 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel7d5eaec2008-02-23 18:41:37 +00002813 // <arg>
Scott Michelb8ee30d2008-12-29 03:23:36 +00002814 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002815 SDValue Op00 = Op0.getOperand(0);
Scott Michelefc8c7a2008-11-24 17:11:17 +00002816 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002817 SDValue Op000 = Op00.getOperand(0);
Scott Michel08a4e202008-12-01 17:56:02 +00002818 if (Op000.getValueType() == NodeVT) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002819 Result = Op000;
2820 }
2821 }
2822 break;
2823 }
Scott Michelefc8c7a2008-11-24 17:11:17 +00002824 case SPUISD::VEC2PREFSLOT: {
Scott Michelb8ee30d2008-12-29 03:23:36 +00002825 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel7d5eaec2008-02-23 18:41:37 +00002826 // <arg>
2827 Result = Op0.getOperand(0);
2828 break;
Scott Michelfe095082008-07-16 17:17:29 +00002829 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002830 }
2831 break;
Scott Michelceae3bb2008-01-29 02:16:57 +00002832 }
2833 }
Scott Michele4d3e3c2008-01-17 20:38:41 +00002834 // Otherwise, return unchanged.
Scott Michel08a4e202008-12-01 17:56:02 +00002835#ifndef NDEBUG
Gabor Greiff304a7a2008-08-28 21:40:38 +00002836 if (Result.getNode()) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002837 DEBUG(cerr << "\nReplace.SPU: ");
2838 DEBUG(N->dump(&DAG));
2839 DEBUG(cerr << "\nWith: ");
Gabor Greiff304a7a2008-08-28 21:40:38 +00002840 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002841 DEBUG(cerr << "\n");
2842 }
2843#endif
2844
2845 return Result;
Scott Michel6e22c652007-12-04 22:23:35 +00002846}
2847
2848//===----------------------------------------------------------------------===//
2849// Inline Assembly Support
2850//===----------------------------------------------------------------------===//
2851
2852/// getConstraintType - Given a constraint letter, return the type of
2853/// constraint it is for this target.
Scott Michelfe095082008-07-16 17:17:29 +00002854SPUTargetLowering::ConstraintType
Scott Michel6e22c652007-12-04 22:23:35 +00002855SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2856 if (ConstraintLetter.size() == 1) {
2857 switch (ConstraintLetter[0]) {
2858 default: break;
2859 case 'b':
2860 case 'r':
2861 case 'f':
2862 case 'v':
2863 case 'y':
2864 return C_RegisterClass;
Scott Michelfe095082008-07-16 17:17:29 +00002865 }
Scott Michel6e22c652007-12-04 22:23:35 +00002866 }
2867 return TargetLowering::getConstraintType(ConstraintLetter);
2868}
2869
Scott Michelfe095082008-07-16 17:17:29 +00002870std::pair<unsigned, const TargetRegisterClass*>
Scott Michel6e22c652007-12-04 22:23:35 +00002871SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands13237ac2008-06-06 12:08:01 +00002872 MVT VT) const
Scott Michel6e22c652007-12-04 22:23:35 +00002873{
2874 if (Constraint.size() == 1) {
2875 // GCC RS6000 Constraint Letters
2876 switch (Constraint[0]) {
2877 case 'b': // R1-R31
2878 case 'r': // R0-R31
2879 if (VT == MVT::i64)
2880 return std::make_pair(0U, SPU::R64CRegisterClass);
2881 return std::make_pair(0U, SPU::R32CRegisterClass);
2882 case 'f':
2883 if (VT == MVT::f32)
2884 return std::make_pair(0U, SPU::R32FPRegisterClass);
2885 else if (VT == MVT::f64)
2886 return std::make_pair(0U, SPU::R64FPRegisterClass);
2887 break;
Scott Michelfe095082008-07-16 17:17:29 +00002888 case 'v':
Scott Michel6e22c652007-12-04 22:23:35 +00002889 return std::make_pair(0U, SPU::GPRCRegisterClass);
2890 }
2891 }
Scott Michelfe095082008-07-16 17:17:29 +00002892
Scott Michel6e22c652007-12-04 22:23:35 +00002893 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2894}
2895
Scott Michel7d5eaec2008-02-23 18:41:37 +00002896//! Compute used/known bits for a SPU operand
Scott Michel6e22c652007-12-04 22:23:35 +00002897void
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002898SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmane1d9ee62008-02-13 22:28:48 +00002899 const APInt &Mask,
Scott Michelfe095082008-07-16 17:17:29 +00002900 APInt &KnownZero,
Dan Gohmanf990faf2008-02-13 00:35:47 +00002901 APInt &KnownOne,
Scott Michelbb713ae2008-01-30 02:55:46 +00002902 const SelectionDAG &DAG,
2903 unsigned Depth ) const {
Scott Michelc3a19102008-04-30 00:30:08 +00002904#if 0
Scott Michel7d5eaec2008-02-23 18:41:37 +00002905 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michelc3a19102008-04-30 00:30:08 +00002906#endif
Scott Michel7d5eaec2008-02-23 18:41:37 +00002907
2908 switch (Op.getOpcode()) {
2909 default:
2910 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2911 break;
2912
2913#if 0
2914 case CALL:
2915 case SHUFB:
Scott Michel0be03392008-11-22 23:50:42 +00002916 case SHUFFLE_MASK:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002917 case CNTB:
2918#endif
2919
Scott Michel82335272008-12-27 04:51:36 +00002920 case SPUISD::PREFSLOT2VEC: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002921 SDValue Op0 = Op.getOperand(0);
Duncan Sands13237ac2008-06-06 12:08:01 +00002922 MVT Op0VT = Op0.getValueType();
2923 unsigned Op0VTBits = Op0VT.getSizeInBits();
2924 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michelc3a19102008-04-30 00:30:08 +00002925 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2926 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002927 break;
2928 }
Scott Michelfe095082008-07-16 17:17:29 +00002929
Scott Michel7d5eaec2008-02-23 18:41:37 +00002930 case SPUISD::LDRESULT:
Scott Michel40f54d22008-12-04 03:02:42 +00002931 case SPUISD::VEC2PREFSLOT: {
Duncan Sands13237ac2008-06-06 12:08:01 +00002932 MVT OpVT = Op.getValueType();
2933 unsigned OpVTBits = OpVT.getSizeInBits();
2934 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michelc3a19102008-04-30 00:30:08 +00002935 KnownZero |= APInt(OpVTBits, ~InMask, false);
2936 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002937 break;
2938 }
2939
2940#if 0
Scott Michelc3a19102008-04-30 00:30:08 +00002941 case SPUISD::SHLQUAD_L_BITS:
2942 case SPUISD::SHLQUAD_L_BYTES:
2943 case SPUISD::VEC_SHL:
2944 case SPUISD::VEC_SRL:
2945 case SPUISD::VEC_SRA:
2946 case SPUISD::VEC_ROTL:
2947 case SPUISD::VEC_ROTR:
Scott Michelc3a19102008-04-30 00:30:08 +00002948 case SPUISD::ROTBYTES_LEFT:
Scott Micheld831cc42008-06-02 22:18:03 +00002949 case SPUISD::SELECT_MASK:
2950 case SPUISD::SELB:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002951#endif
2952 }
Scott Michel6e22c652007-12-04 22:23:35 +00002953}
Scott Michel41236c02008-12-30 23:28:25 +00002954
Scott Michel82335272008-12-27 04:51:36 +00002955unsigned
2956SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2957 unsigned Depth) const {
2958 switch (Op.getOpcode()) {
2959 default:
2960 return 1;
Scott Michel6e22c652007-12-04 22:23:35 +00002961
Scott Michel82335272008-12-27 04:51:36 +00002962 case ISD::SETCC: {
2963 MVT VT = Op.getValueType();
2964
2965 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2966 VT = MVT::i32;
2967 }
2968 return VT.getSizeInBits();
2969 }
2970 }
2971}
Scott Michelb8ee30d2008-12-29 03:23:36 +00002972
Scott Michelc3a19102008-04-30 00:30:08 +00002973// LowerAsmOperandForConstraint
2974void
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002975SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelc3a19102008-04-30 00:30:08 +00002976 char ConstraintLetter,
Evan Chenge0add202008-09-24 00:05:32 +00002977 bool hasMemory,
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002978 std::vector<SDValue> &Ops,
Scott Michelc3a19102008-04-30 00:30:08 +00002979 SelectionDAG &DAG) const {
2980 // Default, for the time being, to the base class handler
Evan Chenge0add202008-09-24 00:05:32 +00002981 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2982 Ops, DAG);
Scott Michelc3a19102008-04-30 00:30:08 +00002983}
2984
Scott Michel6e22c652007-12-04 22:23:35 +00002985/// isLegalAddressImmediate - Return true if the integer value can be used
2986/// as the offset of the target addressing mode.
Gabor Greif81d6a382008-08-31 15:37:04 +00002987bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2988 const Type *Ty) const {
Scott Michel6e22c652007-12-04 22:23:35 +00002989 // SPU's addresses are 256K:
2990 return (V > -(1 << 18) && V < (1 << 18) - 1);
2991}
2992
2993bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michelfe095082008-07-16 17:17:29 +00002994 return false;
Scott Michel6e22c652007-12-04 22:23:35 +00002995}
Dan Gohman2fe6bee2008-10-18 02:06:02 +00002996
2997bool
2998SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
2999 // The SPU target isn't yet aware of offsets.
3000 return false;
3001}