blob: 9dd98558509b618b82f388aeb7d878028e6e2fd5 [file] [log] [blame]
Scott Michel8efdca42007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel8efdca42007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michelbc5fbc12008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel06eabde2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel8efdca42007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel8efdca42007-12-04 22:23:35 +000025#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000041 //! MVT mapping to useful data for Cell SPU
Scott Michel8efdca42007-12-04 22:23:35 +000042 struct valtype_map_s {
Scott Michel56a125e2008-11-22 23:50:42 +000043 const MVT valtype;
44 const int prefslot_byte;
Scott Michel8efdca42007-12-04 22:23:35 +000045 };
Scott Michel4ec722e2008-07-16 17:17:29 +000046
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000060 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +000065 retval = valtype_map + i;
66 break;
Scott Michel8efdca42007-12-04 22:23:35 +000067 }
68 }
69
70#ifndef NDEBUG
71 if (retval == 0) {
72 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands92c43912008-06-06 12:08:01 +000073 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +000074 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +000075 abort();
76 }
77#endif
78
79 return retval;
80 }
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +000093
Scott Michel8efdca42007-12-04 22:23:35 +000094 // Set up the SPU's register classes:
Scott Michel438be252007-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 Michel8efdca42007-12-04 22:23:35 +0000101 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel4ec722e2008-07-16 17:17:29 +0000102
Scott Michel8efdca42007-12-04 22:23:35 +0000103 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng08c171a2008-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 Michel8efdca42007-12-04 22:23:35 +0000107
Scott Michel06eabde2008-12-27 04:51:36 +0000108 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
109 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelec8c82e2008-12-02 19:53:53 +0000110
Scott Michel8efdca42007-12-04 22:23:35 +0000111 // SPU constant load actions are custom lowered:
112 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begeman78125042008-02-14 18:43:04 +0000113 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-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 Michel2ef773a2009-01-06 03:36:14 +0000117 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel8efdca42007-12-04 22:23:35 +0000118 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000119 MVT VT = (MVT::SimpleValueType)sctype;
120
Scott Michel06eabde2008-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 Michelae5cbf52008-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 Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000135 }
136
Scott Michel06eabde2008-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 Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000153
154 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel4ec722e2008-07-16 17:17:29 +0000155 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel56a125e2008-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 Michel8efdca42007-12-04 22:23:35 +0000160
161 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000162 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
163
Scott Michel06eabde2008-12-27 04:51:36 +0000164 // SPU has no SREM/UREM instructions
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000169
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000177
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000181
Scott Michel8efdca42007-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 Wendling965299c2008-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 Michel8efdca42007-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 Michelabb8ca12008-11-20 16:36:33 +0000197
Scott Michel8efdca42007-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 Michel33d73eb2008-11-21 02:56:16 +0000202
Scott Michel4d07fb72008-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 Michel8efdca42007-12-04 22:23:35 +0000207
Scott Michel4ec722e2008-07-16 17:17:29 +0000208 // Custom lower i8, i32 and i64 multiplications
209 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelae5cbf52008-12-29 03:23:36 +0000210 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel33d73eb2008-11-21 02:56:16 +0000211 setOperationAction(ISD::MUL, MVT::i64, Expand); // libcall
212
Scott Michel67224b22008-06-02 22:18:03 +0000213 // Need to custom handle (some) common i8, i64 math ops
Scott Michel4d07fb72008-12-30 23:28:25 +0000214 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel67224b22008-06-02 22:18:03 +0000215 setOperationAction(ISD::ADD, MVT::i64, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000216 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel67224b22008-06-02 22:18:03 +0000217 setOperationAction(ISD::SUB, MVT::i64, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000218
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000233
Scott Michel67224b22008-06-02 22:18:03 +0000234 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel978b96f2008-03-10 23:49:09 +0000235 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000236 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000237 setOperationAction(ISD::SELECT, MVT::i16, Legal);
238 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel06eabde2008-12-27 04:51:36 +0000239 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000240
Scott Michel53ab7792008-03-10 16:58:52 +0000241 setOperationAction(ISD::SETCC, MVT::i8, Legal);
242 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000243 setOperationAction(ISD::SETCC, MVT::i32, Legal);
244 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000245
Scott Michel97872d32008-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 Michel97872d32008-02-23 18:41:37 +0000249 setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000250
Scott Michel06eabde2008-12-27 04:51:36 +0000251 // Custom lower i128 -> i64 truncates
Scott Michelec8c82e2008-12-02 19:53:53 +0000252 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
253
Scott Michel8efdca42007-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 Michel06eabde2008-12-27 04:51:36 +0000261 setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall
Scott Michel8efdca42007-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 Michel754d8662007-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 Michel8efdca42007-12-04 22:23:35 +0000277
278 // We cannot sextinreg(i1). Expand to shifts.
279 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000280
Scott Michel8efdca42007-12-04 22:23:35 +0000281 // Support label based line numbers.
Dan Gohman472d12c2008-06-30 20:59:49 +0000282 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000283 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000284
285 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel8efdca42007-12-04 22:23:35 +0000286 // appropriate instructions to materialize the address.
Scott Michel33d73eb2008-11-21 02:56:16 +0000287 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelf9f42e62008-01-29 02:16:57 +0000288 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000289 MVT VT = (MVT::SimpleValueType)sctype;
290
Scott Michelae5cbf52008-12-29 03:23:36 +0000291 setOperationAction(ISD::GlobalAddress, VT, Custom);
292 setOperationAction(ISD::ConstantPool, VT, Custom);
293 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelf9f42e62008-01-29 02:16:57 +0000294 }
Scott Michel8efdca42007-12-04 22:23:35 +0000295
296 // RET must be custom lowered, to meet ABI requirements
297 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000298
Scott Michel8efdca42007-12-04 22:23:35 +0000299 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
300 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000301
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000306 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000314
Scott Michel8efdca42007-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 Michel70741542009-01-06 23:10:38 +0000330 // "Odd size" vector classes that we're willing to support:
331 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
332
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000336
Duncan Sands92c43912008-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 Michel4d07fb72008-12-30 23:28:25 +0000341 // TODO: v2i64 vector multiply
342 setOperationAction(ISD::MUL , VT, Legal);
Duncan Sands92c43912008-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 Michel4ec722e2008-07-16 17:17:29 +0000350
Scott Michel8efdca42007-12-04 22:23:35 +0000351 // These operations need to be expanded:
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000356
357 // Custom lower build_vector, constant pool spills, insert and
358 // extract vector elements:
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000365 }
366
Scott Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000371
Scott Michel4d07fb72008-12-30 23:28:25 +0000372 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000373
Scott Michel8efdca42007-12-04 22:23:35 +0000374 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000375 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000376
Scott Michel8efdca42007-12-04 22:23:35 +0000377 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000378
Scott Michel8efdca42007-12-04 22:23:35 +0000379 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000380 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000381 setTargetDAGCombine(ISD::ZERO_EXTEND);
382 setTargetDAGCombine(ISD::SIGN_EXTEND);
383 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000384
Scott Michel8efdca42007-12-04 22:23:35 +0000385 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000386
Scott Michel2c261072008-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 Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000401 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000402 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000406 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000407 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000408 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000409 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-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 Michel8efdca42007-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 Michel67224b22008-06-02 22:18:03 +0000417 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000418 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel67224b22008-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 Michel8efdca42007-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 Michel06eabde2008-12-27 04:51:36 +0000430//===----------------------------------------------------------------------===//
431// Return the Cell SPU's SETCC result type
432//===----------------------------------------------------------------------===//
433
Duncan Sands4a361272009-01-01 15:52:00 +0000434MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-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 Michel53ab7792008-03-10 16:58:52 +0000437}
438
Scott Michel8efdca42007-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 Michel6ccefab2008-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 Michelae5cbf52008-12-29 03:23:36 +0000458%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000459%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000460%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000461%4 f32 = vec2perfslot %3
462%5 f64 = fp_extend %4
463\endverbatim
464*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000465static SDValue
466LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000467 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000468 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000469 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000470 MVT InVT = LN->getMemoryVT();
471 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000472 ISD::LoadExtType ExtType = LN->getExtensionType();
473 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000474 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000475
Scott Michel8efdca42007-12-04 22:23:35 +0000476 switch (LN->getAddressingMode()) {
477 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000478 SDValue result;
479 SDValue basePtr = LN->getBasePtr();
480 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000481
Scott Michel06eabde2008-12-27 04:51:36 +0000482 if (alignment == 16) {
483 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000484
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000492
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000515 } else {
Scott Michel06eabde2008-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 Michel5a6f17b2008-01-30 02:55:46 +0000523 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000524 }
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000532
Scott Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000559 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000560
Scott Michel06eabde2008-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 Michel6ccefab2008-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 Michel4ec722e2008-07-16 17:17:29 +0000578
Scott Michel6ccefab2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000586
Scott Michel6ccefab2008-12-04 03:02:42 +0000587 if (OutVT.isFloatingPoint())
588 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000589
Scott Michel6ccefab2008-12-04 03:02:42 +0000590 result = DAG.getNode(NewOpc, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000591 }
592
Scott Michel6ccefab2008-12-04 03:02:42 +0000593 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000594 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000595 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000596 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000597 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000598
Scott Michel394e26d2008-01-17 20:38:41 +0000599 result = DAG.getNode(SPUISD::LDRESULT, retvts,
600 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000601 return result;
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +0000615 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +0000624static SDValue
625LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000626 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000627 SDValue Value = SN->getValue();
Duncan Sands92c43912008-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 Micheldbac4cf2008-01-11 02:53:15 +0000631 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000632
633 switch (SN->getAddressingMode()) {
634 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000635 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000636 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
637 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000638
Scott Michel06eabde2008-12-27 04:51:36 +0000639 SDValue alignLoadVec;
640 SDValue basePtr = SN->getBasePtr();
641 SDValue the_chain = SN->getChain();
642 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000643
Scott Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000713
Scott Micheldbac4cf2008-01-11 02:53:15 +0000714 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000715 SDValue theValue = SN->getValue();
716 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000717
718 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000719 && (theValue.getOpcode() == ISD::AssertZext
720 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000721 // Drill down and get the value for zero- and sign-extended
722 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000723 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000724 }
725
Scott Micheldbac4cf2008-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 Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000737
Scott Michelf65c8f02008-11-19 15:24:16 +0000738 SDValue insertEltOp =
Scott Michel06eabde2008-12-27 04:51:36 +0000739 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000740 SDValue vectorizeOp =
741 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000742
Scott Michel0718cd82008-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 Michel8efdca42007-12-04 22:23:35 +0000746
Scott Micheldbac4cf2008-01-11 02:53:15 +0000747 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000748 LN->getSrcValue(), LN->getSrcValueOffset(),
749 LN->isVolatile(), LN->getAlignment());
750
Scott Michel8c2746e2008-12-04 17:16:59 +0000751#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-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 Michelec8c82e2008-12-02 19:53:53 +0000762
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +0000778 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000779}
780
781/// Generate the address of a constant pool entry.
Dan Gohman8181bd12008-07-27 21:46:04 +0000782static SDValue
783LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000784 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000785 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
786 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000787 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
788 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000789 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000790
791 if (TM.getRelocationModel() == Reloc::Static) {
792 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000793 // Just return the SDValue with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000794 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000795 } else {
Dan Gohman8181bd12008-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 Michel97872d32008-02-23 18:41:37 +0000798 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000799 }
800 }
801
802 assert(0 &&
Gabor Greife9f7f582008-08-31 15:37:04 +0000803 "LowerConstantPool: Relocation model other than static"
804 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000805 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000806}
807
Dan Gohman8181bd12008-07-27 21:46:04 +0000808static SDValue
809LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000810 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000811 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000812 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
813 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000814 const TargetMachine &TM = DAG.getTarget();
815
816 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000817 if (!ST->usingLargeMem()) {
818 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
819 } else {
Dan Gohman8181bd12008-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 Michel97872d32008-02-23 18:41:37 +0000822 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
823 }
Scott Michel8efdca42007-12-04 22:23:35 +0000824 }
825
826 assert(0 &&
827 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000828 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000829}
830
Dan Gohman8181bd12008-07-27 21:46:04 +0000831static SDValue
832LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000833 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000834 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
835 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000836 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000837 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000838 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel4ec722e2008-07-16 17:17:29 +0000839
Scott Michel8efdca42007-12-04 22:23:35 +0000840 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000841 if (!ST->usingLargeMem()) {
842 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
843 } else {
Dan Gohman8181bd12008-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 Michelf9f42e62008-01-29 02:16:57 +0000846 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
847 }
Scott Michel8efdca42007-12-04 22:23:35 +0000848 } else {
849 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000850 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000851 abort();
852 /*NOTREACHED*/
853 }
854
Dan Gohman8181bd12008-07-27 21:46:04 +0000855 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +0000863static SDValue
864LowerConstant(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000865 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000866
867 if (VT == MVT::i64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000868 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
869 SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michelc630c412008-11-24 17:11:17 +0000870 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000871 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +0000872 } else {
873 cerr << "LowerConstant: unhandled constant type "
Duncan Sands92c43912008-06-06 12:08:01 +0000874 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +0000875 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000876 abort();
877 /*NOTREACHED*/
878 }
879
Dan Gohman8181bd12008-07-27 21:46:04 +0000880 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000881}
882
Nate Begeman78125042008-02-14 18:43:04 +0000883//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000884static SDValue
885LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000886 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000887
Nate Begeman78125042008-02-14 18:43:04 +0000888 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000889 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
890
891 assert((FP != 0) &&
892 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000893
Scott Michel11e88bb2007-12-19 20:15:47 +0000894 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-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 Michel8efdca42007-12-04 22:23:35 +0000899 }
900
Dan Gohman8181bd12008-07-27 21:46:04 +0000901 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000902}
903
Dan Gohman8181bd12008-07-27 21:46:04 +0000904static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000905LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000906{
907 MachineFunction &MF = DAG.getMachineFunction();
908 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000909 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000910 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000911 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000912 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel8efdca42007-12-04 22:23:35 +0000913
914 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
915 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000916
Scott Michel8efdca42007-12-04 22:23:35 +0000917 unsigned ArgOffset = SPUFrameInfo::minStackSize();
918 unsigned ArgRegIdx = 0;
919 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000920
Duncan Sands92c43912008-06-06 12:08:01 +0000921 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000922
Scott Michel8efdca42007-12-04 22:23:35 +0000923 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000924 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
925 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000926 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
927 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000928 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000929
Scott Michela313fb02008-10-30 01:51:48 +0000930 if (ArgRegIdx < NumArgRegs) {
931 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000932
Scott Michela313fb02008-10-30 01:51:48 +0000933 switch (ObjectVT.getSimpleVT()) {
934 default: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000935 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
936 << ObjectVT.getMVTString()
937 << "\n";
938 abort();
Scott Michela313fb02008-10-30 01:51:48 +0000939 }
940 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000941 ArgRegClass = &SPU::R8CRegClass;
942 break;
Scott Michela313fb02008-10-30 01:51:48 +0000943 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +0000944 ArgRegClass = &SPU::R16CRegClass;
945 break;
Scott Michela313fb02008-10-30 01:51:48 +0000946 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000947 ArgRegClass = &SPU::R32CRegClass;
948 break;
Scott Michela313fb02008-10-30 01:51:48 +0000949 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000950 ArgRegClass = &SPU::R64CRegClass;
951 break;
Scott Michel2ef773a2009-01-06 03:36:14 +0000952 case MVT::i128:
953 ArgRegClass = &SPU::GPRCRegClass;
954 break;
Scott Michela313fb02008-10-30 01:51:48 +0000955 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000956 ArgRegClass = &SPU::R32FPRegClass;
957 break;
Scott Michela313fb02008-10-30 01:51:48 +0000958 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000959 ArgRegClass = &SPU::R64FPRegClass;
960 break;
Scott Michela313fb02008-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 Michel33d73eb2008-11-21 02:56:16 +0000967 ArgRegClass = &SPU::VECREGRegClass;
968 break;
Scott Michela313fb02008-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 Lattner60069452008-02-13 07:35:30 +0000979 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +0000980 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner60069452008-02-13 07:35:30 +0000981 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +0000982 ArgOffset += StackSlotSize;
983 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000984
Scott Michel8efdca42007-12-04 22:23:35 +0000985 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +0000986 // Update the chain
987 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000988 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000989
Scott Michela313fb02008-10-30 01:51:48 +0000990 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +0000991 if (isVarArg) {
Scott Michela313fb02008-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 Michel8efdca42007-12-04 22:23:35 +0000998 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-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 Michel8efdca42007-12-04 22:23:35 +00001004 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001005
1006 // Increment address by stack slot size for the next stored argument
1007 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001008 }
1009 if (!MemOps.empty())
Scott Michela313fb02008-10-30 01:51:48 +00001010 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001011 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001012
Scott Michel8efdca42007-12-04 22:23:35 +00001013 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001014
Scott Michel8efdca42007-12-04 22:23:35 +00001015 // Return the new list of results.
Duncan Sands42d7bb82008-12-01 11:41:29 +00001016 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1017 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001022static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001023 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001024 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001025
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001026 int Addr = C->getZExtValue();
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001030
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001031 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001032}
1033
Scott Michel70741542009-01-06 23:10:38 +00001034static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +00001035LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001036 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1037 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001038 SDValue Callee = TheCall->getCallee();
1039 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +00001045 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001046
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001051
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001055 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001056
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001063 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001064 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001065 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001066
1067 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001068 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001069
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001072 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel8efdca42007-12-04 22:23:35 +00001073 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1074
Duncan Sands92c43912008-06-06 12:08:01 +00001075 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001076 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001077 case MVT::i8:
1078 case MVT::i16:
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001086 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001095 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001096 }
1097 break;
Scott Michele2641a12008-12-04 21:01:44 +00001098 case MVT::v2i64:
1099 case MVT::v2f64:
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001108 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-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 Lattnerfe5d4022008-10-11 22:08:30 +00001116 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1117 true));
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001124
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001127 SDValue InFlag;
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001133
Dan Gohman8181bd12008-07-27 21:46:04 +00001134 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001135 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001136
Bill Wendlingfef06052008-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 Michel5974f432008-11-11 03:06:06 +00001140 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001141 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001142 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001143 SDValue Zero = DAG.getConstant(0, PtrVT);
1144 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001145
Scott Micheldbac4cf2008-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 Michel8efdca42007-12-04 22:23:35 +00001160 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001161 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1162 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001163 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001164 }
Scott Michelae5cbf52008-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 Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001179 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001180 }
Scott Michel8efdca42007-12-04 22:23:35 +00001181
1182 Ops.push_back(Chain);
1183 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001184
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001188 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001189 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001190
Gabor Greif1c80d112008-08-28 21:40:38 +00001191 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001192 Ops.push_back(InFlag);
Duncan Sands698842f2008-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 Michel8efdca42007-12-04 22:23:35 +00001196 InFlag = Chain.getValue(1);
1197
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001198 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1199 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001200 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001201 InFlag = Chain.getValue(1);
1202
Dan Gohman8181bd12008-07-27 21:46:04 +00001203 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001204 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001205
Scott Michel8efdca42007-12-04 22:23:35 +00001206 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001207 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001208 default: assert(0 && "Unexpected ret value!");
1209 case MVT::Other: break;
1210 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001211 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel8efdca42007-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 Michel8efdca42007-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 Michel8efdca42007-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 Michel8efdca42007-12-04 22:23:35 +00001228 break;
Scott Michel2ef773a2009-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 Michel8efdca42007-12-04 22:23:35 +00001234 case MVT::f32:
1235 case MVT::f64:
Dan Gohman705e3f72008-09-13 01:54:27 +00001236 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001237 InFlag).getValue(1);
1238 ResultVals[0] = Chain.getValue(0);
1239 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001240 break;
1241 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001242 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001243 case MVT::v4f32:
1244 case MVT::v4i32:
1245 case MVT::v8i16:
1246 case MVT::v16i8:
Dan Gohman705e3f72008-09-13 01:54:27 +00001247 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001248 InFlag).getValue(1);
1249 ResultVals[0] = Chain.getValue(0);
1250 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001251 break;
1252 }
Duncan Sands698842f2008-07-02 17:40:58 +00001253
Scott Michel8efdca42007-12-04 22:23:35 +00001254 // If the function returns void, just return the chain.
1255 if (NumResults == 0)
1256 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001257
Scott Michel8efdca42007-12-04 22:23:35 +00001258 // Otherwise, merge everything together with a MERGE_VALUES node.
1259 ResultVals[NumResults++] = Chain;
Dan Gohman8181bd12008-07-27 21:46:04 +00001260 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif46bf5472008-08-26 22:36:50 +00001261 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001262}
1263
Dan Gohman8181bd12008-07-27 21:46:04 +00001264static SDValue
1265LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001270 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001271
Scott Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +00001274 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001275 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001276 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001277 }
1278
Dan Gohman8181bd12008-07-27 21:46:04 +00001279 SDValue Chain = Op.getOperand(0);
1280 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001281
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001290 if (Flag.getNode())
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001303 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001304
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001308 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001309 OpVal = N->getOperand(i);
1310 else if (OpVal != N->getOperand(i))
1311 return 0;
1312 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001313
Gabor Greif1c80d112008-08-28 21:40:38 +00001314 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001315 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001326SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001327 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001328 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001329 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001330 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001331 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001335 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001336 Value = Value >> 32;
1337 }
Scott Michel8efdca42007-12-04 22:23:35 +00001338 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001339 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001340 }
1341
Dan Gohman8181bd12008-07-27 21:46:04 +00001342 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001348SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001349 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001350 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001351 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001352 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001353 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001357 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001358 Value = Value >> 32;
1359 }
Scott Michel6baba072008-03-05 23:02:02 +00001360 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001361 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001362 }
1363 }
1364
Dan Gohman8181bd12008-07-27 21:46:04 +00001365 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001371SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001372 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001373 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001374 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001375 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001376 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001380 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001381 Value = Value >> 32;
1382 }
Scott Michel6baba072008-03-05 23:02:02 +00001383 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001384 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001385 }
1386
Dan Gohman8181bd12008-07-27 21:46:04 +00001387 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001397SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001398 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001399 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001400 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001401 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001402 && Value <= 0xffff /* truncated from uint64_t */
1403 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001404 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001405 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001406 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001407 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001408 }
1409
Dan Gohman8181bd12008-07-27 21:46:04 +00001410 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001416SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001417 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001418 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001419 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001420 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001421 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1422 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001423 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001424 }
1425
Dan Gohman8181bd12008-07-27 21:46:04 +00001426 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001427}
1428
1429/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001430SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001431 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001432 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001433 }
1434
Dan Gohman8181bd12008-07-27 21:46:04 +00001435 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001436}
1437
1438/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001439SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001440 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001441 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001442 }
1443
Dan Gohman8181bd12008-07-27 21:46:04 +00001444 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001445}
1446
1447// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001448// UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001456
Duncan Sands92c43912008-06-06 12:08:01 +00001457 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel8efdca42007-12-04 22:23:35 +00001458 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001459 SDValue OpVal = BV->getOperand(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001460
Scott Michel8efdca42007-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 Michel5974f432008-11-11 03:06:06 +00001469 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001470 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel5974f432008-11-11 03:06:06 +00001471 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001472 const APFloat &apf = CN->getValueAPF();
1473 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001474 ? FloatToBits(apf.convertToFloat())
1475 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001476 } else {
1477 // Nonconstant element.
1478 return true;
1479 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001480
Scott Michel8efdca42007-12-04 22:23:35 +00001481 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1482 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001483
1484 //printf("%llx %llx %llx %llx\n",
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001491/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel8efdca42007-12-04 22:23:35 +00001492/// SplatSize = 1 byte.
Scott Michel4ec722e2008-07-16 17:17:29 +00001493static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel8efdca42007-12-04 22:23:35 +00001494 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001495 int MinSplatBits,
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001509
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001513 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001514
Scott Michel5a6f17b2008-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 Greife9f7f582008-08-31 15:37:04 +00001521 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1522 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel5a6f17b2008-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 Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001559static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001560 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00001561 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001562 // UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001563 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel4ec722e2008-07-16 17:17:29 +00001564 // zero.
Scott Michel8efdca42007-12-04 22:23:35 +00001565 uint64_t VectorBits[2];
1566 uint64_t UndefBits[2];
1567 uint64_t SplatBits, SplatUndef;
1568 int SplatSize;
Gabor Greif1c80d112008-08-28 21:40:38 +00001569 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel8efdca42007-12-04 22:23:35 +00001570 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00001571 VT.getVectorElementType().getSizeInBits(),
Scott Michel8efdca42007-12-04 22:23:35 +00001572 SplatBits, SplatUndef, SplatSize))
Dan Gohman8181bd12008-07-27 21:46:04 +00001573 return SDValue(); // Not a constant vector, not a splat.
Scott Michel4ec722e2008-07-16 17:17:29 +00001574
Duncan Sands92c43912008-06-06 12:08:01 +00001575 switch (VT.getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001576 default:
1577 case MVT::v4f32: {
1578 uint32_t Value32 = SplatBits;
1579 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001580 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001581 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001582 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001583 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001584 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001585 break;
1586 }
1587 case MVT::v2f64: {
1588 uint64_t f64val = SplatBits;
1589 assert(SplatSize == 8
Scott Michelc630c412008-11-24 17:11:17 +00001590 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001591 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001592 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001593 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001594 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001600 SDValue Ops[8];
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001608 if (SplatSize == 2)
Scott Michel8efdca42007-12-04 22:23:35 +00001609 Value16 = (unsigned short) (SplatBits & 0xffff);
1610 else
1611 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman8181bd12008-07-27 21:46:04 +00001612 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1613 SDValue Ops[8];
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001619 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel8efdca42007-12-04 22:23:35 +00001620 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1621 }
Scott Michel70741542009-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 Michel8efdca42007-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 Michelbcc7b672008-03-06 04:02:54 +00001632 if (upper == lower) {
1633 // Magic constant that can be matched by IL, ILA, et. al.
Dan Gohman8181bd12008-07-27 21:46:04 +00001634 SDValue Val = DAG.getTargetConstant(val, MVT::i64);
Scott Michelbcc7b672008-03-06 04:02:54 +00001635 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel6baba072008-03-05 23:02:02 +00001636 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +00001637 SDValue LO32;
1638 SDValue HI32;
1639 SmallVector<SDValue, 16> ShufBytes;
1640 SDValue Result;
Scott Michel8efdca42007-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 Michelc630c412008-11-24 17:11:17 +00001648 upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
1649 lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
Scott Michel8efdca42007-12-04 22:23:35 +00001650
1651 // Create lower vector if not a special pattern
1652 if (!lower_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001653 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Scott Michel5a6f17b2008-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 Michel8efdca42007-12-04 22:23:35 +00001657 }
1658
1659 // Create upper vector if not a special pattern
1660 if (!upper_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001661 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Scott Michel5a6f17b2008-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 Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001670 LO32 = HI32;
Scott Michel8efdca42007-12-04 22:23:35 +00001671 if (upper_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001672 HI32 = LO32;
Scott Michel8efdca42007-12-04 22:23:35 +00001673 if (lower_special && upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001674 // Unhappy situation... both upper and lower are special, so punt with
1675 // a target constant:
Dan Gohman8181bd12008-07-27 21:46:04 +00001676 SDValue Zero = DAG.getConstant(0, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001677 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel8efdca42007-12-04 22:23:35 +00001678 Zero, Zero);
1679 }
1680
1681 for (int i = 0; i < 4; ++i) {
Scott Michel67224b22008-06-02 22:18:03 +00001682 uint64_t val = 0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001683 for (int j = 0; j < 4; ++j) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001684 SDValue V;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001685 bool process_upper, process_lower;
Scott Michel67224b22008-06-02 22:18:03 +00001686 val <<= 8;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001687 process_upper = (upper_special && (i & 1) == 0);
1688 process_lower = (lower_special && (i & 1) == 1);
Scott Michel8efdca42007-12-04 22:23:35 +00001689
Scott Michel5a6f17b2008-01-30 02:55:46 +00001690 if (process_upper || process_lower) {
1691 if ((process_upper && upper == 0)
1692 || (process_lower && lower == 0))
Scott Michel67224b22008-06-02 22:18:03 +00001693 val |= 0x80;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001694 else if ((process_upper && upper == 0xffffffff)
1695 || (process_lower && lower == 0xffffffff))
Scott Michel67224b22008-06-02 22:18:03 +00001696 val |= 0xc0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001697 else if ((process_upper && upper == 0x80000000)
1698 || (process_lower && lower == 0x80000000))
Scott Michel67224b22008-06-02 22:18:03 +00001699 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001700 } else
Scott Michel67224b22008-06-02 22:18:03 +00001701 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001702 }
Scott Michel67224b22008-06-02 22:18:03 +00001703
1704 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001705 }
1706
1707 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel67224b22008-06-02 22:18:03 +00001708 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001709 &ShufBytes[0], ShufBytes.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001710 }
1711 }
1712 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001713
Dan Gohman8181bd12008-07-27 21:46:04 +00001714 return SDValue();
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +00001721/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +00001725/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-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 Gohman8181bd12008-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 Michel4ec722e2008-07-16 17:17:29 +00001734
Scott Michel8efdca42007-12-04 22:23:35 +00001735 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001736
Scott Michel8efdca42007-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 Michele2641a12008-12-04 21:01:44 +00001740 MVT VecVT = V1.getValueType();
1741 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001742 unsigned EltsFromV2 = 0;
1743 unsigned V2Elt = 0;
1744 unsigned V2EltIdx0 = 0;
1745 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001746 unsigned MaxElts = VecVT.getVectorNumElements();
1747 unsigned PrevElt = 0;
1748 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001749 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001750 bool rotate = true;
1751
1752 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001753 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001754 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001755 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001756 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001757 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001758 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1759 V2EltIdx0 = 2;
1760 } else
Scott Michel8efdca42007-12-04 22:23:35 +00001761 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1762
Scott Michele2641a12008-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 Michel8efdca42007-12-04 22:23:35 +00001766
Scott Michele2641a12008-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 Michel8efdca42007-12-04 22:23:35 +00001797 }
Scott Michel8efdca42007-12-04 22:23:35 +00001798 }
1799
1800 if (EltsFromV2 == 1 && monotonic) {
1801 // Compute mask and shuffle
1802 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001803 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1804 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001805 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001806 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001807 SDValue InitTempReg =
Scott Michel8efdca42007-12-04 22:23:35 +00001808 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001809 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001810 SDValue ShufMaskOp =
Scott Michel0718cd82008-12-01 17:56:02 +00001811 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001812 DAG.getTargetConstant(V2Elt, MVT::i32),
1813 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-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 Michele2641a12008-12-04 21:01:44 +00001816 } else if (rotate) {
1817 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001818
Scott Michele2641a12008-12-04 21:01:44 +00001819 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1820 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001821 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001822 // Convert the SHUFFLE_VECTOR mask's input element units to the
1823 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001824 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001825
Dan Gohman8181bd12008-07-27 21:46:04 +00001826 SmallVector<SDValue, 16> ResultMask;
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001830 SrcElt = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001831 else
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001832 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel4ec722e2008-07-16 17:17:29 +00001833
Scott Michel97872d32008-02-23 18:41:37 +00001834 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001835 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1836 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001837 }
1838 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001839
Dan Gohman8181bd12008-07-27 21:46:04 +00001840 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel0718cd82008-12-01 17:56:02 +00001841 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001842 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1843 }
1844}
1845
Dan Gohman8181bd12008-07-27 21:46:04 +00001846static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1847 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001848
Gabor Greif1c80d112008-08-28 21:40:38 +00001849 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001853 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001854 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001855 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001856 size_t n_copies;
1857
1858 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001859 switch (Op.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001860 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001861 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-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 Gohmanfaeb4a32008-09-12 16:56:44 +00001870 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00001875 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001876 } else {
1877 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001878 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-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 Michel06eabde2008-12-27 04:51:36 +00001886 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001887 }
1888 }
1889
Dan Gohman8181bd12008-07-27 21:46:04 +00001890 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001891}
1892
Dan Gohman8181bd12008-07-27 21:46:04 +00001893static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001894 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001895 SDValue N = Op.getOperand(0);
1896 SDValue Elt = Op.getOperand(1);
Scott Michel56a125e2008-11-22 23:50:42 +00001897 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001898
Scott Michel56a125e2008-11-22 23:50:42 +00001899 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1900 // Constant argument:
1901 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001902
Scott Michel56a125e2008-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 Michel8efdca42007-12-04 22:23:35 +00001912
Scott Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00001915 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001916 }
Scott Michel8efdca42007-12-04 22:23:35 +00001917
Scott Michel56a125e2008-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 Michele2641a12008-12-04 21:01:44 +00001966 unsigned bidx = i * 4;
Scott Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00001978 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00001996 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1997 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00001998 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00001999
Scott Michelc630c412008-11-24 17:11:17 +00002000 if (scaleShift > 0) {
2001 // Scale the shift factor:
Scott Michel56a125e2008-11-22 23:50:42 +00002002 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00002003 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00002004 }
2005
Scott Michelc630c412008-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 Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00002018 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00002024 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel56a125e2008-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 Michelc630c412008-11-24 17:11:17 +00002046 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel0718cd82008-12-01 17:56:02 +00002047 DAG.getNode(SPUISD::SHUFB, VecVT,
2048 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002049 }
2050
Scott Michel56a125e2008-11-22 23:50:42 +00002051 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002052}
2053
Dan Gohman8181bd12008-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 Sands92c43912008-06-06 12:08:01 +00002058 MVT VT = Op.getValueType();
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +00002063 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-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 Michel8efdca42007-12-04 22:23:35 +00002069
Dan Gohman8181bd12008-07-27 21:46:04 +00002070 SDValue result =
Scott Michel8efdca42007-12-04 22:23:35 +00002071 DAG.getNode(SPUISD::SHUFB, VT,
2072 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002073 VecOp,
Scott Michel0718cd82008-12-01 17:56:02 +00002074 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002075
2076 return result;
2077}
2078
Scott Michel06eabde2008-12-27 04:51:36 +00002079static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2080 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002081{
Dan Gohman8181bd12008-07-27 21:46:04 +00002082 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michel06eabde2008-12-27 04:51:36 +00002083 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-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 Michel4d07fb72008-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 Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002105 SDValue N1 = Op.getOperand(1);
Scott Michel4d07fb72008-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 Michel4ec722e2008-07-16 17:17:29 +00002108 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002109 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel4ec722e2008-07-16 17:17:29 +00002110 }
Scott Michel8efdca42007-12-04 22:23:35 +00002111 case ISD::ROTR:
2112 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002113 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002114 unsigned N1Opc;
2115 N0 = (N0.getOpcode() != ISD::Constant
2116 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002117 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2118 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002119 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002120 ? ISD::ZERO_EXTEND
2121 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002122 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002123 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002124 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002125 TLI.getShiftAmountTy()));
Dan Gohman8181bd12008-07-27 21:46:04 +00002126 SDValue ExpandArg =
Scott Michel8efdca42007-12-04 22:23:35 +00002127 DAG.getNode(ISD::OR, MVT::i16, N0,
2128 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002129 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel4ec722e2008-07-16 17:17:29 +00002130 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002131 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2132 }
2133 case ISD::SRL:
2134 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002135 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002136 unsigned N1Opc;
2137 N0 = (N0.getOpcode() != ISD::Constant
2138 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002139 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002140 MVT::i32));
2141 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002142 ? ISD::ZERO_EXTEND
2143 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002144 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002145 ? DAG.getNode(N1Opc, ShiftVT, N1)
2146 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002147 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002148 DAG.getNode(Opc, MVT::i16, N0, N1));
2149 }
2150 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002151 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002152 unsigned N1Opc;
2153 N0 = (N0.getOpcode() != ISD::Constant
2154 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michel06eabde2008-12-27 04:51:36 +00002155 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002156 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002157 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002158 ? ISD::SIGN_EXTEND
2159 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002160 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002161 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002162 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002163 ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002164 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002165 DAG.getNode(Opc, MVT::i16, N0, N1));
2166 }
2167 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002168 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002169 unsigned N1Opc;
2170 N0 = (N0.getOpcode() != ISD::Constant
2171 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002172 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2173 MVT::i16));
Duncan Sandsec142ee2008-06-08 20:54:56 +00002174 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002175 N1 = (N1.getOpcode() != ISD::Constant
2176 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michel06eabde2008-12-27 04:51:36 +00002177 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002178 MVT::i16));
Scott Michel4ec722e2008-07-16 17:17:29 +00002179 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002180 DAG.getNode(Opc, MVT::i16, N0, N1));
2181 break;
2182 }
2183 }
2184
Dan Gohman8181bd12008-07-27 21:46:04 +00002185 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002186}
2187
Dan Gohman8181bd12008-07-27 21:46:04 +00002188static SDValue LowerI64Math(SDValue Op, SelectionDAG &DAG, unsigned Opc)
Scott Michel97872d32008-02-23 18:41:37 +00002189{
Duncan Sands92c43912008-06-06 12:08:01 +00002190 MVT VT = Op.getValueType();
2191 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel97872d32008-02-23 18:41:37 +00002192
Dan Gohman8181bd12008-07-27 21:46:04 +00002193 SDValue Op0 = Op.getOperand(0);
Scott Michel97872d32008-02-23 18:41:37 +00002194
2195 switch (Opc) {
2196 case ISD::ZERO_EXTEND:
Scott Michel97872d32008-02-23 18:41:37 +00002197 case ISD::ANY_EXTEND: {
Duncan Sands92c43912008-06-06 12:08:01 +00002198 MVT Op0VT = Op0.getValueType();
2199 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
Scott Michel97872d32008-02-23 18:41:37 +00002200
Dan Gohman8181bd12008-07-27 21:46:04 +00002201 SDValue PromoteScalar =
Scott Michel06eabde2008-12-27 04:51:36 +00002202 DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
Scott Michel97872d32008-02-23 18:41:37 +00002203
Scott Michel4d07fb72008-12-30 23:28:25 +00002204 // Use a shuffle to zero extend the i32 to i64 directly:
Scott Michel2ef773a2009-01-06 03:36:14 +00002205 SDValue shufMask;
Scott Michelf2df6cb2008-11-24 18:20:46 +00002206
Scott Michel2ef773a2009-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 Michel97872d32008-02-23 18:41:37 +00002243 }
2244
Scott Michel67224b22008-06-02 22:18:03 +00002245 case ISD::ADD: {
2246 // Turn operands into vectors to satisfy type checking (shufb works on
2247 // vectors)
Dan Gohman8181bd12008-07-27 21:46:04 +00002248 SDValue Op0 =
Scott Michel06eabde2008-12-27 04:51:36 +00002249 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman8181bd12008-07-27 21:46:04 +00002250 SDValue Op1 =
Scott Michel06eabde2008-12-27 04:51:36 +00002251 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman8181bd12008-07-27 21:46:04 +00002252 SmallVector<SDValue, 16> ShufBytes;
Scott Michel67224b22008-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 Gohman8181bd12008-07-27 21:46:04 +00002261 SDValue CarryGen =
Scott Michel67224b22008-06-02 22:18:03 +00002262 DAG.getNode(SPUISD::CARRY_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman8181bd12008-07-27 21:46:04 +00002263 SDValue ShiftedCarry =
Scott Michel67224b22008-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 Michelc630c412008-11-24 17:11:17 +00002269 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Michel67224b22008-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 Gohman8181bd12008-07-27 21:46:04 +00002277 SDValue Op0 =
Scott Michel06eabde2008-12-27 04:51:36 +00002278 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman8181bd12008-07-27 21:46:04 +00002279 SDValue Op1 =
Scott Michel06eabde2008-12-27 04:51:36 +00002280 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman8181bd12008-07-27 21:46:04 +00002281 SmallVector<SDValue, 16> ShufBytes;
Scott Michel67224b22008-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 Gohman8181bd12008-07-27 21:46:04 +00002290 SDValue BorrowGen =
Scott Michel67224b22008-06-02 22:18:03 +00002291 DAG.getNode(SPUISD::BORROW_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman8181bd12008-07-27 21:46:04 +00002292 SDValue ShiftedBorrow =
Scott Michel67224b22008-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 Michelc630c412008-11-24 17:11:17 +00002298 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Michel67224b22008-06-02 22:18:03 +00002299 DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64,
2300 Op0, Op1, ShiftedBorrow));
2301 }
Scott Michel97872d32008-02-23 18:41:37 +00002302 }
2303
Dan Gohman8181bd12008-07-27 21:46:04 +00002304 return SDValue();
Scott Michel97872d32008-02-23 18:41:37 +00002305}
2306
Scott Michel8efdca42007-12-04 22:23:35 +00002307//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002308static SDValue
2309LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2310 SDValue ConstVec;
2311 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002312 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002313
2314 ConstVec = Op.getOperand(0);
2315 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002316 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2317 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002318 ConstVec = ConstVec.getOperand(0);
2319 } else {
2320 ConstVec = Op.getOperand(1);
2321 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002322 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002323 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002324 }
2325 }
2326 }
2327
Gabor Greif1c80d112008-08-28 21:40:38 +00002328 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00002334 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002335 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00002336 VT.getVectorElementType().getSizeInBits(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002337 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002338 SDValue tcVec[16];
2339 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +00002344 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002345
Gabor Greif1c80d112008-08-28 21:40:38 +00002346 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002347 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002348 }
2349 }
Nate Begeman7569e762008-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 Michel8efdca42007-12-04 22:23:35 +00002353}
2354
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002361static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002362 MVT VT = Op.getValueType();
2363 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +00002364
Duncan Sands92c43912008-06-06 12:08:01 +00002365 switch (VT.getSimpleVT()) {
2366 default:
2367 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002368 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002369 SDValue N = Op.getOperand(0);
2370 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002371
Scott Michel06eabde2008-12-27 04:51:36 +00002372 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002373 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +00002380 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002381
Chris Lattner1b989192007-12-31 04:13:23 +00002382 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002383
Dan Gohman8181bd12008-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 Sands7aef60d2008-10-30 19:24:28 +00002387 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002388
Scott Michel06eabde2008-12-27 04:51:36 +00002389 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002390 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002394 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002395 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002396
Dan Gohman8181bd12008-07-27 21:46:04 +00002397 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002398 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2399
Dan Gohman8181bd12008-07-27 21:46:04 +00002400 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002401
2402 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-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 Michel8efdca42007-12-04 22:23:35 +00002408 }
2409
2410 case MVT::i32: {
2411 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002412 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002413
Chris Lattner1b989192007-12-31 04:13:23 +00002414 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2415 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002416
Dan Gohman8181bd12008-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 Michel8efdca42007-12-04 22:23:35 +00002422
Scott Michel06eabde2008-12-27 04:51:36 +00002423 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002424 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002428 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002429 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002430
Dan Gohman8181bd12008-07-27 21:46:04 +00002431 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002432 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2433
Dan Gohman8181bd12008-07-27 21:46:04 +00002434 SDValue Comp1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002435 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002436 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002437
Dan Gohman8181bd12008-07-27 21:46:04 +00002438 SDValue Sum1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002439 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002440 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002441
Dan Gohman8181bd12008-07-27 21:46:04 +00002442 SDValue Sum1_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002443 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2444
Dan Gohman8181bd12008-07-27 21:46:04 +00002445 SDValue Comp2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002446 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002447 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2448 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002449 SDValue Sum2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002450 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002451 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002460 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002461}
2462
Scott Michel56a125e2008-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 Michel06eabde2008-12-27 04:51:36 +00002475static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2476 const TargetLowering &TLI) {
Scott Michel56a125e2008-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 Michel06eabde2008-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 Michel56a125e2008-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 Sands4a361272009-01-01 15:52:00 +00002495 SDValue compare = DAG.getNode(ISD::SETCC,
2496 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002497 lhs, rhs, condition);
2498 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002499}
2500
Scott Michelec8c82e2008-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 Michel06eabde2008-12-27 04:51:36 +00002512 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002513 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-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 Michelec8c82e2008-12-02 19:53:53 +00002531 }
2532
Scott Michel06eabde2008-12-27 04:51:36 +00002533 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002534}
2535
Scott Michel56a125e2008-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 Gohman8181bd12008-07-27 21:46:04 +00002541SDValue
2542SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002543{
Scott Michel97872d32008-02-23 18:41:37 +00002544 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002545 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002546
2547 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002548 default: {
2549 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002550 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002551 cerr << "*Op.getNode():\n";
2552 Op.getNode()->dump();
Scott Michel8efdca42007-12-04 22:23:35 +00002553 abort();
2554 }
2555 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002556 case ISD::EXTLOAD:
Scott Michel8efdca42007-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 Michel394e26d2008-01-17 20:38:41 +00002573 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002574 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002575 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002576 case ISD::RET:
2577 return LowerRET(Op, DAG, getTargetMachine());
2578
Scott Michel97872d32008-02-23 18:41:37 +00002579
Scott Michel97872d32008-02-23 18:41:37 +00002580 case ISD::ZERO_EXTEND:
Scott Michel97872d32008-02-23 18:41:37 +00002581 case ISD::ANY_EXTEND:
Scott Michel4d07fb72008-12-30 23:28:25 +00002582 return LowerI64Math(Op, DAG, Opc);
2583
2584 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002585 case ISD::ADD:
Scott Michel8efdca42007-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 Michel67224b22008-06-02 22:18:03 +00002591 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002592 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002593 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002594 else if (VT == MVT::i64)
2595 return LowerI64Math(Op, DAG, Opc);
2596 break;
Scott Michel67224b22008-06-02 22:18:03 +00002597 }
Scott Michel8efdca42007-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 Michel4d07fb72008-12-30 23:28:25 +00002619 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002620 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002621
Scott Michel8efdca42007-12-04 22:23:35 +00002622 case ISD::CTPOP:
2623 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002624
2625 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002626 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002627
2628 case ISD::TRUNCATE:
2629 return LowerTRUNCATE(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002630 }
2631
Dan Gohman8181bd12008-07-27 21:46:04 +00002632 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002633}
2634
Duncan Sands7d9834b2008-12-01 11:39:25 +00002635void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2636 SmallVectorImpl<SDValue>&Results,
2637 SelectionDAG &DAG)
Scott Michel6e2d68b2008-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 Michel6e2d68b2008-11-10 23:43:06 +00002656}
2657
Scott Michel8efdca42007-12-04 22:23:35 +00002658//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002659// Target Optimization Hooks
2660//===----------------------------------------------------------------------===//
2661
Dan Gohman8181bd12008-07-27 21:46:04 +00002662SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002663SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2664{
2665#if 0
2666 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002667#endif
2668 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002669 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-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 Michel06eabde2008-12-27 04:51:36 +00002672 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002673 SDValue Result; // Initially, empty result
Scott Michel8efdca42007-12-04 22:23:35 +00002674
2675 switch (N->getOpcode()) {
2676 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002677 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002678 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002679
Scott Michel06eabde2008-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 Michelae5cbf52008-12-29 03:23:36 +00002684
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002697
Scott Michel8c2746e2008-12-04 17:16:59 +00002698#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002699 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002700 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002701 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2702 << "With: (SPUindirect <arg>, <arg>)\n";
2703 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002704#endif
2705
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002713
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002723
Scott Michel06eabde2008-12-27 04:51:36 +00002724 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2725 IndirectArg, combinedValue);
2726 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002727 }
2728 }
Scott Michel97872d32008-02-23 18:41:37 +00002729 break;
2730 }
2731 case ISD::SIGN_EXTEND:
2732 case ISD::ZERO_EXTEND:
2733 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002734 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002735 // (any_extend (SPUextract_elt0 <arg>)) ->
2736 // (SPUextract_elt0 <arg>)
2737 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002738#if !defined(NDEBUG)
2739 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002740 cerr << "\nReplace: ";
2741 N->dump(&DAG);
2742 cerr << "\nWith: ";
2743 Op0.getNode()->dump(&DAG);
2744 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002745 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002746#endif
Scott Michel97872d32008-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 Gohmanfaeb4a32008-09-12 16:56:44 +00002755 if (CN->getZExtValue() == 0) {
Scott Michel97872d32008-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 Greif1c80d112008-08-28 21:40:38 +00002762 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002763 DEBUG(cerr << "\n");
2764
2765 return Op0;
2766 }
Scott Michel06eabde2008-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 Michel97872d32008-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 Michel06eabde2008-12-27 04:51:36 +00002794 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002795 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002796
Scott Michel06eabde2008-12-27 04:51:36 +00002797 // Kill degenerate vector shifts:
2798 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2799 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002800 Result = Op0;
2801 }
2802 }
2803 break;
2804 }
Scott Michel06eabde2008-12-27 04:51:36 +00002805 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-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 Michelae5cbf52008-12-29 03:23:36 +00002812 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002813 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002814 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002815 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002816 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002817 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002818 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002819 Result = Op000;
2820 }
2821 }
2822 break;
2823 }
Scott Michelc630c412008-11-24 17:11:17 +00002824 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002825 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002826 // <arg>
2827 Result = Op0.getOperand(0);
2828 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002829 }
Scott Michel97872d32008-02-23 18:41:37 +00002830 }
2831 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002832 }
2833 }
Scott Michel394e26d2008-01-17 20:38:41 +00002834 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002835#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002836 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002837 DEBUG(cerr << "\nReplace.SPU: ");
2838 DEBUG(N->dump(&DAG));
2839 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002840 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002841 DEBUG(cerr << "\n");
2842 }
2843#endif
2844
2845 return Result;
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002854SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002865 }
Scott Michel8efdca42007-12-04 22:23:35 +00002866 }
2867 return TargetLowering::getConstraintType(ConstraintLetter);
2868}
2869
Scott Michel4ec722e2008-07-16 17:17:29 +00002870std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002871SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002872 MVT VT) const
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002888 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00002889 return std::make_pair(0U, SPU::GPRCRegisterClass);
2890 }
2891 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002892
Scott Michel8efdca42007-12-04 22:23:35 +00002893 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2894}
2895
Scott Michel97872d32008-02-23 18:41:37 +00002896//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002897void
Dan Gohman8181bd12008-07-27 21:46:04 +00002898SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002899 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00002900 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00002901 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002902 const SelectionDAG &DAG,
2903 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00002904#if 0
Scott Michel97872d32008-02-23 18:41:37 +00002905 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michelbc5fbc12008-04-30 00:30:08 +00002906#endif
Scott Michel97872d32008-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 Michel56a125e2008-11-22 23:50:42 +00002916 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00002917 case CNTB:
2918#endif
2919
Scott Michel06eabde2008-12-27 04:51:36 +00002920 case SPUISD::PREFSLOT2VEC: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002921 SDValue Op0 = Op.getOperand(0);
Duncan Sands92c43912008-06-06 12:08:01 +00002922 MVT Op0VT = Op0.getValueType();
2923 unsigned Op0VTBits = Op0VT.getSizeInBits();
2924 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002925 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2926 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002927 break;
2928 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002929
Scott Michel97872d32008-02-23 18:41:37 +00002930 case SPUISD::LDRESULT:
Scott Michel6ccefab2008-12-04 03:02:42 +00002931 case SPUISD::VEC2PREFSLOT: {
Duncan Sands92c43912008-06-06 12:08:01 +00002932 MVT OpVT = Op.getValueType();
2933 unsigned OpVTBits = OpVT.getSizeInBits();
2934 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002935 KnownZero |= APInt(OpVTBits, ~InMask, false);
2936 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002937 break;
2938 }
2939
2940#if 0
Scott Michelbc5fbc12008-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 Michelbc5fbc12008-04-30 00:30:08 +00002948 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00002949 case SPUISD::SELECT_MASK:
2950 case SPUISD::SELB:
Scott Michel97872d32008-02-23 18:41:37 +00002951#endif
2952 }
Scott Michel8efdca42007-12-04 22:23:35 +00002953}
Scott Michel4d07fb72008-12-30 23:28:25 +00002954
Scott Michel06eabde2008-12-27 04:51:36 +00002955unsigned
2956SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2957 unsigned Depth) const {
2958 switch (Op.getOpcode()) {
2959 default:
2960 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00002961
Scott Michel06eabde2008-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 Michelae5cbf52008-12-29 03:23:36 +00002972
Scott Michelbc5fbc12008-04-30 00:30:08 +00002973// LowerAsmOperandForConstraint
2974void
Dan Gohman8181bd12008-07-27 21:46:04 +00002975SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002976 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00002977 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00002978 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002979 SelectionDAG &DAG) const {
2980 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00002981 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2982 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00002983}
2984
Scott Michel8efdca42007-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 Greife9f7f582008-08-31 15:37:04 +00002987bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2988 const Type *Ty) const {
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002994 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00002995}
Dan Gohman36322c72008-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}