blob: 7e63a87288349d4c214296de2fe21477a34b31e3 [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
Duncan Sands92c43912008-06-06 12:08:01 +0000330 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
331 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
332 MVT VT = (MVT::SimpleValueType)i;
Scott Michel8efdca42007-12-04 22:23:35 +0000333
Duncan Sands92c43912008-06-06 12:08:01 +0000334 // add/sub are legal for all supported vector VT's.
335 setOperationAction(ISD::ADD , VT, Legal);
336 setOperationAction(ISD::SUB , VT, Legal);
337 // mul has to be custom lowered.
Scott Michel4d07fb72008-12-30 23:28:25 +0000338 // TODO: v2i64 vector multiply
339 setOperationAction(ISD::MUL , VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000340
341 setOperationAction(ISD::AND , VT, Legal);
342 setOperationAction(ISD::OR , VT, Legal);
343 setOperationAction(ISD::XOR , VT, Legal);
344 setOperationAction(ISD::LOAD , VT, Legal);
345 setOperationAction(ISD::SELECT, VT, Legal);
346 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000347
Scott Michel8efdca42007-12-04 22:23:35 +0000348 // These operations need to be expanded:
Duncan Sands92c43912008-06-06 12:08:01 +0000349 setOperationAction(ISD::SDIV, VT, Expand);
350 setOperationAction(ISD::SREM, VT, Expand);
351 setOperationAction(ISD::UDIV, VT, Expand);
352 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000353
354 // Custom lower build_vector, constant pool spills, insert and
355 // extract vector elements:
Duncan Sands92c43912008-06-06 12:08:01 +0000356 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
357 setOperationAction(ISD::ConstantPool, VT, Custom);
358 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
359 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
360 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
361 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000362 }
363
Scott Michel8efdca42007-12-04 22:23:35 +0000364 setOperationAction(ISD::AND, MVT::v16i8, Custom);
365 setOperationAction(ISD::OR, MVT::v16i8, Custom);
366 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
367 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000368
Scott Michel4d07fb72008-12-30 23:28:25 +0000369 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000370
Scott Michel8efdca42007-12-04 22:23:35 +0000371 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000372 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000373
Scott Michel8efdca42007-12-04 22:23:35 +0000374 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000375
Scott Michel8efdca42007-12-04 22:23:35 +0000376 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000377 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000378 setTargetDAGCombine(ISD::ZERO_EXTEND);
379 setTargetDAGCombine(ISD::SIGN_EXTEND);
380 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000381
Scott Michel8efdca42007-12-04 22:23:35 +0000382 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000383
Scott Michel2c261072008-12-09 03:37:19 +0000384 // Set pre-RA register scheduler default to BURR, which produces slightly
385 // better code than the default (could also be TDRR, but TargetLowering.h
386 // needs a mod to support that model):
387 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel8efdca42007-12-04 22:23:35 +0000388}
389
390const char *
391SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
392{
393 if (node_names.empty()) {
394 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
395 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
396 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
397 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Micheldbac4cf2008-01-11 02:53:15 +0000398 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000399 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-12-04 22:23:35 +0000400 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
401 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
402 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel56a125e2008-11-22 23:50:42 +0000403 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000404 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000405 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000406 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-02-23 18:41:37 +0000407 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
408 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel8efdca42007-12-04 22:23:35 +0000409 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
410 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
411 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
412 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
413 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michel67224b22008-06-02 22:18:03 +0000414 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000415 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel67224b22008-06-02 22:18:03 +0000416 node_names[(unsigned) SPUISD::ADD_EXTENDED] = "SPUISD::ADD_EXTENDED";
417 node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
418 node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
419 node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
Scott Michel8efdca42007-12-04 22:23:35 +0000420 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
421 }
422
423 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
424
425 return ((i != node_names.end()) ? i->second : 0);
426}
427
Scott Michel06eabde2008-12-27 04:51:36 +0000428//===----------------------------------------------------------------------===//
429// Return the Cell SPU's SETCC result type
430//===----------------------------------------------------------------------===//
431
Duncan Sands4a361272009-01-01 15:52:00 +0000432MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-12-27 04:51:36 +0000433 // i16 and i32 are valid SETCC result types
434 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel53ab7792008-03-10 16:58:52 +0000435}
436
Scott Michel8efdca42007-12-04 22:23:35 +0000437//===----------------------------------------------------------------------===//
438// Calling convention code:
439//===----------------------------------------------------------------------===//
440
441#include "SPUGenCallingConv.inc"
442
443//===----------------------------------------------------------------------===//
444// LowerOperation implementation
445//===----------------------------------------------------------------------===//
446
447/// Custom lower loads for CellSPU
448/*!
449 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
450 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel6ccefab2008-12-04 03:02:42 +0000451
452 For extending loads, we also want to ensure that the following sequence is
453 emitted, e.g. for MVT::f32 extending load to MVT::f64:
454
455\verbatim
Scott Michelae5cbf52008-12-29 03:23:36 +0000456%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000457%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000458%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000459%4 f32 = vec2perfslot %3
460%5 f64 = fp_extend %4
461\endverbatim
462*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000463static SDValue
464LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000465 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000466 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000467 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000468 MVT InVT = LN->getMemoryVT();
469 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000470 ISD::LoadExtType ExtType = LN->getExtensionType();
471 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000472 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000473
Scott Michel8efdca42007-12-04 22:23:35 +0000474 switch (LN->getAddressingMode()) {
475 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000476 SDValue result;
477 SDValue basePtr = LN->getBasePtr();
478 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000479
Scott Michel06eabde2008-12-27 04:51:36 +0000480 if (alignment == 16) {
481 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000482
Scott Michel06eabde2008-12-27 04:51:36 +0000483 // Special cases for a known aligned load to simplify the base pointer
484 // and the rotation amount:
485 if (basePtr.getOpcode() == ISD::ADD
486 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
487 // Known offset into basePtr
488 int64_t offset = CN->getSExtValue();
489 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000490
Scott Michel06eabde2008-12-27 04:51:36 +0000491 if (rotamt < 0)
492 rotamt += 16;
493
494 rotate = DAG.getConstant(rotamt, MVT::i16);
495
496 // Simplify the base pointer for this case:
497 basePtr = basePtr.getOperand(0);
498 if ((offset & ~0xf) > 0) {
499 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
500 basePtr,
501 DAG.getConstant((offset & ~0xf), PtrVT));
502 }
503 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
504 || (basePtr.getOpcode() == SPUISD::IndirectAddr
505 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
506 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
507 // Plain aligned a-form address: rotate into preferred slot
508 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
509 int64_t rotamt = -vtm->prefslot_byte;
510 if (rotamt < 0)
511 rotamt += 16;
512 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000513 } else {
Scott Michel06eabde2008-12-27 04:51:36 +0000514 // Offset the rotate amount by the basePtr and the preferred slot
515 // byte offset
516 int64_t rotamt = -vtm->prefslot_byte;
517 if (rotamt < 0)
518 rotamt += 16;
519 rotate = DAG.getNode(ISD::ADD, PtrVT,
520 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000521 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000522 }
Scott Michel06eabde2008-12-27 04:51:36 +0000523 } else {
524 // Unaligned load: must be more pessimistic about addressing modes:
525 if (basePtr.getOpcode() == ISD::ADD) {
526 MachineFunction &MF = DAG.getMachineFunction();
527 MachineRegisterInfo &RegInfo = MF.getRegInfo();
528 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
529 SDValue Flag;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000530
Scott Michel06eabde2008-12-27 04:51:36 +0000531 SDValue Op0 = basePtr.getOperand(0);
532 SDValue Op1 = basePtr.getOperand(1);
533
534 if (isa<ConstantSDNode>(Op1)) {
535 // Convert the (add <ptr>, <const>) to an indirect address contained
536 // in a register. Note that this is done because we need to avoid
537 // creating a 0(reg) d-form address due to the SPU's block loads.
538 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
539 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
540 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
541 } else {
542 // Convert the (add <arg1>, <arg2>) to an indirect address, which
543 // will likely be lowered as a reg(reg) x-form address.
544 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
545 }
546 } else {
547 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
548 basePtr,
549 DAG.getConstant(0, PtrVT));
550 }
551
552 // Offset the rotate amount by the basePtr and the preferred slot
553 // byte offset
554 rotate = DAG.getNode(ISD::ADD, PtrVT,
555 basePtr,
556 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +0000557 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000558
Scott Michel06eabde2008-12-27 04:51:36 +0000559 // Re-emit as a v16i8 vector load
560 result = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
561 LN->getSrcValue(), LN->getSrcValueOffset(),
562 LN->isVolatile(), 16);
563
564 // Update the chain
565 the_chain = result.getValue(1);
566
567 // Rotate into the preferred slot:
568 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8,
569 result.getValue(0), rotate);
570
Scott Michel6ccefab2008-12-04 03:02:42 +0000571 // Convert the loaded v16i8 vector to the appropriate vector type
572 // specified by the operand:
573 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
574 result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
575 DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
Scott Michel4ec722e2008-07-16 17:17:29 +0000576
Scott Michel6ccefab2008-12-04 03:02:42 +0000577 // Handle extending loads by extending the scalar result:
578 if (ExtType == ISD::SEXTLOAD) {
579 result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result);
580 } else if (ExtType == ISD::ZEXTLOAD) {
581 result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result);
582 } else if (ExtType == ISD::EXTLOAD) {
583 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000584
Scott Michel6ccefab2008-12-04 03:02:42 +0000585 if (OutVT.isFloatingPoint())
586 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000587
Scott Michel6ccefab2008-12-04 03:02:42 +0000588 result = DAG.getNode(NewOpc, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000589 }
590
Scott Michel6ccefab2008-12-04 03:02:42 +0000591 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000592 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000593 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000594 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000595 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000596
Scott Michel394e26d2008-01-17 20:38:41 +0000597 result = DAG.getNode(SPUISD::LDRESULT, retvts,
598 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000599 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000600 }
601 case ISD::PRE_INC:
602 case ISD::PRE_DEC:
603 case ISD::POST_INC:
604 case ISD::POST_DEC:
605 case ISD::LAST_INDEXED_MODE:
606 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
607 "UNINDEXED\n";
608 cerr << (unsigned) LN->getAddressingMode() << "\n";
609 abort();
610 /*NOTREACHED*/
611 }
612
Dan Gohman8181bd12008-07-27 21:46:04 +0000613 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000614}
615
616/// Custom lower stores for CellSPU
617/*!
618 All CellSPU stores are aligned to 16-byte boundaries, so for elements
619 within a 16-byte block, we have to generate a shuffle to insert the
620 requested element into its place, then store the resulting block.
621 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000622static SDValue
623LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000624 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000625 SDValue Value = SN->getValue();
Duncan Sands92c43912008-06-06 12:08:01 +0000626 MVT VT = Value.getValueType();
627 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
628 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000629 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000630
631 switch (SN->getAddressingMode()) {
632 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000633 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000634 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
635 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000636
Scott Michel06eabde2008-12-27 04:51:36 +0000637 SDValue alignLoadVec;
638 SDValue basePtr = SN->getBasePtr();
639 SDValue the_chain = SN->getChain();
640 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000641
Scott Michel06eabde2008-12-27 04:51:36 +0000642 if (alignment == 16) {
643 ConstantSDNode *CN;
644
645 // Special cases for a known aligned load to simplify the base pointer
646 // and insertion byte:
647 if (basePtr.getOpcode() == ISD::ADD
648 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
649 // Known offset into basePtr
650 int64_t offset = CN->getSExtValue();
651
652 // Simplify the base pointer for this case:
653 basePtr = basePtr.getOperand(0);
654 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
655 basePtr,
656 DAG.getConstant((offset & 0xf), PtrVT));
657
658 if ((offset & ~0xf) > 0) {
659 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
660 basePtr,
661 DAG.getConstant((offset & ~0xf), PtrVT));
662 }
663 } else {
664 // Otherwise, assume it's at byte 0 of basePtr
665 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
666 basePtr,
667 DAG.getConstant(0, PtrVT));
668 }
669 } else {
670 // Unaligned load: must be more pessimistic about addressing modes:
671 if (basePtr.getOpcode() == ISD::ADD) {
672 MachineFunction &MF = DAG.getMachineFunction();
673 MachineRegisterInfo &RegInfo = MF.getRegInfo();
674 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
675 SDValue Flag;
676
677 SDValue Op0 = basePtr.getOperand(0);
678 SDValue Op1 = basePtr.getOperand(1);
679
680 if (isa<ConstantSDNode>(Op1)) {
681 // Convert the (add <ptr>, <const>) to an indirect address contained
682 // in a register. Note that this is done because we need to avoid
683 // creating a 0(reg) d-form address due to the SPU's block loads.
684 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
685 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
686 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
687 } else {
688 // Convert the (add <arg1>, <arg2>) to an indirect address, which
689 // will likely be lowered as a reg(reg) x-form address.
690 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
691 }
692 } else {
693 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
694 basePtr,
695 DAG.getConstant(0, PtrVT));
696 }
697
698 // Insertion point is solely determined by basePtr's contents
699 insertEltOffs = DAG.getNode(ISD::ADD, PtrVT,
700 basePtr,
701 DAG.getConstant(0, PtrVT));
702 }
703
704 // Re-emit as a v16i8 vector load
705 alignLoadVec = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
706 SN->getSrcValue(), SN->getSrcValueOffset(),
707 SN->isVolatile(), 16);
708
709 // Update the chain
710 the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000711
Scott Micheldbac4cf2008-01-11 02:53:15 +0000712 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000713 SDValue theValue = SN->getValue();
714 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000715
716 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000717 && (theValue.getOpcode() == ISD::AssertZext
718 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000719 // Drill down and get the value for zero- and sign-extended
720 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000721 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000722 }
723
Scott Micheldbac4cf2008-01-11 02:53:15 +0000724 // If the base pointer is already a D-form address, then just create
725 // a new D-form address with a slot offset and the orignal base pointer.
726 // Otherwise generate a D-form address with the slot offset relative
727 // to the stack pointer, which is always aligned.
Scott Michel06eabde2008-12-27 04:51:36 +0000728#if !defined(NDEBUG)
729 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
730 cerr << "CellSPU LowerSTORE: basePtr = ";
731 basePtr.getNode()->dump(&DAG);
732 cerr << "\n";
733 }
734#endif
Scott Micheldbac4cf2008-01-11 02:53:15 +0000735
Scott Michelf65c8f02008-11-19 15:24:16 +0000736 SDValue insertEltOp =
Scott Michel06eabde2008-12-27 04:51:36 +0000737 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000738 SDValue vectorizeOp =
739 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000740
Scott Michel0718cd82008-12-01 17:56:02 +0000741 result = DAG.getNode(SPUISD::SHUFB, vecVT,
742 vectorizeOp, alignLoadVec,
743 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000744
Scott Micheldbac4cf2008-01-11 02:53:15 +0000745 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000746 LN->getSrcValue(), LN->getSrcValueOffset(),
747 LN->isVolatile(), LN->getAlignment());
748
Scott Michel8c2746e2008-12-04 17:16:59 +0000749#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-11-19 15:24:16 +0000750 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
751 const SDValue &currentRoot = DAG.getRoot();
752
753 DAG.setRoot(result);
754 cerr << "------- CellSPU:LowerStore result:\n";
755 DAG.dump();
756 cerr << "-------\n";
757 DAG.setRoot(currentRoot);
758 }
759#endif
Scott Michelec8c82e2008-12-02 19:53:53 +0000760
Scott Michel8efdca42007-12-04 22:23:35 +0000761 return result;
762 /*UNREACHED*/
763 }
764 case ISD::PRE_INC:
765 case ISD::PRE_DEC:
766 case ISD::POST_INC:
767 case ISD::POST_DEC:
768 case ISD::LAST_INDEXED_MODE:
769 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
770 "UNINDEXED\n";
771 cerr << (unsigned) SN->getAddressingMode() << "\n";
772 abort();
773 /*NOTREACHED*/
774 }
775
Dan Gohman8181bd12008-07-27 21:46:04 +0000776 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000777}
778
779/// Generate the address of a constant pool entry.
Dan Gohman8181bd12008-07-27 21:46:04 +0000780static SDValue
781LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000782 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000783 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
784 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000785 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
786 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000787 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000788
789 if (TM.getRelocationModel() == Reloc::Static) {
790 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000791 // Just return the SDValue with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000792 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000793 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000794 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
795 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000796 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000797 }
798 }
799
800 assert(0 &&
Gabor Greife9f7f582008-08-31 15:37:04 +0000801 "LowerConstantPool: Relocation model other than static"
802 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000803 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000804}
805
Dan Gohman8181bd12008-07-27 21:46:04 +0000806static SDValue
807LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000808 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000809 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000810 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
811 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000812 const TargetMachine &TM = DAG.getTarget();
813
814 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000815 if (!ST->usingLargeMem()) {
816 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
817 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000818 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
819 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000820 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
821 }
Scott Michel8efdca42007-12-04 22:23:35 +0000822 }
823
824 assert(0 &&
825 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000826 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000827}
828
Dan Gohman8181bd12008-07-27 21:46:04 +0000829static SDValue
830LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000831 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000832 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
833 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000834 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000835 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000836 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel4ec722e2008-07-16 17:17:29 +0000837
Scott Michel8efdca42007-12-04 22:23:35 +0000838 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000839 if (!ST->usingLargeMem()) {
840 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
841 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000842 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
843 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
Scott Michelf9f42e62008-01-29 02:16:57 +0000844 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
845 }
Scott Michel8efdca42007-12-04 22:23:35 +0000846 } else {
847 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000848 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000849 abort();
850 /*NOTREACHED*/
851 }
852
Dan Gohman8181bd12008-07-27 21:46:04 +0000853 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000854}
855
856//! Custom lower i64 integer constants
857/*!
858 This code inserts all of the necessary juggling that needs to occur to load
859 a 64-bit constant into a register.
860 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000861static SDValue
862LowerConstant(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000863 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000864
865 if (VT == MVT::i64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000866 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
867 SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michelc630c412008-11-24 17:11:17 +0000868 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000869 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +0000870 } else {
871 cerr << "LowerConstant: unhandled constant type "
Duncan Sands92c43912008-06-06 12:08:01 +0000872 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +0000873 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000874 abort();
875 /*NOTREACHED*/
876 }
877
Dan Gohman8181bd12008-07-27 21:46:04 +0000878 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000879}
880
Nate Begeman78125042008-02-14 18:43:04 +0000881//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000882static SDValue
883LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000884 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000885
Nate Begeman78125042008-02-14 18:43:04 +0000886 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000887 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
888
889 assert((FP != 0) &&
890 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000891
Scott Michel11e88bb2007-12-19 20:15:47 +0000892 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-12-01 17:56:02 +0000893 SDValue T = DAG.getConstant(dbits, MVT::i64);
894 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T);
895 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
896 DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec));
Scott Michel8efdca42007-12-04 22:23:35 +0000897 }
898
Dan Gohman8181bd12008-07-27 21:46:04 +0000899 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000900}
901
Dan Gohman8181bd12008-07-27 21:46:04 +0000902static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000903LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000904{
905 MachineFunction &MF = DAG.getMachineFunction();
906 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000907 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000908 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000909 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000910 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel8efdca42007-12-04 22:23:35 +0000911
912 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
913 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000914
Scott Michel8efdca42007-12-04 22:23:35 +0000915 unsigned ArgOffset = SPUFrameInfo::minStackSize();
916 unsigned ArgRegIdx = 0;
917 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000918
Duncan Sands92c43912008-06-06 12:08:01 +0000919 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000920
Scott Michel8efdca42007-12-04 22:23:35 +0000921 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000922 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
923 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000924 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
925 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000926 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000927
Scott Michela313fb02008-10-30 01:51:48 +0000928 if (ArgRegIdx < NumArgRegs) {
929 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000930
Scott Michela313fb02008-10-30 01:51:48 +0000931 switch (ObjectVT.getSimpleVT()) {
932 default: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000933 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
934 << ObjectVT.getMVTString()
935 << "\n";
936 abort();
Scott Michela313fb02008-10-30 01:51:48 +0000937 }
938 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000939 ArgRegClass = &SPU::R8CRegClass;
940 break;
Scott Michela313fb02008-10-30 01:51:48 +0000941 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +0000942 ArgRegClass = &SPU::R16CRegClass;
943 break;
Scott Michela313fb02008-10-30 01:51:48 +0000944 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000945 ArgRegClass = &SPU::R32CRegClass;
946 break;
Scott Michela313fb02008-10-30 01:51:48 +0000947 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000948 ArgRegClass = &SPU::R64CRegClass;
949 break;
Scott Michel2ef773a2009-01-06 03:36:14 +0000950 case MVT::i128:
951 ArgRegClass = &SPU::GPRCRegClass;
952 break;
Scott Michela313fb02008-10-30 01:51:48 +0000953 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000954 ArgRegClass = &SPU::R32FPRegClass;
955 break;
Scott Michela313fb02008-10-30 01:51:48 +0000956 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000957 ArgRegClass = &SPU::R64FPRegClass;
958 break;
Scott Michela313fb02008-10-30 01:51:48 +0000959 case MVT::v2f64:
960 case MVT::v4f32:
961 case MVT::v2i64:
962 case MVT::v4i32:
963 case MVT::v8i16:
964 case MVT::v16i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000965 ArgRegClass = &SPU::VECREGRegClass;
966 break;
Scott Michela313fb02008-10-30 01:51:48 +0000967 }
968
969 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
970 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
971 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
972 ++ArgRegIdx;
973 } else {
974 // We need to load the argument to a virtual register if we determined
975 // above that we ran out of physical registers of the appropriate type
976 // or we're forced to do vararg
Chris Lattner60069452008-02-13 07:35:30 +0000977 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +0000978 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner60069452008-02-13 07:35:30 +0000979 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +0000980 ArgOffset += StackSlotSize;
981 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000982
Scott Michel8efdca42007-12-04 22:23:35 +0000983 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +0000984 // Update the chain
985 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000986 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000987
Scott Michela313fb02008-10-30 01:51:48 +0000988 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +0000989 if (isVarArg) {
Scott Michela313fb02008-10-30 01:51:48 +0000990 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
991 // We will spill (79-3)+1 registers to the stack
992 SmallVector<SDValue, 79-3+1> MemOps;
993
994 // Create the frame slot
995
Scott Michel8efdca42007-12-04 22:23:35 +0000996 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-10-30 01:51:48 +0000997 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
998 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
999 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
1000 SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
1001 Root = Store.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001002 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001003
1004 // Increment address by stack slot size for the next stored argument
1005 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001006 }
1007 if (!MemOps.empty())
Scott Michela313fb02008-10-30 01:51:48 +00001008 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001009 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001010
Scott Michel8efdca42007-12-04 22:23:35 +00001011 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001012
Scott Michel8efdca42007-12-04 22:23:35 +00001013 // Return the new list of results.
Duncan Sands42d7bb82008-12-01 11:41:29 +00001014 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1015 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001016}
1017
1018/// isLSAAddress - Return the immediate to use if the specified
1019/// value is representable as a LSA address.
Dan Gohman8181bd12008-07-27 21:46:04 +00001020static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001021 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001022 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001023
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001024 int Addr = C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001025 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1026 (Addr << 14 >> 14) != Addr)
1027 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel4ec722e2008-07-16 17:17:29 +00001028
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001029 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001030}
1031
1032static
Dan Gohman8181bd12008-07-27 21:46:04 +00001033SDValue
1034LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001035 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1036 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001037 SDValue Callee = TheCall->getCallee();
1038 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-12-04 22:23:35 +00001039 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1040 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1041 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1042
1043 // Handy pointer type
Duncan Sands92c43912008-06-06 12:08:01 +00001044 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001045
Scott Michel8efdca42007-12-04 22:23:35 +00001046 // Accumulate how many bytes are to be pushed on the stack, including the
1047 // linkage area, and parameter passing area. According to the SPU ABI,
1048 // we minimally need space for [LR] and [SP]
1049 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel4ec722e2008-07-16 17:17:29 +00001050
Scott Michel8efdca42007-12-04 22:23:35 +00001051 // Set up a copy of the stack pointer for use loading and storing any
1052 // arguments that may not fit in the registers available for argument
1053 // passing.
Dan Gohman8181bd12008-07-27 21:46:04 +00001054 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001055
Scott Michel8efdca42007-12-04 22:23:35 +00001056 // Figure out which arguments are going to go in registers, and which in
1057 // memory.
1058 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1059 unsigned ArgRegIdx = 0;
1060
1061 // Keep track of registers passing arguments
Dan Gohman8181bd12008-07-27 21:46:04 +00001062 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001063 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001064 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001065
1066 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001067 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001068
Scott Michel8efdca42007-12-04 22:23:35 +00001069 // PtrOff will be used to store the current argument to the stack if a
1070 // register cannot be found for it.
Dan Gohman8181bd12008-07-27 21:46:04 +00001071 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel8efdca42007-12-04 22:23:35 +00001072 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1073
Duncan Sands92c43912008-06-06 12:08:01 +00001074 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001075 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001076 case MVT::i8:
1077 case MVT::i16:
Scott Michel8efdca42007-12-04 22:23:35 +00001078 case MVT::i32:
1079 case MVT::i64:
1080 case MVT::i128:
1081 if (ArgRegIdx != NumArgRegs) {
1082 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1083 } else {
1084 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001085 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001086 }
1087 break;
1088 case MVT::f32:
1089 case MVT::f64:
1090 if (ArgRegIdx != NumArgRegs) {
1091 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1092 } else {
1093 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001094 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001095 }
1096 break;
Scott Michele2641a12008-12-04 21:01:44 +00001097 case MVT::v2i64:
1098 case MVT::v2f64:
Scott Michel8efdca42007-12-04 22:23:35 +00001099 case MVT::v4f32:
1100 case MVT::v4i32:
1101 case MVT::v8i16:
1102 case MVT::v16i8:
1103 if (ArgRegIdx != NumArgRegs) {
1104 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1105 } else {
1106 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001107 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001108 }
1109 break;
1110 }
1111 }
1112
1113 // Update number of stack bytes actually used, insert a call sequence start
1114 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001115 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1116 true));
Scott Michel8efdca42007-12-04 22:23:35 +00001117
1118 if (!MemOpChains.empty()) {
1119 // Adjust the stack pointer for the stack arguments.
1120 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1121 &MemOpChains[0], MemOpChains.size());
1122 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001123
Scott Michel8efdca42007-12-04 22:23:35 +00001124 // Build a sequence of copy-to-reg nodes chained together with token chain
1125 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman8181bd12008-07-27 21:46:04 +00001126 SDValue InFlag;
Scott Michel8efdca42007-12-04 22:23:35 +00001127 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1128 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1129 InFlag);
1130 InFlag = Chain.getValue(1);
1131 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001132
Dan Gohman8181bd12008-07-27 21:46:04 +00001133 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001134 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001135
Bill Wendlingfef06052008-09-16 21:48:12 +00001136 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1137 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1138 // node so that legalize doesn't hack it.
Scott Michel5974f432008-11-11 03:06:06 +00001139 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001140 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001141 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001142 SDValue Zero = DAG.getConstant(0, PtrVT);
1143 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001144
Scott Micheldbac4cf2008-01-11 02:53:15 +00001145 if (!ST->usingLargeMem()) {
1146 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1147 // style calls, otherwise, external symbols are BRASL calls. This assumes
1148 // that declared/defined symbols are in the same compilation unit and can
1149 // be reached through PC-relative jumps.
1150 //
1151 // NOTE:
1152 // This may be an unsafe assumption for JIT and really large compilation
1153 // units.
1154 if (GV->isDeclaration()) {
1155 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1156 } else {
1157 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1158 }
Scott Michel8efdca42007-12-04 22:23:35 +00001159 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001160 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1161 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001162 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001163 }
Scott Michelae5cbf52008-12-29 03:23:36 +00001164 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1165 MVT CalleeVT = Callee.getValueType();
1166 SDValue Zero = DAG.getConstant(0, PtrVT);
1167 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1168 Callee.getValueType());
1169
1170 if (!ST->usingLargeMem()) {
1171 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, ExtSym, Zero);
1172 } else {
1173 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, ExtSym, Zero);
1174 }
1175 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001176 // If this is an absolute destination address that appears to be a legal
1177 // local store address, use the munged value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001178 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001179 }
Scott Michel8efdca42007-12-04 22:23:35 +00001180
1181 Ops.push_back(Chain);
1182 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001183
Scott Michel8efdca42007-12-04 22:23:35 +00001184 // Add argument registers to the end of the list so that they are known live
1185 // into the call.
1186 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel4ec722e2008-07-16 17:17:29 +00001187 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001188 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001189
Gabor Greif1c80d112008-08-28 21:40:38 +00001190 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001191 Ops.push_back(InFlag);
Duncan Sands698842f2008-07-02 17:40:58 +00001192 // Returns a chain and a flag for retval copy to use.
1193 Chain = DAG.getNode(CallOpc, DAG.getVTList(MVT::Other, MVT::Flag),
1194 &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001195 InFlag = Chain.getValue(1);
1196
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001197 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1198 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001199 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001200 InFlag = Chain.getValue(1);
1201
Dan Gohman8181bd12008-07-27 21:46:04 +00001202 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001203 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001204
Scott Michel8efdca42007-12-04 22:23:35 +00001205 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001206 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001207 default: assert(0 && "Unexpected ret value!");
1208 case MVT::Other: break;
1209 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001210 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001211 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1212 ResultVals[0] = Chain.getValue(0);
1213 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1214 Chain.getValue(2)).getValue(1);
1215 ResultVals[1] = Chain.getValue(0);
1216 NumResults = 2;
Scott Michel8efdca42007-12-04 22:23:35 +00001217 } else {
1218 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1219 ResultVals[0] = Chain.getValue(0);
1220 NumResults = 1;
1221 }
Scott Michel8efdca42007-12-04 22:23:35 +00001222 break;
1223 case MVT::i64:
1224 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1225 ResultVals[0] = Chain.getValue(0);
1226 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001227 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001228 case MVT::i128:
1229 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
1230 ResultVals[0] = Chain.getValue(0);
1231 NumResults = 1;
1232 break;
Scott Michel8efdca42007-12-04 22:23:35 +00001233 case MVT::f32:
1234 case MVT::f64:
Dan Gohman705e3f72008-09-13 01:54:27 +00001235 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001236 InFlag).getValue(1);
1237 ResultVals[0] = Chain.getValue(0);
1238 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001239 break;
1240 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001241 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001242 case MVT::v4f32:
1243 case MVT::v4i32:
1244 case MVT::v8i16:
1245 case MVT::v16i8:
Dan Gohman705e3f72008-09-13 01:54:27 +00001246 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001247 InFlag).getValue(1);
1248 ResultVals[0] = Chain.getValue(0);
1249 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001250 break;
1251 }
Duncan Sands698842f2008-07-02 17:40:58 +00001252
Scott Michel8efdca42007-12-04 22:23:35 +00001253 // If the function returns void, just return the chain.
1254 if (NumResults == 0)
1255 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001256
Scott Michel8efdca42007-12-04 22:23:35 +00001257 // Otherwise, merge everything together with a MERGE_VALUES node.
1258 ResultVals[NumResults++] = Chain;
Dan Gohman8181bd12008-07-27 21:46:04 +00001259 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif46bf5472008-08-26 22:36:50 +00001260 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001261}
1262
Dan Gohman8181bd12008-07-27 21:46:04 +00001263static SDValue
1264LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-12-04 22:23:35 +00001265 SmallVector<CCValAssign, 16> RVLocs;
1266 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1267 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1268 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greif1c80d112008-08-28 21:40:38 +00001269 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001270
Scott Michel8efdca42007-12-04 22:23:35 +00001271 // If this is the first return lowered for this function, add the regs to the
1272 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001273 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001274 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001275 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001276 }
1277
Dan Gohman8181bd12008-07-27 21:46:04 +00001278 SDValue Chain = Op.getOperand(0);
1279 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001280
Scott Michel8efdca42007-12-04 22:23:35 +00001281 // Copy the result values into the output registers.
1282 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1283 CCValAssign &VA = RVLocs[i];
1284 assert(VA.isRegLoc() && "Can only return in registers!");
1285 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1286 Flag = Chain.getValue(1);
1287 }
1288
Gabor Greif1c80d112008-08-28 21:40:38 +00001289 if (Flag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001290 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1291 else
1292 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1293}
1294
1295
1296//===----------------------------------------------------------------------===//
1297// Vector related lowering:
1298//===----------------------------------------------------------------------===//
1299
1300static ConstantSDNode *
1301getVecImm(SDNode *N) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001302 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001303
Scott Michel8efdca42007-12-04 22:23:35 +00001304 // Check to see if this buildvec has a single non-undef value in its elements.
1305 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1306 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greif1c80d112008-08-28 21:40:38 +00001307 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001308 OpVal = N->getOperand(i);
1309 else if (OpVal != N->getOperand(i))
1310 return 0;
1311 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001312
Gabor Greif1c80d112008-08-28 21:40:38 +00001313 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001314 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001315 return CN;
1316 }
1317 }
1318
1319 return 0; // All UNDEF: use implicit def.; not Constant node
1320}
1321
1322/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1323/// and the value fits into an unsigned 18-bit constant, and if so, return the
1324/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001325SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001326 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001327 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001328 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001329 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001330 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001331 uint32_t upper = uint32_t(UValue >> 32);
1332 uint32_t lower = uint32_t(UValue);
1333 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001334 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001335 Value = Value >> 32;
1336 }
Scott Michel8efdca42007-12-04 22:23:35 +00001337 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001338 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001339 }
1340
Dan Gohman8181bd12008-07-27 21:46:04 +00001341 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001342}
1343
1344/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1345/// and the value fits into a signed 16-bit constant, and if so, return the
1346/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001347SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001348 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001349 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001350 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001351 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001352 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001353 uint32_t upper = uint32_t(UValue >> 32);
1354 uint32_t lower = uint32_t(UValue);
1355 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001356 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001357 Value = Value >> 32;
1358 }
Scott Michel6baba072008-03-05 23:02:02 +00001359 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001360 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001361 }
1362 }
1363
Dan Gohman8181bd12008-07-27 21:46:04 +00001364 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001365}
1366
1367/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1368/// and the value fits into a signed 10-bit constant, and if so, return the
1369/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001370SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001371 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001372 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001373 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001374 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001375 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001376 uint32_t upper = uint32_t(UValue >> 32);
1377 uint32_t lower = uint32_t(UValue);
1378 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001379 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001380 Value = Value >> 32;
1381 }
Scott Michel6baba072008-03-05 23:02:02 +00001382 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001383 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001384 }
1385
Dan Gohman8181bd12008-07-27 21:46:04 +00001386 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001387}
1388
1389/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1390/// and the value fits into a signed 8-bit constant, and if so, return the
1391/// constant.
1392///
1393/// @note: The incoming vector is v16i8 because that's the only way we can load
1394/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1395/// same value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001396SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001397 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001398 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001399 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001400 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001401 && Value <= 0xffff /* truncated from uint64_t */
1402 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001403 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001404 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001405 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001406 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001407 }
1408
Dan Gohman8181bd12008-07-27 21:46:04 +00001409 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001410}
1411
1412/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1413/// and the value fits into a signed 16-bit constant, and if so, return the
1414/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001415SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001416 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001417 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001418 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001419 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001420 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1421 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001422 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001423 }
1424
Dan Gohman8181bd12008-07-27 21:46:04 +00001425 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001426}
1427
1428/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001429SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001430 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001431 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001432 }
1433
Dan Gohman8181bd12008-07-27 21:46:04 +00001434 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001435}
1436
1437/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001438SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001439 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001440 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001441 }
1442
Dan Gohman8181bd12008-07-27 21:46:04 +00001443 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001444}
1445
1446// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001447// UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001448// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1449// zero. Return true if this is not an array of constants, false if it is.
1450//
1451static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1452 uint64_t UndefBits[2]) {
1453 // Start with zero'd results.
1454 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001455
Duncan Sands92c43912008-06-06 12:08:01 +00001456 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel8efdca42007-12-04 22:23:35 +00001457 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001458 SDValue OpVal = BV->getOperand(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001459
Scott Michel8efdca42007-12-04 22:23:35 +00001460 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1461 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1462
1463 uint64_t EltBits = 0;
1464 if (OpVal.getOpcode() == ISD::UNDEF) {
1465 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1466 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1467 continue;
Scott Michel5974f432008-11-11 03:06:06 +00001468 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001469 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel5974f432008-11-11 03:06:06 +00001470 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001471 const APFloat &apf = CN->getValueAPF();
1472 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001473 ? FloatToBits(apf.convertToFloat())
1474 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001475 } else {
1476 // Nonconstant element.
1477 return true;
1478 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001479
Scott Michel8efdca42007-12-04 22:23:35 +00001480 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1481 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001482
1483 //printf("%llx %llx %llx %llx\n",
Scott Michel8efdca42007-12-04 22:23:35 +00001484 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1485 return false;
1486}
1487
1488/// If this is a splat (repetition) of a value across the whole vector, return
1489/// the smallest size that splats it. For example, "0x01010101010101..." is a
Scott Michel4ec722e2008-07-16 17:17:29 +00001490/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel8efdca42007-12-04 22:23:35 +00001491/// SplatSize = 1 byte.
Scott Michel4ec722e2008-07-16 17:17:29 +00001492static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel8efdca42007-12-04 22:23:35 +00001493 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001494 int MinSplatBits,
Scott Michel8efdca42007-12-04 22:23:35 +00001495 uint64_t &SplatBits, uint64_t &SplatUndef,
1496 int &SplatSize) {
1497 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1498 // the same as the lower 64-bits, ignoring undefs.
1499 uint64_t Bits64 = Bits128[0] | Bits128[1];
1500 uint64_t Undef64 = Undef128[0] & Undef128[1];
1501 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1502 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1503 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1504 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1505
1506 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1507 if (MinSplatBits < 64) {
Scott Michel4ec722e2008-07-16 17:17:29 +00001508
Scott Michel8efdca42007-12-04 22:23:35 +00001509 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1510 // undefs.
1511 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001512 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001513
Scott Michel5a6f17b2008-01-30 02:55:46 +00001514 // If the top 16-bits are different than the lower 16-bits, ignoring
1515 // undefs, we have an i32 splat.
1516 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1517 if (MinSplatBits < 16) {
1518 // If the top 8-bits are different than the lower 8-bits, ignoring
1519 // undefs, we have an i16 splat.
Gabor Greife9f7f582008-08-31 15:37:04 +00001520 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1521 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001522 // Otherwise, we have an 8-bit splat.
1523 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1524 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1525 SplatSize = 1;
1526 return true;
1527 }
1528 } else {
1529 SplatBits = Bits16;
1530 SplatUndef = Undef16;
1531 SplatSize = 2;
1532 return true;
1533 }
1534 }
1535 } else {
1536 SplatBits = Bits32;
1537 SplatUndef = Undef32;
1538 SplatSize = 4;
1539 return true;
1540 }
Scott Michel8efdca42007-12-04 22:23:35 +00001541 }
1542 } else {
1543 SplatBits = Bits128[0];
1544 SplatUndef = Undef128[0];
1545 SplatSize = 8;
1546 return true;
1547 }
1548 }
1549
1550 return false; // Can't be a splat if two pieces don't match.
1551}
1552
1553// If this is a case we can't handle, return null and let the default
1554// expansion code take care of it. If we CAN select this case, and if it
1555// selects to a single instruction, return Op. Otherwise, if we can codegen
1556// this case more efficiently than a constant pool load, lower it to the
1557// sequence of ops that should be used.
Dan Gohman8181bd12008-07-27 21:46:04 +00001558static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001559 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00001560 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001561 // UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001562 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel4ec722e2008-07-16 17:17:29 +00001563 // zero.
Scott Michel8efdca42007-12-04 22:23:35 +00001564 uint64_t VectorBits[2];
1565 uint64_t UndefBits[2];
1566 uint64_t SplatBits, SplatUndef;
1567 int SplatSize;
Gabor Greif1c80d112008-08-28 21:40:38 +00001568 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel8efdca42007-12-04 22:23:35 +00001569 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00001570 VT.getVectorElementType().getSizeInBits(),
Scott Michel8efdca42007-12-04 22:23:35 +00001571 SplatBits, SplatUndef, SplatSize))
Dan Gohman8181bd12008-07-27 21:46:04 +00001572 return SDValue(); // Not a constant vector, not a splat.
Scott Michel4ec722e2008-07-16 17:17:29 +00001573
Duncan Sands92c43912008-06-06 12:08:01 +00001574 switch (VT.getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001575 default:
1576 case MVT::v4f32: {
1577 uint32_t Value32 = SplatBits;
1578 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001579 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001580 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001581 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001582 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001583 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001584 break;
1585 }
1586 case MVT::v2f64: {
1587 uint64_t f64val = SplatBits;
1588 assert(SplatSize == 8
Scott Michelc630c412008-11-24 17:11:17 +00001589 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001590 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001591 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001592 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001593 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001594 break;
1595 }
1596 case MVT::v16i8: {
1597 // 8-bit constants have to be expanded to 16-bits
1598 unsigned short Value16 = SplatBits | (SplatBits << 8);
Dan Gohman8181bd12008-07-27 21:46:04 +00001599 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001600 for (int i = 0; i < 8; ++i)
1601 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1602 return DAG.getNode(ISD::BIT_CONVERT, VT,
1603 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1604 }
1605 case MVT::v8i16: {
1606 unsigned short Value16;
Scott Michel4ec722e2008-07-16 17:17:29 +00001607 if (SplatSize == 2)
Scott Michel8efdca42007-12-04 22:23:35 +00001608 Value16 = (unsigned short) (SplatBits & 0xffff);
1609 else
1610 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman8181bd12008-07-27 21:46:04 +00001611 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1612 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001613 for (int i = 0; i < 8; ++i) Ops[i] = T;
1614 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1615 }
1616 case MVT::v4i32: {
1617 unsigned int Value = SplatBits;
Dan Gohman8181bd12008-07-27 21:46:04 +00001618 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel8efdca42007-12-04 22:23:35 +00001619 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1620 }
1621 case MVT::v2i64: {
1622 uint64_t val = SplatBits;
1623 uint32_t upper = uint32_t(val >> 32);
1624 uint32_t lower = uint32_t(val);
1625
Scott Michelbcc7b672008-03-06 04:02:54 +00001626 if (upper == lower) {
1627 // Magic constant that can be matched by IL, ILA, et. al.
Dan Gohman8181bd12008-07-27 21:46:04 +00001628 SDValue Val = DAG.getTargetConstant(val, MVT::i64);
Scott Michelbcc7b672008-03-06 04:02:54 +00001629 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel6baba072008-03-05 23:02:02 +00001630 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +00001631 SDValue LO32;
1632 SDValue HI32;
1633 SmallVector<SDValue, 16> ShufBytes;
1634 SDValue Result;
Scott Michel8efdca42007-12-04 22:23:35 +00001635 bool upper_special, lower_special;
1636
1637 // NOTE: This code creates common-case shuffle masks that can be easily
1638 // detected as common expressions. It is not attempting to create highly
1639 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1640
1641 // Detect if the upper or lower half is a special shuffle mask pattern:
Scott Michelc630c412008-11-24 17:11:17 +00001642 upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
1643 lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
Scott Michel8efdca42007-12-04 22:23:35 +00001644
1645 // Create lower vector if not a special pattern
1646 if (!lower_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001647 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001648 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1649 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1650 LO32C, LO32C, LO32C, LO32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001651 }
1652
1653 // Create upper vector if not a special pattern
1654 if (!upper_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001655 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001656 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1657 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1658 HI32C, HI32C, HI32C, HI32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001659 }
1660
1661 // If either upper or lower are special, then the two input operands are
1662 // the same (basically, one of them is a "don't care")
1663 if (lower_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001664 LO32 = HI32;
Scott Michel8efdca42007-12-04 22:23:35 +00001665 if (upper_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001666 HI32 = LO32;
Scott Michel8efdca42007-12-04 22:23:35 +00001667 if (lower_special && upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001668 // Unhappy situation... both upper and lower are special, so punt with
1669 // a target constant:
Dan Gohman8181bd12008-07-27 21:46:04 +00001670 SDValue Zero = DAG.getConstant(0, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001671 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel8efdca42007-12-04 22:23:35 +00001672 Zero, Zero);
1673 }
1674
1675 for (int i = 0; i < 4; ++i) {
Scott Michel67224b22008-06-02 22:18:03 +00001676 uint64_t val = 0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001677 for (int j = 0; j < 4; ++j) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001678 SDValue V;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001679 bool process_upper, process_lower;
Scott Michel67224b22008-06-02 22:18:03 +00001680 val <<= 8;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001681 process_upper = (upper_special && (i & 1) == 0);
1682 process_lower = (lower_special && (i & 1) == 1);
Scott Michel8efdca42007-12-04 22:23:35 +00001683
Scott Michel5a6f17b2008-01-30 02:55:46 +00001684 if (process_upper || process_lower) {
1685 if ((process_upper && upper == 0)
1686 || (process_lower && lower == 0))
Scott Michel67224b22008-06-02 22:18:03 +00001687 val |= 0x80;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001688 else if ((process_upper && upper == 0xffffffff)
1689 || (process_lower && lower == 0xffffffff))
Scott Michel67224b22008-06-02 22:18:03 +00001690 val |= 0xc0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001691 else if ((process_upper && upper == 0x80000000)
1692 || (process_lower && lower == 0x80000000))
Scott Michel67224b22008-06-02 22:18:03 +00001693 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001694 } else
Scott Michel67224b22008-06-02 22:18:03 +00001695 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001696 }
Scott Michel67224b22008-06-02 22:18:03 +00001697
1698 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001699 }
1700
1701 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel67224b22008-06-02 22:18:03 +00001702 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001703 &ShufBytes[0], ShufBytes.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001704 }
1705 }
1706 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001707
Dan Gohman8181bd12008-07-27 21:46:04 +00001708 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001709}
1710
1711/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1712/// which the Cell can operate. The code inspects V3 to ascertain whether the
1713/// permutation vector, V3, is monotonically increasing with one "exception"
1714/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel56a125e2008-11-22 23:50:42 +00001715/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-12-04 22:23:35 +00001716/// In either case, the net result is going to eventually invoke SHUFB to
1717/// permute/shuffle the bytes from V1 and V2.
1718/// \note
Scott Michel56a125e2008-11-22 23:50:42 +00001719/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-12-04 22:23:35 +00001720/// control word for byte/halfword/word insertion. This takes care of a single
1721/// element move from V2 into V1.
1722/// \note
1723/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman8181bd12008-07-27 21:46:04 +00001724static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
1725 SDValue V1 = Op.getOperand(0);
1726 SDValue V2 = Op.getOperand(1);
1727 SDValue PermMask = Op.getOperand(2);
Scott Michel4ec722e2008-07-16 17:17:29 +00001728
Scott Michel8efdca42007-12-04 22:23:35 +00001729 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001730
Scott Michel8efdca42007-12-04 22:23:35 +00001731 // If we have a single element being moved from V1 to V2, this can be handled
1732 // using the C*[DX] compute mask instructions, but the vector elements have
1733 // to be monotonically increasing with one exception element.
Scott Michele2641a12008-12-04 21:01:44 +00001734 MVT VecVT = V1.getValueType();
1735 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001736 unsigned EltsFromV2 = 0;
1737 unsigned V2Elt = 0;
1738 unsigned V2EltIdx0 = 0;
1739 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001740 unsigned MaxElts = VecVT.getVectorNumElements();
1741 unsigned PrevElt = 0;
1742 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001743 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001744 bool rotate = true;
1745
1746 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001747 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001748 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001749 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001750 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001751 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001752 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1753 V2EltIdx0 = 2;
1754 } else
Scott Michel8efdca42007-12-04 22:23:35 +00001755 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1756
Scott Michele2641a12008-12-04 21:01:44 +00001757 for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) {
1758 if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) {
1759 unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001760
Scott Michele2641a12008-12-04 21:01:44 +00001761 if (monotonic) {
1762 if (SrcElt >= V2EltIdx0) {
1763 if (1 >= (++EltsFromV2)) {
1764 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1765 }
1766 } else if (CurrElt != SrcElt) {
1767 monotonic = false;
1768 }
1769
1770 ++CurrElt;
1771 }
1772
1773 if (rotate) {
1774 if (PrevElt > 0 && SrcElt < MaxElts) {
1775 if ((PrevElt == SrcElt - 1)
1776 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
1777 PrevElt = SrcElt;
1778 if (SrcElt == 0)
1779 V0Elt = i;
1780 } else {
1781 rotate = false;
1782 }
1783 } else if (PrevElt == 0) {
1784 // First time through, need to keep track of previous element
1785 PrevElt = SrcElt;
1786 } else {
1787 // This isn't a rotation, takes elements from vector 2
1788 rotate = false;
1789 }
1790 }
Scott Michel8efdca42007-12-04 22:23:35 +00001791 }
Scott Michel8efdca42007-12-04 22:23:35 +00001792 }
1793
1794 if (EltsFromV2 == 1 && monotonic) {
1795 // Compute mask and shuffle
1796 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001797 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1798 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001799 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001800 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001801 SDValue InitTempReg =
Scott Michel8efdca42007-12-04 22:23:35 +00001802 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001803 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001804 SDValue ShufMaskOp =
Scott Michel0718cd82008-12-01 17:56:02 +00001805 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001806 DAG.getTargetConstant(V2Elt, MVT::i32),
1807 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001808 // Use shuffle mask in SHUFB synthetic instruction:
1809 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
Scott Michele2641a12008-12-04 21:01:44 +00001810 } else if (rotate) {
1811 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001812
Scott Michele2641a12008-12-04 21:01:44 +00001813 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1814 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001815 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001816 // Convert the SHUFFLE_VECTOR mask's input element units to the
1817 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001818 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001819
Dan Gohman8181bd12008-07-27 21:46:04 +00001820 SmallVector<SDValue, 16> ResultMask;
Scott Michel8efdca42007-12-04 22:23:35 +00001821 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1822 unsigned SrcElt;
1823 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001824 SrcElt = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001825 else
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001826 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel4ec722e2008-07-16 17:17:29 +00001827
Scott Michel97872d32008-02-23 18:41:37 +00001828 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001829 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1830 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001831 }
1832 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001833
Dan Gohman8181bd12008-07-27 21:46:04 +00001834 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel0718cd82008-12-01 17:56:02 +00001835 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001836 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1837 }
1838}
1839
Dan Gohman8181bd12008-07-27 21:46:04 +00001840static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1841 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001842
Gabor Greif1c80d112008-08-28 21:40:38 +00001843 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-12-04 22:23:35 +00001844 // For a constant, build the appropriate constant vector, which will
1845 // eventually simplify to a vector register load.
1846
Gabor Greif1c80d112008-08-28 21:40:38 +00001847 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001848 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001849 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001850 size_t n_copies;
1851
1852 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001853 switch (Op.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001854 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001855 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001856 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1857 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1858 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1859 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1860 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1861 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1862 }
1863
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001864 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-12-04 22:23:35 +00001865 for (size_t j = 0; j < n_copies; ++j)
1866 ConstVecValues.push_back(CValue);
1867
1868 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001869 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001870 } else {
1871 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001872 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001873 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1874 case MVT::i8:
1875 case MVT::i16:
1876 case MVT::i32:
1877 case MVT::i64:
1878 case MVT::f32:
1879 case MVT::f64:
Scott Michel06eabde2008-12-27 04:51:36 +00001880 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001881 }
1882 }
1883
Dan Gohman8181bd12008-07-27 21:46:04 +00001884 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001885}
1886
Dan Gohman8181bd12008-07-27 21:46:04 +00001887static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001888 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001889 SDValue N = Op.getOperand(0);
1890 SDValue Elt = Op.getOperand(1);
Scott Michel56a125e2008-11-22 23:50:42 +00001891 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001892
Scott Michel56a125e2008-11-22 23:50:42 +00001893 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1894 // Constant argument:
1895 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001896
Scott Michel56a125e2008-11-22 23:50:42 +00001897 // sanity checks:
1898 if (VT == MVT::i8 && EltNo >= 16)
1899 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1900 else if (VT == MVT::i16 && EltNo >= 8)
1901 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1902 else if (VT == MVT::i32 && EltNo >= 4)
1903 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1904 else if (VT == MVT::i64 && EltNo >= 2)
1905 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel8efdca42007-12-04 22:23:35 +00001906
Scott Michel56a125e2008-11-22 23:50:42 +00001907 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1908 // i32 and i64: Element 0 is the preferred slot
Scott Michelc630c412008-11-24 17:11:17 +00001909 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001910 }
Scott Michel8efdca42007-12-04 22:23:35 +00001911
Scott Michel56a125e2008-11-22 23:50:42 +00001912 // Need to generate shuffle mask and extract:
1913 int prefslot_begin = -1, prefslot_end = -1;
1914 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1915
1916 switch (VT.getSimpleVT()) {
1917 default:
1918 assert(false && "Invalid value type!");
1919 case MVT::i8: {
1920 prefslot_begin = prefslot_end = 3;
1921 break;
1922 }
1923 case MVT::i16: {
1924 prefslot_begin = 2; prefslot_end = 3;
1925 break;
1926 }
1927 case MVT::i32:
1928 case MVT::f32: {
1929 prefslot_begin = 0; prefslot_end = 3;
1930 break;
1931 }
1932 case MVT::i64:
1933 case MVT::f64: {
1934 prefslot_begin = 0; prefslot_end = 7;
1935 break;
1936 }
1937 }
1938
1939 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1940 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1941
1942 unsigned int ShufBytes[16];
1943 for (int i = 0; i < 16; ++i) {
1944 // zero fill uppper part of preferred slot, don't care about the
1945 // other slots:
1946 unsigned int mask_val;
1947 if (i <= prefslot_end) {
1948 mask_val =
1949 ((i < prefslot_begin)
1950 ? 0x80
1951 : elt_byte + (i - prefslot_begin));
1952
1953 ShufBytes[i] = mask_val;
1954 } else
1955 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1956 }
1957
1958 SDValue ShufMask[4];
1959 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michele2641a12008-12-04 21:01:44 +00001960 unsigned bidx = i * 4;
Scott Michel56a125e2008-11-22 23:50:42 +00001961 unsigned int bits = ((ShufBytes[bidx] << 24) |
1962 (ShufBytes[bidx+1] << 16) |
1963 (ShufBytes[bidx+2] << 8) |
1964 ShufBytes[bidx+3]);
1965 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1966 }
1967
1968 SDValue ShufMaskVec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1969 &ShufMask[0],
1970 sizeof(ShufMask) / sizeof(ShufMask[0]));
1971
Scott Michelc630c412008-11-24 17:11:17 +00001972 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel56a125e2008-11-22 23:50:42 +00001973 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
1974 N, N, ShufMaskVec));
1975 } else {
1976 // Variable index: Rotate the requested element into slot 0, then replicate
1977 // slot 0 across the vector
1978 MVT VecVT = N.getValueType();
1979 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
1980 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
1981 abort();
1982 }
1983
1984 // Make life easier by making sure the index is zero-extended to i32
1985 if (Elt.getValueType() != MVT::i32)
1986 Elt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Elt);
1987
1988 // Scale the index to a bit/byte shift quantity
1989 APInt scaleFactor =
Scott Michelc630c412008-11-24 17:11:17 +00001990 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1991 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00001992 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00001993
Scott Michelc630c412008-11-24 17:11:17 +00001994 if (scaleShift > 0) {
1995 // Scale the shift factor:
Scott Michel56a125e2008-11-22 23:50:42 +00001996 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00001997 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00001998 }
1999
Scott Michelc630c412008-11-24 17:11:17 +00002000 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt);
2001
2002 // Replicate the bytes starting at byte 0 across the entire vector (for
2003 // consistency with the notion of a unified register set)
Scott Michel56a125e2008-11-22 23:50:42 +00002004 SDValue replicate;
2005
2006 switch (VT.getSimpleVT()) {
2007 default:
2008 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
2009 abort();
2010 /*NOTREACHED*/
2011 case MVT::i8: {
Scott Michelc630c412008-11-24 17:11:17 +00002012 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel56a125e2008-11-22 23:50:42 +00002013 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2014 factor, factor);
2015 break;
2016 }
2017 case MVT::i16: {
Scott Michelc630c412008-11-24 17:11:17 +00002018 SDValue factor = DAG.getConstant(0x00010001, 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::i32:
2024 case MVT::f32: {
2025 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
2026 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2027 factor, factor);
2028 break;
2029 }
2030 case MVT::i64:
2031 case MVT::f64: {
2032 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2033 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
2034 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, loFactor, hiFactor,
2035 loFactor, hiFactor);
2036 break;
2037 }
2038 }
2039
Scott Michelc630c412008-11-24 17:11:17 +00002040 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel0718cd82008-12-01 17:56:02 +00002041 DAG.getNode(SPUISD::SHUFB, VecVT,
2042 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002043 }
2044
Scott Michel56a125e2008-11-22 23:50:42 +00002045 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002046}
2047
Dan Gohman8181bd12008-07-27 21:46:04 +00002048static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2049 SDValue VecOp = Op.getOperand(0);
2050 SDValue ValOp = Op.getOperand(1);
2051 SDValue IdxOp = Op.getOperand(2);
Duncan Sands92c43912008-06-06 12:08:01 +00002052 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002053
2054 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2055 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2056
Duncan Sands92c43912008-06-06 12:08:01 +00002057 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-12-01 17:56:02 +00002058 // Use $sp ($1) because it's always 16-byte aligned and it's available:
2059 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
2060 DAG.getRegister(SPU::R1, PtrVT),
2061 DAG.getConstant(CN->getSExtValue(), PtrVT));
2062 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer);
Scott Michel8efdca42007-12-04 22:23:35 +00002063
Dan Gohman8181bd12008-07-27 21:46:04 +00002064 SDValue result =
Scott Michel8efdca42007-12-04 22:23:35 +00002065 DAG.getNode(SPUISD::SHUFB, VT,
2066 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002067 VecOp,
Scott Michel0718cd82008-12-01 17:56:02 +00002068 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002069
2070 return result;
2071}
2072
Scott Michel06eabde2008-12-27 04:51:36 +00002073static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2074 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002075{
Dan Gohman8181bd12008-07-27 21:46:04 +00002076 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michel06eabde2008-12-27 04:51:36 +00002077 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-12-04 22:23:35 +00002078
2079 assert(Op.getValueType() == MVT::i8);
2080 switch (Opc) {
2081 default:
2082 assert(0 && "Unhandled i8 math operator");
2083 /*NOTREACHED*/
2084 break;
Scott Michel4d07fb72008-12-30 23:28:25 +00002085 case ISD::ADD: {
2086 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2087 // the result:
2088 SDValue N1 = Op.getOperand(1);
2089 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2090 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
2091 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2092 DAG.getNode(Opc, MVT::i16, N0, N1));
2093
2094 }
2095
Scott Michel8efdca42007-12-04 22:23:35 +00002096 case ISD::SUB: {
2097 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2098 // the result:
Dan Gohman8181bd12008-07-27 21:46:04 +00002099 SDValue N1 = Op.getOperand(1);
Scott Michel4d07fb72008-12-30 23:28:25 +00002100 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2101 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
Scott Michel4ec722e2008-07-16 17:17:29 +00002102 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002103 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel4ec722e2008-07-16 17:17:29 +00002104 }
Scott Michel8efdca42007-12-04 22:23:35 +00002105 case ISD::ROTR:
2106 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002107 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002108 unsigned N1Opc;
2109 N0 = (N0.getOpcode() != ISD::Constant
2110 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002111 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2112 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002113 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002114 ? ISD::ZERO_EXTEND
2115 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002116 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002117 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002118 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002119 TLI.getShiftAmountTy()));
Dan Gohman8181bd12008-07-27 21:46:04 +00002120 SDValue ExpandArg =
Scott Michel8efdca42007-12-04 22:23:35 +00002121 DAG.getNode(ISD::OR, MVT::i16, N0,
2122 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002123 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel4ec722e2008-07-16 17:17:29 +00002124 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002125 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2126 }
2127 case ISD::SRL:
2128 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002129 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002130 unsigned N1Opc;
2131 N0 = (N0.getOpcode() != ISD::Constant
2132 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002133 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002134 MVT::i32));
2135 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002136 ? ISD::ZERO_EXTEND
2137 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002138 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002139 ? DAG.getNode(N1Opc, ShiftVT, N1)
2140 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002141 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002142 DAG.getNode(Opc, MVT::i16, N0, N1));
2143 }
2144 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002145 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002146 unsigned N1Opc;
2147 N0 = (N0.getOpcode() != ISD::Constant
2148 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michel06eabde2008-12-27 04:51:36 +00002149 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002150 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002151 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002152 ? ISD::SIGN_EXTEND
2153 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002154 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002155 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002156 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002157 ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002158 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002159 DAG.getNode(Opc, MVT::i16, N0, N1));
2160 }
2161 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002162 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002163 unsigned N1Opc;
2164 N0 = (N0.getOpcode() != ISD::Constant
2165 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002166 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2167 MVT::i16));
Duncan Sandsec142ee2008-06-08 20:54:56 +00002168 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002169 N1 = (N1.getOpcode() != ISD::Constant
2170 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michel06eabde2008-12-27 04:51:36 +00002171 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002172 MVT::i16));
Scott Michel4ec722e2008-07-16 17:17:29 +00002173 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002174 DAG.getNode(Opc, MVT::i16, N0, N1));
2175 break;
2176 }
2177 }
2178
Dan Gohman8181bd12008-07-27 21:46:04 +00002179 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002180}
2181
Dan Gohman8181bd12008-07-27 21:46:04 +00002182static SDValue LowerI64Math(SDValue Op, SelectionDAG &DAG, unsigned Opc)
Scott Michel97872d32008-02-23 18:41:37 +00002183{
Duncan Sands92c43912008-06-06 12:08:01 +00002184 MVT VT = Op.getValueType();
2185 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel97872d32008-02-23 18:41:37 +00002186
Dan Gohman8181bd12008-07-27 21:46:04 +00002187 SDValue Op0 = Op.getOperand(0);
Scott Michel97872d32008-02-23 18:41:37 +00002188
2189 switch (Opc) {
2190 case ISD::ZERO_EXTEND:
Scott Michel97872d32008-02-23 18:41:37 +00002191 case ISD::ANY_EXTEND: {
Duncan Sands92c43912008-06-06 12:08:01 +00002192 MVT Op0VT = Op0.getValueType();
2193 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
Scott Michel97872d32008-02-23 18:41:37 +00002194
Dan Gohman8181bd12008-07-27 21:46:04 +00002195 SDValue PromoteScalar =
Scott Michel06eabde2008-12-27 04:51:36 +00002196 DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
Scott Michel97872d32008-02-23 18:41:37 +00002197
Scott Michel4d07fb72008-12-30 23:28:25 +00002198 // Use a shuffle to zero extend the i32 to i64 directly:
Scott Michel2ef773a2009-01-06 03:36:14 +00002199 SDValue shufMask;
Scott Michelf2df6cb2008-11-24 18:20:46 +00002200
Scott Michel2ef773a2009-01-06 03:36:14 +00002201 switch (Op0VT.getSimpleVT()) {
2202 default:
2203 cerr << "CellSPU LowerI64Math: Unhandled zero/any extend MVT\n";
2204 abort();
2205 /*NOTREACHED*/
2206 break;
2207 case MVT::i32:
2208 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2209 DAG.getConstant(0x80808080, MVT::i32),
2210 DAG.getConstant(0x00010203, MVT::i32),
2211 DAG.getConstant(0x80808080, MVT::i32),
2212 DAG.getConstant(0x08090a0b, MVT::i32));
2213 break;
2214
2215 case MVT::i16:
2216 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2217 DAG.getConstant(0x80808080, MVT::i32),
2218 DAG.getConstant(0x80800203, MVT::i32),
2219 DAG.getConstant(0x80808080, MVT::i32),
2220 DAG.getConstant(0x80800a0b, MVT::i32));
2221 break;
2222
2223 case MVT::i8:
2224 shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2225 DAG.getConstant(0x80808080, MVT::i32),
2226 DAG.getConstant(0x80808003, MVT::i32),
2227 DAG.getConstant(0x80808080, MVT::i32),
2228 DAG.getConstant(0x8080800b, MVT::i32));
2229 break;
2230 }
2231
2232 SDValue zextShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2233 PromoteScalar, PromoteScalar, shufMask);
2234
2235 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2236 DAG.getNode(ISD::BIT_CONVERT, VecVT, zextShuffle));
Scott Michel97872d32008-02-23 18:41:37 +00002237 }
2238
Scott Michel67224b22008-06-02 22:18:03 +00002239 case ISD::ADD: {
2240 // Turn operands into vectors to satisfy type checking (shufb works on
2241 // vectors)
Dan Gohman8181bd12008-07-27 21:46:04 +00002242 SDValue Op0 =
Scott Michel06eabde2008-12-27 04:51:36 +00002243 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman8181bd12008-07-27 21:46:04 +00002244 SDValue Op1 =
Scott Michel06eabde2008-12-27 04:51:36 +00002245 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman8181bd12008-07-27 21:46:04 +00002246 SmallVector<SDValue, 16> ShufBytes;
Scott Michel67224b22008-06-02 22:18:03 +00002247
2248 // Create the shuffle mask for "rotating" the borrow up one register slot
2249 // once the borrow is generated.
2250 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2251 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2252 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2253 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2254
Dan Gohman8181bd12008-07-27 21:46:04 +00002255 SDValue CarryGen =
Scott Michel67224b22008-06-02 22:18:03 +00002256 DAG.getNode(SPUISD::CARRY_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman8181bd12008-07-27 21:46:04 +00002257 SDValue ShiftedCarry =
Scott Michel67224b22008-06-02 22:18:03 +00002258 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2259 CarryGen, CarryGen,
2260 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2261 &ShufBytes[0], ShufBytes.size()));
2262
Scott Michelc630c412008-11-24 17:11:17 +00002263 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Michel67224b22008-06-02 22:18:03 +00002264 DAG.getNode(SPUISD::ADD_EXTENDED, MVT::v2i64,
2265 Op0, Op1, ShiftedCarry));
2266 }
2267
2268 case ISD::SUB: {
2269 // Turn operands into vectors to satisfy type checking (shufb works on
2270 // vectors)
Dan Gohman8181bd12008-07-27 21:46:04 +00002271 SDValue Op0 =
Scott Michel06eabde2008-12-27 04:51:36 +00002272 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(0));
Dan Gohman8181bd12008-07-27 21:46:04 +00002273 SDValue Op1 =
Scott Michel06eabde2008-12-27 04:51:36 +00002274 DAG.getNode(SPUISD::PREFSLOT2VEC, MVT::v2i64, Op.getOperand(1));
Dan Gohman8181bd12008-07-27 21:46:04 +00002275 SmallVector<SDValue, 16> ShufBytes;
Scott Michel67224b22008-06-02 22:18:03 +00002276
2277 // Create the shuffle mask for "rotating" the borrow up one register slot
2278 // once the borrow is generated.
2279 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2280 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2281 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2282 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2283
Dan Gohman8181bd12008-07-27 21:46:04 +00002284 SDValue BorrowGen =
Scott Michel67224b22008-06-02 22:18:03 +00002285 DAG.getNode(SPUISD::BORROW_GENERATE, MVT::v2i64, Op0, Op1);
Dan Gohman8181bd12008-07-27 21:46:04 +00002286 SDValue ShiftedBorrow =
Scott Michel67224b22008-06-02 22:18:03 +00002287 DAG.getNode(SPUISD::SHUFB, MVT::v2i64,
2288 BorrowGen, BorrowGen,
2289 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2290 &ShufBytes[0], ShufBytes.size()));
2291
Scott Michelc630c412008-11-24 17:11:17 +00002292 return DAG.getNode(SPUISD::VEC2PREFSLOT, MVT::i64,
Scott Michel67224b22008-06-02 22:18:03 +00002293 DAG.getNode(SPUISD::SUB_EXTENDED, MVT::v2i64,
2294 Op0, Op1, ShiftedBorrow));
2295 }
Scott Michel97872d32008-02-23 18:41:37 +00002296 }
2297
Dan Gohman8181bd12008-07-27 21:46:04 +00002298 return SDValue();
Scott Michel97872d32008-02-23 18:41:37 +00002299}
2300
Scott Michel8efdca42007-12-04 22:23:35 +00002301//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002302static SDValue
2303LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2304 SDValue ConstVec;
2305 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002306 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002307
2308 ConstVec = Op.getOperand(0);
2309 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002310 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2311 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002312 ConstVec = ConstVec.getOperand(0);
2313 } else {
2314 ConstVec = Op.getOperand(1);
2315 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002316 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002317 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002318 }
2319 }
2320 }
2321
Gabor Greif1c80d112008-08-28 21:40:38 +00002322 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel8efdca42007-12-04 22:23:35 +00002323 uint64_t VectorBits[2];
2324 uint64_t UndefBits[2];
2325 uint64_t SplatBits, SplatUndef;
2326 int SplatSize;
2327
Gabor Greif1c80d112008-08-28 21:40:38 +00002328 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002329 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00002330 VT.getVectorElementType().getSizeInBits(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002331 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002332 SDValue tcVec[16];
2333 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002334 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2335
2336 // Turn the BUILD_VECTOR into a set of target constants:
2337 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002338 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002339
Gabor Greif1c80d112008-08-28 21:40:38 +00002340 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002341 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002342 }
2343 }
Nate Begeman7569e762008-07-29 19:07:27 +00002344 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2345 // lowered. Return the operation, rather than a null SDValue.
2346 return Op;
Scott Michel8efdca42007-12-04 22:23:35 +00002347}
2348
Scott Michel8efdca42007-12-04 22:23:35 +00002349//! Custom lowering for CTPOP (count population)
2350/*!
2351 Custom lowering code that counts the number ones in the input
2352 operand. SPU has such an instruction, but it counts the number of
2353 ones per byte, which then have to be accumulated.
2354*/
Dan Gohman8181bd12008-07-27 21:46:04 +00002355static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002356 MVT VT = Op.getValueType();
2357 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +00002358
Duncan Sands92c43912008-06-06 12:08:01 +00002359 switch (VT.getSimpleVT()) {
2360 default:
2361 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002362 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002363 SDValue N = Op.getOperand(0);
2364 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002365
Scott Michel06eabde2008-12-27 04:51:36 +00002366 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002367 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002368
2369 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2370 }
2371
2372 case MVT::i16: {
2373 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002374 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002375
Chris Lattner1b989192007-12-31 04:13:23 +00002376 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002377
Dan Gohman8181bd12008-07-27 21:46:04 +00002378 SDValue N = Op.getOperand(0);
2379 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2380 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sands7aef60d2008-10-30 19:24:28 +00002381 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002382
Scott Michel06eabde2008-12-27 04:51:36 +00002383 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002384 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002385
2386 // CNTB_result becomes the chain to which all of the virtual registers
2387 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002388 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002389 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002390
Dan Gohman8181bd12008-07-27 21:46:04 +00002391 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002392 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2393
Dan Gohman8181bd12008-07-27 21:46:04 +00002394 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002395
2396 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002397 DAG.getNode(ISD::ADD, MVT::i16,
2398 DAG.getNode(ISD::SRL, MVT::i16,
2399 Tmp1, Shift1),
2400 Tmp1),
2401 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002402 }
2403
2404 case MVT::i32: {
2405 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002406 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002407
Chris Lattner1b989192007-12-31 04:13:23 +00002408 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2409 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002410
Dan Gohman8181bd12008-07-27 21:46:04 +00002411 SDValue N = Op.getOperand(0);
2412 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2413 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2414 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2415 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002416
Scott Michel06eabde2008-12-27 04:51:36 +00002417 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002418 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002419
2420 // CNTB_result becomes the chain to which all of the virtual registers
2421 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002422 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002423 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002424
Dan Gohman8181bd12008-07-27 21:46:04 +00002425 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002426 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2427
Dan Gohman8181bd12008-07-27 21:46:04 +00002428 SDValue Comp1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002429 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002430 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002431
Dan Gohman8181bd12008-07-27 21:46:04 +00002432 SDValue Sum1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002433 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002434 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002435
Dan Gohman8181bd12008-07-27 21:46:04 +00002436 SDValue Sum1_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002437 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2438
Dan Gohman8181bd12008-07-27 21:46:04 +00002439 SDValue Comp2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002440 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002441 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2442 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002443 SDValue Sum2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002444 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002445 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002446
2447 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2448 }
2449
2450 case MVT::i64:
2451 break;
2452 }
2453
Dan Gohman8181bd12008-07-27 21:46:04 +00002454 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002455}
2456
Scott Michel06eabde2008-12-27 04:51:36 +00002457//! Lower ISD::SETCC
2458/*!
2459 Lower i64 condition code handling.
2460 */
2461
2462static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) {
2463 MVT VT = Op.getValueType();
2464 SDValue lhs = Op.getOperand(0);
2465 SDValue rhs = Op.getOperand(1);
2466 SDValue condition = Op.getOperand(2);
2467
2468 if (VT == MVT::i32 && lhs.getValueType() == MVT::i64) {
2469 // Expand the i64 comparisons to what Cell can actually support,
2470 // which is eq, ugt and sgt:
2471#if 0
2472 CondCodeSDNode *ccvalue = dyn_cast<CondCodeSDValue>(condition);
2473
2474 switch (ccvalue->get()) {
2475 case
2476 }
2477#endif
2478 }
2479
2480 return SDValue();
2481}
2482
Scott Michel56a125e2008-11-22 23:50:42 +00002483//! Lower ISD::SELECT_CC
2484/*!
2485 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2486 SELB instruction.
2487
2488 \note Need to revisit this in the future: if the code path through the true
2489 and false value computations is longer than the latency of a branch (6
2490 cycles), then it would be more advantageous to branch and insert a new basic
2491 block and branch on the condition. However, this code does not make that
2492 assumption, given the simplisitc uses so far.
2493 */
2494
Scott Michel06eabde2008-12-27 04:51:36 +00002495static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2496 const TargetLowering &TLI) {
Scott Michel56a125e2008-11-22 23:50:42 +00002497 MVT VT = Op.getValueType();
2498 SDValue lhs = Op.getOperand(0);
2499 SDValue rhs = Op.getOperand(1);
2500 SDValue trueval = Op.getOperand(2);
2501 SDValue falseval = Op.getOperand(3);
2502 SDValue condition = Op.getOperand(4);
2503
Scott Michel06eabde2008-12-27 04:51:36 +00002504 // NOTE: SELB's arguments: $rA, $rB, $mask
2505 //
2506 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2507 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2508 // condition was true and 0s where the condition was false. Hence, the
2509 // arguments to SELB get reversed.
2510
Scott Michel56a125e2008-11-22 23:50:42 +00002511 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2512 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2513 // with another "cannot select select_cc" assert:
2514
Duncan Sands4a361272009-01-01 15:52:00 +00002515 SDValue compare = DAG.getNode(ISD::SETCC,
2516 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002517 lhs, rhs, condition);
2518 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002519}
2520
Scott Michelec8c82e2008-12-02 19:53:53 +00002521//! Custom lower ISD::TRUNCATE
2522static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2523{
2524 MVT VT = Op.getValueType();
2525 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2526 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
2527
2528 SDValue Op0 = Op.getOperand(0);
2529 MVT Op0VT = Op0.getValueType();
2530 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
2531
Scott Michel06eabde2008-12-27 04:51:36 +00002532 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002533 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-12-27 04:51:36 +00002534 unsigned maskHigh = 0x08090a0b;
2535 unsigned maskLow = 0x0c0d0e0f;
2536 // Use a shuffle to perform the truncation
2537 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2538 DAG.getConstant(maskHigh, MVT::i32),
2539 DAG.getConstant(maskLow, MVT::i32),
2540 DAG.getConstant(maskHigh, MVT::i32),
2541 DAG.getConstant(maskLow, MVT::i32));
2542
2543
2544 SDValue PromoteScalar = DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
2545
2546 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2547 PromoteScalar, PromoteScalar, shufMask);
2548
2549 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2550 DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle));
Scott Michelec8c82e2008-12-02 19:53:53 +00002551 }
2552
Scott Michel06eabde2008-12-27 04:51:36 +00002553 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002554}
2555
Scott Michel56a125e2008-11-22 23:50:42 +00002556//! Custom (target-specific) lowering entry point
2557/*!
2558 This is where LLVM's DAG selection process calls to do target-specific
2559 lowering of nodes.
2560 */
Dan Gohman8181bd12008-07-27 21:46:04 +00002561SDValue
2562SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002563{
Scott Michel97872d32008-02-23 18:41:37 +00002564 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002565 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002566
2567 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002568 default: {
2569 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002570 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002571 cerr << "*Op.getNode():\n";
2572 Op.getNode()->dump();
Scott Michel8efdca42007-12-04 22:23:35 +00002573 abort();
2574 }
2575 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002576 case ISD::EXTLOAD:
Scott Michel8efdca42007-12-04 22:23:35 +00002577 case ISD::SEXTLOAD:
2578 case ISD::ZEXTLOAD:
2579 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2580 case ISD::STORE:
2581 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2582 case ISD::ConstantPool:
2583 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2584 case ISD::GlobalAddress:
2585 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2586 case ISD::JumpTable:
2587 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2588 case ISD::Constant:
2589 return LowerConstant(Op, DAG);
2590 case ISD::ConstantFP:
2591 return LowerConstantFP(Op, DAG);
2592 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002593 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002594 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002595 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002596 case ISD::RET:
2597 return LowerRET(Op, DAG, getTargetMachine());
2598
Scott Michel97872d32008-02-23 18:41:37 +00002599
Scott Michel97872d32008-02-23 18:41:37 +00002600 case ISD::ZERO_EXTEND:
Scott Michel97872d32008-02-23 18:41:37 +00002601 case ISD::ANY_EXTEND:
Scott Michel4d07fb72008-12-30 23:28:25 +00002602 return LowerI64Math(Op, DAG, Opc);
2603
2604 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002605 case ISD::ADD:
Scott Michel8efdca42007-12-04 22:23:35 +00002606 case ISD::SUB:
2607 case ISD::ROTR:
2608 case ISD::ROTL:
2609 case ISD::SRL:
2610 case ISD::SHL:
Scott Michel67224b22008-06-02 22:18:03 +00002611 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002612 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002613 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002614 else if (VT == MVT::i64)
2615 return LowerI64Math(Op, DAG, Opc);
2616 break;
Scott Michel67224b22008-06-02 22:18:03 +00002617 }
Scott Michel8efdca42007-12-04 22:23:35 +00002618
2619 // Vector-related lowering.
2620 case ISD::BUILD_VECTOR:
2621 return LowerBUILD_VECTOR(Op, DAG);
2622 case ISD::SCALAR_TO_VECTOR:
2623 return LowerSCALAR_TO_VECTOR(Op, DAG);
2624 case ISD::VECTOR_SHUFFLE:
2625 return LowerVECTOR_SHUFFLE(Op, DAG);
2626 case ISD::EXTRACT_VECTOR_ELT:
2627 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2628 case ISD::INSERT_VECTOR_ELT:
2629 return LowerINSERT_VECTOR_ELT(Op, DAG);
2630
2631 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2632 case ISD::AND:
2633 case ISD::OR:
2634 case ISD::XOR:
2635 return LowerByteImmed(Op, DAG);
2636
2637 // Vector and i8 multiply:
2638 case ISD::MUL:
Scott Michel4d07fb72008-12-30 23:28:25 +00002639 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002640 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002641
Scott Michel8efdca42007-12-04 22:23:35 +00002642 case ISD::CTPOP:
2643 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002644
2645 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002646 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002647
2648 case ISD::TRUNCATE:
2649 return LowerTRUNCATE(Op, DAG);
Scott Michel06eabde2008-12-27 04:51:36 +00002650
2651 case ISD::SETCC:
2652 return LowerSETCC(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002653 }
2654
Dan Gohman8181bd12008-07-27 21:46:04 +00002655 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002656}
2657
Duncan Sands7d9834b2008-12-01 11:39:25 +00002658void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2659 SmallVectorImpl<SDValue>&Results,
2660 SelectionDAG &DAG)
Scott Michel6e2d68b2008-11-10 23:43:06 +00002661{
2662#if 0
2663 unsigned Opc = (unsigned) N->getOpcode();
2664 MVT OpVT = N->getValueType(0);
2665
2666 switch (Opc) {
2667 default: {
2668 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2669 cerr << "Op.getOpcode() = " << Opc << "\n";
2670 cerr << "*Op.getNode():\n";
2671 N->dump();
2672 abort();
2673 /*NOTREACHED*/
2674 }
2675 }
2676#endif
2677
2678 /* Otherwise, return unchanged */
Scott Michel6e2d68b2008-11-10 23:43:06 +00002679}
2680
Scott Michel8efdca42007-12-04 22:23:35 +00002681//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002682// Target Optimization Hooks
2683//===----------------------------------------------------------------------===//
2684
Dan Gohman8181bd12008-07-27 21:46:04 +00002685SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002686SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2687{
2688#if 0
2689 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002690#endif
2691 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002692 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-12-01 17:56:02 +00002693 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2694 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michel06eabde2008-12-27 04:51:36 +00002695 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002696 SDValue Result; // Initially, empty result
Scott Michel8efdca42007-12-04 22:23:35 +00002697
2698 switch (N->getOpcode()) {
2699 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002700 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002701 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002702
Scott Michel06eabde2008-12-27 04:51:36 +00002703 if (Op0.getOpcode() == SPUISD::IndirectAddr
2704 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2705 // Normalize the operands to reduce repeated code
2706 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michelae5cbf52008-12-29 03:23:36 +00002707
Scott Michel06eabde2008-12-27 04:51:36 +00002708 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2709 IndirectArg = Op1;
2710 AddArg = Op0;
2711 }
2712
2713 if (isa<ConstantSDNode>(AddArg)) {
2714 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2715 SDValue IndOp1 = IndirectArg.getOperand(1);
2716
2717 if (CN0->isNullValue()) {
2718 // (add (SPUindirect <arg>, <arg>), 0) ->
2719 // (SPUindirect <arg>, <arg>)
Scott Michelf9f42e62008-01-29 02:16:57 +00002720
Scott Michel8c2746e2008-12-04 17:16:59 +00002721#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002722 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002723 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002724 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2725 << "With: (SPUindirect <arg>, <arg>)\n";
2726 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002727#endif
2728
Scott Michel06eabde2008-12-27 04:51:36 +00002729 return IndirectArg;
2730 } else if (isa<ConstantSDNode>(IndOp1)) {
2731 // (add (SPUindirect <arg>, <const>), <const>) ->
2732 // (SPUindirect <arg>, <const + const>)
2733 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2734 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2735 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michelf9f42e62008-01-29 02:16:57 +00002736
Scott Michel06eabde2008-12-27 04:51:36 +00002737#if !defined(NDEBUG)
2738 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2739 cerr << "\n"
2740 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2741 << "), " << CN0->getSExtValue() << ")\n"
2742 << "With: (SPUindirect <arg>, "
2743 << combinedConst << ")\n";
2744 }
2745#endif
Scott Michelf9f42e62008-01-29 02:16:57 +00002746
Scott Michel06eabde2008-12-27 04:51:36 +00002747 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2748 IndirectArg, combinedValue);
2749 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002750 }
2751 }
Scott Michel97872d32008-02-23 18:41:37 +00002752 break;
2753 }
2754 case ISD::SIGN_EXTEND:
2755 case ISD::ZERO_EXTEND:
2756 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002757 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002758 // (any_extend (SPUextract_elt0 <arg>)) ->
2759 // (SPUextract_elt0 <arg>)
2760 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002761#if !defined(NDEBUG)
2762 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002763 cerr << "\nReplace: ";
2764 N->dump(&DAG);
2765 cerr << "\nWith: ";
2766 Op0.getNode()->dump(&DAG);
2767 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002768 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002769#endif
Scott Michel97872d32008-02-23 18:41:37 +00002770
2771 return Op0;
2772 }
2773 break;
2774 }
2775 case SPUISD::IndirectAddr: {
2776 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2777 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002778 if (CN->getZExtValue() == 0) {
Scott Michel97872d32008-02-23 18:41:37 +00002779 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2780 // (SPUaform <addr>, 0)
2781
2782 DEBUG(cerr << "Replace: ");
2783 DEBUG(N->dump(&DAG));
2784 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002785 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002786 DEBUG(cerr << "\n");
2787
2788 return Op0;
2789 }
Scott Michel06eabde2008-12-27 04:51:36 +00002790 } else if (Op0.getOpcode() == ISD::ADD) {
2791 SDValue Op1 = N->getOperand(1);
2792 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2793 // (SPUindirect (add <arg>, <arg>), 0) ->
2794 // (SPUindirect <arg>, <arg>)
2795 if (CN1->isNullValue()) {
2796
2797#if !defined(NDEBUG)
2798 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2799 cerr << "\n"
2800 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2801 << "With: (SPUindirect <arg>, <arg>)\n";
2802 }
2803#endif
2804
2805 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2806 Op0.getOperand(0), Op0.getOperand(1));
2807 }
2808 }
Scott Michel97872d32008-02-23 18:41:37 +00002809 }
2810 break;
2811 }
2812 case SPUISD::SHLQUAD_L_BITS:
2813 case SPUISD::SHLQUAD_L_BYTES:
2814 case SPUISD::VEC_SHL:
2815 case SPUISD::VEC_SRL:
2816 case SPUISD::VEC_SRA:
Scott Michel06eabde2008-12-27 04:51:36 +00002817 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002818 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002819
Scott Michel06eabde2008-12-27 04:51:36 +00002820 // Kill degenerate vector shifts:
2821 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2822 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002823 Result = Op0;
2824 }
2825 }
2826 break;
2827 }
Scott Michel06eabde2008-12-27 04:51:36 +00002828 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-02-23 18:41:37 +00002829 switch (Op0.getOpcode()) {
2830 default:
2831 break;
2832 case ISD::ANY_EXTEND:
2833 case ISD::ZERO_EXTEND:
2834 case ISD::SIGN_EXTEND: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002835 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002836 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002837 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002838 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002839 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002840 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002841 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002842 Result = Op000;
2843 }
2844 }
2845 break;
2846 }
Scott Michelc630c412008-11-24 17:11:17 +00002847 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002848 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002849 // <arg>
2850 Result = Op0.getOperand(0);
2851 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002852 }
Scott Michel97872d32008-02-23 18:41:37 +00002853 }
2854 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002855 }
2856 }
Scott Michel394e26d2008-01-17 20:38:41 +00002857 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002858#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002859 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002860 DEBUG(cerr << "\nReplace.SPU: ");
2861 DEBUG(N->dump(&DAG));
2862 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002863 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002864 DEBUG(cerr << "\n");
2865 }
2866#endif
2867
2868 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002869}
2870
2871//===----------------------------------------------------------------------===//
2872// Inline Assembly Support
2873//===----------------------------------------------------------------------===//
2874
2875/// getConstraintType - Given a constraint letter, return the type of
2876/// constraint it is for this target.
Scott Michel4ec722e2008-07-16 17:17:29 +00002877SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-12-04 22:23:35 +00002878SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2879 if (ConstraintLetter.size() == 1) {
2880 switch (ConstraintLetter[0]) {
2881 default: break;
2882 case 'b':
2883 case 'r':
2884 case 'f':
2885 case 'v':
2886 case 'y':
2887 return C_RegisterClass;
Scott Michel4ec722e2008-07-16 17:17:29 +00002888 }
Scott Michel8efdca42007-12-04 22:23:35 +00002889 }
2890 return TargetLowering::getConstraintType(ConstraintLetter);
2891}
2892
Scott Michel4ec722e2008-07-16 17:17:29 +00002893std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002894SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002895 MVT VT) const
Scott Michel8efdca42007-12-04 22:23:35 +00002896{
2897 if (Constraint.size() == 1) {
2898 // GCC RS6000 Constraint Letters
2899 switch (Constraint[0]) {
2900 case 'b': // R1-R31
2901 case 'r': // R0-R31
2902 if (VT == MVT::i64)
2903 return std::make_pair(0U, SPU::R64CRegisterClass);
2904 return std::make_pair(0U, SPU::R32CRegisterClass);
2905 case 'f':
2906 if (VT == MVT::f32)
2907 return std::make_pair(0U, SPU::R32FPRegisterClass);
2908 else if (VT == MVT::f64)
2909 return std::make_pair(0U, SPU::R64FPRegisterClass);
2910 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002911 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00002912 return std::make_pair(0U, SPU::GPRCRegisterClass);
2913 }
2914 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002915
Scott Michel8efdca42007-12-04 22:23:35 +00002916 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2917}
2918
Scott Michel97872d32008-02-23 18:41:37 +00002919//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002920void
Dan Gohman8181bd12008-07-27 21:46:04 +00002921SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002922 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00002923 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00002924 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002925 const SelectionDAG &DAG,
2926 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00002927#if 0
Scott Michel97872d32008-02-23 18:41:37 +00002928 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michelbc5fbc12008-04-30 00:30:08 +00002929#endif
Scott Michel97872d32008-02-23 18:41:37 +00002930
2931 switch (Op.getOpcode()) {
2932 default:
2933 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2934 break;
2935
2936#if 0
2937 case CALL:
2938 case SHUFB:
Scott Michel56a125e2008-11-22 23:50:42 +00002939 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00002940 case CNTB:
2941#endif
2942
Scott Michel06eabde2008-12-27 04:51:36 +00002943 case SPUISD::PREFSLOT2VEC: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002944 SDValue Op0 = Op.getOperand(0);
Duncan Sands92c43912008-06-06 12:08:01 +00002945 MVT Op0VT = Op0.getValueType();
2946 unsigned Op0VTBits = Op0VT.getSizeInBits();
2947 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002948 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2949 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002950 break;
2951 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002952
Scott Michel97872d32008-02-23 18:41:37 +00002953 case SPUISD::LDRESULT:
Scott Michel6ccefab2008-12-04 03:02:42 +00002954 case SPUISD::VEC2PREFSLOT: {
Duncan Sands92c43912008-06-06 12:08:01 +00002955 MVT OpVT = Op.getValueType();
2956 unsigned OpVTBits = OpVT.getSizeInBits();
2957 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002958 KnownZero |= APInt(OpVTBits, ~InMask, false);
2959 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002960 break;
2961 }
2962
2963#if 0
Scott Michelbc5fbc12008-04-30 00:30:08 +00002964 case SPUISD::SHLQUAD_L_BITS:
2965 case SPUISD::SHLQUAD_L_BYTES:
2966 case SPUISD::VEC_SHL:
2967 case SPUISD::VEC_SRL:
2968 case SPUISD::VEC_SRA:
2969 case SPUISD::VEC_ROTL:
2970 case SPUISD::VEC_ROTR:
Scott Michelbc5fbc12008-04-30 00:30:08 +00002971 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00002972 case SPUISD::SELECT_MASK:
2973 case SPUISD::SELB:
Scott Michel67224b22008-06-02 22:18:03 +00002974 case SPUISD::SEXT32TO64:
Scott Michel97872d32008-02-23 18:41:37 +00002975#endif
2976 }
Scott Michel8efdca42007-12-04 22:23:35 +00002977}
Scott Michel4d07fb72008-12-30 23:28:25 +00002978
Scott Michel06eabde2008-12-27 04:51:36 +00002979unsigned
2980SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2981 unsigned Depth) const {
2982 switch (Op.getOpcode()) {
2983 default:
2984 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00002985
Scott Michel06eabde2008-12-27 04:51:36 +00002986 case ISD::SETCC: {
2987 MVT VT = Op.getValueType();
2988
2989 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2990 VT = MVT::i32;
2991 }
2992 return VT.getSizeInBits();
2993 }
2994 }
2995}
Scott Michelae5cbf52008-12-29 03:23:36 +00002996
Scott Michelbc5fbc12008-04-30 00:30:08 +00002997// LowerAsmOperandForConstraint
2998void
Dan Gohman8181bd12008-07-27 21:46:04 +00002999SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00003000 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00003001 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00003002 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00003003 SelectionDAG &DAG) const {
3004 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00003005 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
3006 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00003007}
3008
Scott Michel8efdca42007-12-04 22:23:35 +00003009/// isLegalAddressImmediate - Return true if the integer value can be used
3010/// as the offset of the target addressing mode.
Gabor Greife9f7f582008-08-31 15:37:04 +00003011bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3012 const Type *Ty) const {
Scott Michel8efdca42007-12-04 22:23:35 +00003013 // SPU's addresses are 256K:
3014 return (V > -(1 << 18) && V < (1 << 18) - 1);
3015}
3016
3017bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel4ec722e2008-07-16 17:17:29 +00003018 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00003019}
Dan Gohman36322c72008-10-18 02:06:02 +00003020
3021bool
3022SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
3023 // The SPU target isn't yet aware of offsets.
3024 return false;
3025}