blob: 92bd92886c3d2a809de0a8017755df8b6b8f471e [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 Michel750b93f2009-01-15 04:41:47 +000081
Scott Michel8efdca42007-12-04 22:23:35 +000082}
83
84SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
85 : TargetLowering(TM),
86 SPUTM(TM)
87{
88 // Fold away setcc operations if possible.
89 setPow2DivIsCheap();
90
91 // Use _setjmp/_longjmp instead of setjmp/longjmp.
92 setUseUnderscoreSetJmp(true);
93 setUseUnderscoreLongJmp(true);
Scott Michel4ec722e2008-07-16 17:17:29 +000094
Scott Michel8efdca42007-12-04 22:23:35 +000095 // Set up the SPU's register classes:
Scott Michel438be252007-12-17 22:32:34 +000096 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
97 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
98 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
99 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
100 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
101 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel8efdca42007-12-04 22:23:35 +0000102 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel4ec722e2008-07-16 17:17:29 +0000103
Scott Michel8efdca42007-12-04 22:23:35 +0000104 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng08c171a2008-10-14 21:26:46 +0000105 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
106 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
107 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +0000108
Scott Michel06eabde2008-12-27 04:51:36 +0000109 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
110 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelec8c82e2008-12-02 19:53:53 +0000111
Scott Michel8efdca42007-12-04 22:23:35 +0000112 // SPU constant load actions are custom lowered:
113 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begeman78125042008-02-14 18:43:04 +0000114 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000115 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
116
117 // SPU's loads and stores have to be custom lowered:
Scott Michel2ef773a2009-01-06 03:36:14 +0000118 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel8efdca42007-12-04 22:23:35 +0000119 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000120 MVT VT = (MVT::SimpleValueType)sctype;
121
Scott Michel06eabde2008-12-27 04:51:36 +0000122 setOperationAction(ISD::LOAD, VT, Custom);
123 setOperationAction(ISD::STORE, VT, Custom);
124 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
125 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
126 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
127
Scott Michelae5cbf52008-12-29 03:23:36 +0000128 // SMUL_LOHI, UMUL_LOHI are not legal for Cell:
129 setOperationAction(ISD::SMUL_LOHI, VT, Expand);
130 setOperationAction(ISD::UMUL_LOHI, VT, Expand);
131
Scott Michel06eabde2008-12-27 04:51:36 +0000132 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
133 MVT StoreVT = (MVT::SimpleValueType) stype;
134 setTruncStoreAction(VT, StoreVT, Expand);
135 }
Scott Michel8efdca42007-12-04 22:23:35 +0000136 }
137
Scott Michel06eabde2008-12-27 04:51:36 +0000138 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
139 ++sctype) {
140 MVT VT = (MVT::SimpleValueType) sctype;
141
142 setOperationAction(ISD::LOAD, VT, Custom);
143 setOperationAction(ISD::STORE, VT, Custom);
144
145 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
146 MVT StoreVT = (MVT::SimpleValueType) stype;
147 setTruncStoreAction(VT, StoreVT, Expand);
148 }
149 }
150
Scott Michel8efdca42007-12-04 22:23:35 +0000151 // Expand the jumptable branches
152 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
153 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel56a125e2008-11-22 23:50:42 +0000154
155 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel4ec722e2008-07-16 17:17:29 +0000156 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel56a125e2008-11-22 23:50:42 +0000157 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
158 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
159 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
160 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000161
162 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000163 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
164
Scott Michel06eabde2008-12-27 04:51:36 +0000165 // SPU has no SREM/UREM instructions
Scott Michel8efdca42007-12-04 22:23:35 +0000166 setOperationAction(ISD::SREM, MVT::i32, Expand);
167 setOperationAction(ISD::UREM, MVT::i32, Expand);
168 setOperationAction(ISD::SREM, MVT::i64, Expand);
169 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000170
Scott Michel8efdca42007-12-04 22:23:35 +0000171 // We don't support sin/cos/sqrt/fmod
172 setOperationAction(ISD::FSIN , MVT::f64, Expand);
173 setOperationAction(ISD::FCOS , MVT::f64, Expand);
174 setOperationAction(ISD::FREM , MVT::f64, Expand);
175 setOperationAction(ISD::FSIN , MVT::f32, Expand);
176 setOperationAction(ISD::FCOS , MVT::f32, Expand);
177 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000178
Scott Michel8efdca42007-12-04 22:23:35 +0000179 // If we're enabling GP optimizations, use hardware square root
180 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
181 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000182
Scott Michel8efdca42007-12-04 22:23:35 +0000183 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
184 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
185
186 // SPU can do rotate right and left, so legalize it... but customize for i8
187 // because instructions don't exist.
Bill Wendling965299c2008-08-31 02:59:23 +0000188
189 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
190 // .td files.
191 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
192 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
193 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
194
Scott Michel8efdca42007-12-04 22:23:35 +0000195 setOperationAction(ISD::ROTL, MVT::i32, Legal);
196 setOperationAction(ISD::ROTL, MVT::i16, Legal);
197 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Michelabb8ca12008-11-20 16:36:33 +0000198
Scott Michel8efdca42007-12-04 22:23:35 +0000199 // SPU has no native version of shift left/right for i8
200 setOperationAction(ISD::SHL, MVT::i8, Custom);
201 setOperationAction(ISD::SRL, MVT::i8, Custom);
202 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel33d73eb2008-11-21 02:56:16 +0000203
Scott Michel4d07fb72008-12-30 23:28:25 +0000204 // Make these operations legal and handle them during instruction selection:
205 setOperationAction(ISD::SHL, MVT::i64, Legal);
206 setOperationAction(ISD::SRL, MVT::i64, Legal);
207 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000208
Scott Michel4ec722e2008-07-16 17:17:29 +0000209 // Custom lower i8, i32 and i64 multiplications
210 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelae5cbf52008-12-29 03:23:36 +0000211 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel750b93f2009-01-15 04:41:47 +0000212 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel33d73eb2008-11-21 02:56:16 +0000213
Scott Michel67224b22008-06-02 22:18:03 +0000214 // Need to custom handle (some) common i8, i64 math ops
Scott Michel4d07fb72008-12-30 23:28:25 +0000215 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000216 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000217 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000218 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000219
Scott Michel8efdca42007-12-04 22:23:35 +0000220 // SPU does not have BSWAP. It does have i32 support CTLZ.
221 // CTPOP has to be custom lowered.
222 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
223 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
224
225 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
226 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
227 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
228 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
229
230 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
231 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
232
233 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000234
Scott Michel67224b22008-06-02 22:18:03 +0000235 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel978b96f2008-03-10 23:49:09 +0000236 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000237 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000238 setOperationAction(ISD::SELECT, MVT::i16, Legal);
239 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel06eabde2008-12-27 04:51:36 +0000240 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000241
Scott Michel53ab7792008-03-10 16:58:52 +0000242 setOperationAction(ISD::SETCC, MVT::i8, Legal);
243 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000244 setOperationAction(ISD::SETCC, MVT::i32, Legal);
245 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000246
Scott Michel06eabde2008-12-27 04:51:36 +0000247 // Custom lower i128 -> i64 truncates
Scott Michelec8c82e2008-12-02 19:53:53 +0000248 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
249
Scott Michel8efdca42007-12-04 22:23:35 +0000250 // SPU has a legal FP -> signed INT instruction
251 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal);
252 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
253 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
254 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
255
256 // FDIV on SPU requires custom lowering
Scott Michel06eabde2008-12-27 04:51:36 +0000257 setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall
Scott Michel8efdca42007-12-04 22:23:35 +0000258
259 // SPU has [U|S]INT_TO_FP
260 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
261 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
262 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
263 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
264 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
265 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
266 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
267 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
268
Scott Michel754d8662007-12-20 00:44:13 +0000269 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
270 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
271 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
272 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000273
274 // We cannot sextinreg(i1). Expand to shifts.
275 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000276
Scott Michel8efdca42007-12-04 22:23:35 +0000277 // Support label based line numbers.
Dan Gohman472d12c2008-06-30 20:59:49 +0000278 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000279 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000280
281 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel8efdca42007-12-04 22:23:35 +0000282 // appropriate instructions to materialize the address.
Scott Michel33d73eb2008-11-21 02:56:16 +0000283 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelf9f42e62008-01-29 02:16:57 +0000284 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000285 MVT VT = (MVT::SimpleValueType)sctype;
286
Scott Michelae5cbf52008-12-29 03:23:36 +0000287 setOperationAction(ISD::GlobalAddress, VT, Custom);
288 setOperationAction(ISD::ConstantPool, VT, Custom);
289 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelf9f42e62008-01-29 02:16:57 +0000290 }
Scott Michel8efdca42007-12-04 22:23:35 +0000291
292 // RET must be custom lowered, to meet ABI requirements
293 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000294
Scott Michel8efdca42007-12-04 22:23:35 +0000295 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
296 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000297
Scott Michel8efdca42007-12-04 22:23:35 +0000298 // Use the default implementation.
299 setOperationAction(ISD::VAARG , MVT::Other, Expand);
300 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
301 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000302 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000303 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
304 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
305 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
306
307 // Cell SPU has instructions for converting between i64 and fp.
308 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
309 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000310
Scott Michel8efdca42007-12-04 22:23:35 +0000311 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
312 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
313
314 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
315 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
316
317 // First set operation action for all vector types to expand. Then we
318 // will selectively turn on ones that can be effectively codegen'd.
319 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
320 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
321 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
322 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
323 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
324 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
325
Scott Michel70741542009-01-06 23:10:38 +0000326 // "Odd size" vector classes that we're willing to support:
327 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
328
Duncan Sands92c43912008-06-06 12:08:01 +0000329 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
330 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
331 MVT VT = (MVT::SimpleValueType)i;
Scott Michel8efdca42007-12-04 22:23:35 +0000332
Duncan Sands92c43912008-06-06 12:08:01 +0000333 // add/sub are legal for all supported vector VT's.
334 setOperationAction(ISD::ADD , VT, Legal);
335 setOperationAction(ISD::SUB , VT, Legal);
336 // mul has to be custom lowered.
Scott Michel4d07fb72008-12-30 23:28:25 +0000337 // TODO: v2i64 vector multiply
338 setOperationAction(ISD::MUL , VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000339
340 setOperationAction(ISD::AND , VT, Legal);
341 setOperationAction(ISD::OR , VT, Legal);
342 setOperationAction(ISD::XOR , VT, Legal);
343 setOperationAction(ISD::LOAD , VT, Legal);
344 setOperationAction(ISD::SELECT, VT, Legal);
345 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000346
Scott Michel8efdca42007-12-04 22:23:35 +0000347 // These operations need to be expanded:
Duncan Sands92c43912008-06-06 12:08:01 +0000348 setOperationAction(ISD::SDIV, VT, Expand);
349 setOperationAction(ISD::SREM, VT, Expand);
350 setOperationAction(ISD::UDIV, VT, Expand);
351 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000352
353 // Custom lower build_vector, constant pool spills, insert and
354 // extract vector elements:
Duncan Sands92c43912008-06-06 12:08:01 +0000355 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
356 setOperationAction(ISD::ConstantPool, VT, Custom);
357 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
358 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
359 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
360 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000361 }
362
Scott Michel8efdca42007-12-04 22:23:35 +0000363 setOperationAction(ISD::AND, MVT::v16i8, Custom);
364 setOperationAction(ISD::OR, MVT::v16i8, Custom);
365 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
366 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000367
Scott Michel4d07fb72008-12-30 23:28:25 +0000368 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000369
Scott Michel8efdca42007-12-04 22:23:35 +0000370 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000371 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000372
Scott Michel8efdca42007-12-04 22:23:35 +0000373 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000374
Scott Michel8efdca42007-12-04 22:23:35 +0000375 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000376 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000377 setTargetDAGCombine(ISD::ZERO_EXTEND);
378 setTargetDAGCombine(ISD::SIGN_EXTEND);
379 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000380
Scott Michel8efdca42007-12-04 22:23:35 +0000381 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000382
Scott Michel2c261072008-12-09 03:37:19 +0000383 // Set pre-RA register scheduler default to BURR, which produces slightly
384 // better code than the default (could also be TDRR, but TargetLowering.h
385 // needs a mod to support that model):
386 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel8efdca42007-12-04 22:23:35 +0000387}
388
389const char *
390SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
391{
392 if (node_names.empty()) {
393 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
394 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
395 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
396 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Micheldbac4cf2008-01-11 02:53:15 +0000397 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000398 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-12-04 22:23:35 +0000399 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
400 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
401 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel56a125e2008-11-22 23:50:42 +0000402 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000403 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000404 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000405 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-02-23 18:41:37 +0000406 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
407 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel8efdca42007-12-04 22:23:35 +0000408 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
409 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
410 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
411 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
412 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michel67224b22008-06-02 22:18:03 +0000413 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000414 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel750b93f2009-01-15 04:41:47 +0000415 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
416 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
417 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel8efdca42007-12-04 22:23:35 +0000418 }
419
420 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
421
422 return ((i != node_names.end()) ? i->second : 0);
423}
424
Scott Michel06eabde2008-12-27 04:51:36 +0000425//===----------------------------------------------------------------------===//
426// Return the Cell SPU's SETCC result type
427//===----------------------------------------------------------------------===//
428
Duncan Sands4a361272009-01-01 15:52:00 +0000429MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-12-27 04:51:36 +0000430 // i16 and i32 are valid SETCC result types
431 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel53ab7792008-03-10 16:58:52 +0000432}
433
Scott Michel8efdca42007-12-04 22:23:35 +0000434//===----------------------------------------------------------------------===//
435// Calling convention code:
436//===----------------------------------------------------------------------===//
437
438#include "SPUGenCallingConv.inc"
439
440//===----------------------------------------------------------------------===//
441// LowerOperation implementation
442//===----------------------------------------------------------------------===//
443
444/// Custom lower loads for CellSPU
445/*!
446 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
447 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel6ccefab2008-12-04 03:02:42 +0000448
449 For extending loads, we also want to ensure that the following sequence is
450 emitted, e.g. for MVT::f32 extending load to MVT::f64:
451
452\verbatim
Scott Michelae5cbf52008-12-29 03:23:36 +0000453%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000454%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000455%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000456%4 f32 = vec2perfslot %3
457%5 f64 = fp_extend %4
458\endverbatim
459*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000460static SDValue
461LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000462 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000463 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000464 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000465 MVT InVT = LN->getMemoryVT();
466 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000467 ISD::LoadExtType ExtType = LN->getExtensionType();
468 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000469 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000470
Scott Michel8efdca42007-12-04 22:23:35 +0000471 switch (LN->getAddressingMode()) {
472 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000473 SDValue result;
474 SDValue basePtr = LN->getBasePtr();
475 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000476
Scott Michel06eabde2008-12-27 04:51:36 +0000477 if (alignment == 16) {
478 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000479
Scott Michel06eabde2008-12-27 04:51:36 +0000480 // Special cases for a known aligned load to simplify the base pointer
481 // and the rotation amount:
482 if (basePtr.getOpcode() == ISD::ADD
483 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
484 // Known offset into basePtr
485 int64_t offset = CN->getSExtValue();
486 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000487
Scott Michel06eabde2008-12-27 04:51:36 +0000488 if (rotamt < 0)
489 rotamt += 16;
490
491 rotate = DAG.getConstant(rotamt, MVT::i16);
492
493 // Simplify the base pointer for this case:
494 basePtr = basePtr.getOperand(0);
495 if ((offset & ~0xf) > 0) {
496 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
497 basePtr,
498 DAG.getConstant((offset & ~0xf), PtrVT));
499 }
500 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
501 || (basePtr.getOpcode() == SPUISD::IndirectAddr
502 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
503 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
504 // Plain aligned a-form address: rotate into preferred slot
505 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
506 int64_t rotamt = -vtm->prefslot_byte;
507 if (rotamt < 0)
508 rotamt += 16;
509 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000510 } else {
Scott Michel06eabde2008-12-27 04:51:36 +0000511 // Offset the rotate amount by the basePtr and the preferred slot
512 // byte offset
513 int64_t rotamt = -vtm->prefslot_byte;
514 if (rotamt < 0)
515 rotamt += 16;
516 rotate = DAG.getNode(ISD::ADD, PtrVT,
517 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000518 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000519 }
Scott Michel06eabde2008-12-27 04:51:36 +0000520 } else {
521 // Unaligned load: must be more pessimistic about addressing modes:
522 if (basePtr.getOpcode() == ISD::ADD) {
523 MachineFunction &MF = DAG.getMachineFunction();
524 MachineRegisterInfo &RegInfo = MF.getRegInfo();
525 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
526 SDValue Flag;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000527
Scott Michel06eabde2008-12-27 04:51:36 +0000528 SDValue Op0 = basePtr.getOperand(0);
529 SDValue Op1 = basePtr.getOperand(1);
530
531 if (isa<ConstantSDNode>(Op1)) {
532 // Convert the (add <ptr>, <const>) to an indirect address contained
533 // in a register. Note that this is done because we need to avoid
534 // creating a 0(reg) d-form address due to the SPU's block loads.
535 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
536 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
537 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
538 } else {
539 // Convert the (add <arg1>, <arg2>) to an indirect address, which
540 // will likely be lowered as a reg(reg) x-form address.
541 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
542 }
543 } else {
544 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
545 basePtr,
546 DAG.getConstant(0, PtrVT));
547 }
548
549 // Offset the rotate amount by the basePtr and the preferred slot
550 // byte offset
551 rotate = DAG.getNode(ISD::ADD, PtrVT,
552 basePtr,
553 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +0000554 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000555
Scott Michel06eabde2008-12-27 04:51:36 +0000556 // Re-emit as a v16i8 vector load
557 result = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
558 LN->getSrcValue(), LN->getSrcValueOffset(),
559 LN->isVolatile(), 16);
560
561 // Update the chain
562 the_chain = result.getValue(1);
563
564 // Rotate into the preferred slot:
565 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8,
566 result.getValue(0), rotate);
567
Scott Michel6ccefab2008-12-04 03:02:42 +0000568 // Convert the loaded v16i8 vector to the appropriate vector type
569 // specified by the operand:
570 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
571 result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
572 DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
Scott Michel4ec722e2008-07-16 17:17:29 +0000573
Scott Michel6ccefab2008-12-04 03:02:42 +0000574 // Handle extending loads by extending the scalar result:
575 if (ExtType == ISD::SEXTLOAD) {
576 result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result);
577 } else if (ExtType == ISD::ZEXTLOAD) {
578 result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result);
579 } else if (ExtType == ISD::EXTLOAD) {
580 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000581
Scott Michel6ccefab2008-12-04 03:02:42 +0000582 if (OutVT.isFloatingPoint())
583 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000584
Scott Michel6ccefab2008-12-04 03:02:42 +0000585 result = DAG.getNode(NewOpc, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000586 }
587
Scott Michel6ccefab2008-12-04 03:02:42 +0000588 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000589 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000590 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000591 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000592 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000593
Scott Michel394e26d2008-01-17 20:38:41 +0000594 result = DAG.getNode(SPUISD::LDRESULT, retvts,
595 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000596 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000597 }
598 case ISD::PRE_INC:
599 case ISD::PRE_DEC:
600 case ISD::POST_INC:
601 case ISD::POST_DEC:
602 case ISD::LAST_INDEXED_MODE:
603 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
604 "UNINDEXED\n";
605 cerr << (unsigned) LN->getAddressingMode() << "\n";
606 abort();
607 /*NOTREACHED*/
608 }
609
Dan Gohman8181bd12008-07-27 21:46:04 +0000610 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000611}
612
613/// Custom lower stores for CellSPU
614/*!
615 All CellSPU stores are aligned to 16-byte boundaries, so for elements
616 within a 16-byte block, we have to generate a shuffle to insert the
617 requested element into its place, then store the resulting block.
618 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000619static SDValue
620LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000621 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000622 SDValue Value = SN->getValue();
Duncan Sands92c43912008-06-06 12:08:01 +0000623 MVT VT = Value.getValueType();
624 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
625 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000626 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000627
628 switch (SN->getAddressingMode()) {
629 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000630 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000631 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
632 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000633
Scott Michel06eabde2008-12-27 04:51:36 +0000634 SDValue alignLoadVec;
635 SDValue basePtr = SN->getBasePtr();
636 SDValue the_chain = SN->getChain();
637 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000638
Scott Michel06eabde2008-12-27 04:51:36 +0000639 if (alignment == 16) {
640 ConstantSDNode *CN;
641
642 // Special cases for a known aligned load to simplify the base pointer
643 // and insertion byte:
644 if (basePtr.getOpcode() == ISD::ADD
645 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
646 // Known offset into basePtr
647 int64_t offset = CN->getSExtValue();
648
649 // Simplify the base pointer for this case:
650 basePtr = basePtr.getOperand(0);
651 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
652 basePtr,
653 DAG.getConstant((offset & 0xf), PtrVT));
654
655 if ((offset & ~0xf) > 0) {
656 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
657 basePtr,
658 DAG.getConstant((offset & ~0xf), PtrVT));
659 }
660 } else {
661 // Otherwise, assume it's at byte 0 of basePtr
662 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
663 basePtr,
664 DAG.getConstant(0, PtrVT));
665 }
666 } else {
667 // Unaligned load: must be more pessimistic about addressing modes:
668 if (basePtr.getOpcode() == ISD::ADD) {
669 MachineFunction &MF = DAG.getMachineFunction();
670 MachineRegisterInfo &RegInfo = MF.getRegInfo();
671 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
672 SDValue Flag;
673
674 SDValue Op0 = basePtr.getOperand(0);
675 SDValue Op1 = basePtr.getOperand(1);
676
677 if (isa<ConstantSDNode>(Op1)) {
678 // Convert the (add <ptr>, <const>) to an indirect address contained
679 // in a register. Note that this is done because we need to avoid
680 // creating a 0(reg) d-form address due to the SPU's block loads.
681 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
682 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
683 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
684 } else {
685 // Convert the (add <arg1>, <arg2>) to an indirect address, which
686 // will likely be lowered as a reg(reg) x-form address.
687 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
688 }
689 } else {
690 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
691 basePtr,
692 DAG.getConstant(0, PtrVT));
693 }
694
695 // Insertion point is solely determined by basePtr's contents
696 insertEltOffs = DAG.getNode(ISD::ADD, PtrVT,
697 basePtr,
698 DAG.getConstant(0, PtrVT));
699 }
700
701 // Re-emit as a v16i8 vector load
702 alignLoadVec = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
703 SN->getSrcValue(), SN->getSrcValueOffset(),
704 SN->isVolatile(), 16);
705
706 // Update the chain
707 the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000708
Scott Micheldbac4cf2008-01-11 02:53:15 +0000709 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000710 SDValue theValue = SN->getValue();
711 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000712
713 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000714 && (theValue.getOpcode() == ISD::AssertZext
715 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000716 // Drill down and get the value for zero- and sign-extended
717 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000718 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000719 }
720
Scott Micheldbac4cf2008-01-11 02:53:15 +0000721 // If the base pointer is already a D-form address, then just create
722 // a new D-form address with a slot offset and the orignal base pointer.
723 // Otherwise generate a D-form address with the slot offset relative
724 // to the stack pointer, which is always aligned.
Scott Michel06eabde2008-12-27 04:51:36 +0000725#if !defined(NDEBUG)
726 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
727 cerr << "CellSPU LowerSTORE: basePtr = ";
728 basePtr.getNode()->dump(&DAG);
729 cerr << "\n";
730 }
731#endif
Scott Micheldbac4cf2008-01-11 02:53:15 +0000732
Scott Michelf65c8f02008-11-19 15:24:16 +0000733 SDValue insertEltOp =
Scott Michel06eabde2008-12-27 04:51:36 +0000734 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000735 SDValue vectorizeOp =
736 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000737
Scott Michel0718cd82008-12-01 17:56:02 +0000738 result = DAG.getNode(SPUISD::SHUFB, vecVT,
739 vectorizeOp, alignLoadVec,
740 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000741
Scott Micheldbac4cf2008-01-11 02:53:15 +0000742 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000743 LN->getSrcValue(), LN->getSrcValueOffset(),
744 LN->isVolatile(), LN->getAlignment());
745
Scott Michel8c2746e2008-12-04 17:16:59 +0000746#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-11-19 15:24:16 +0000747 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
748 const SDValue &currentRoot = DAG.getRoot();
749
750 DAG.setRoot(result);
751 cerr << "------- CellSPU:LowerStore result:\n";
752 DAG.dump();
753 cerr << "-------\n";
754 DAG.setRoot(currentRoot);
755 }
756#endif
Scott Michelec8c82e2008-12-02 19:53:53 +0000757
Scott Michel8efdca42007-12-04 22:23:35 +0000758 return result;
759 /*UNREACHED*/
760 }
761 case ISD::PRE_INC:
762 case ISD::PRE_DEC:
763 case ISD::POST_INC:
764 case ISD::POST_DEC:
765 case ISD::LAST_INDEXED_MODE:
766 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
767 "UNINDEXED\n";
768 cerr << (unsigned) SN->getAddressingMode() << "\n";
769 abort();
770 /*NOTREACHED*/
771 }
772
Dan Gohman8181bd12008-07-27 21:46:04 +0000773 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000774}
775
Scott Michel750b93f2009-01-15 04:41:47 +0000776//! Generate the address of a constant pool entry.
777SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000778LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000779 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000780 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
781 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000782 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
783 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000784 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000785
786 if (TM.getRelocationModel() == Reloc::Static) {
787 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000788 // Just return the SDValue with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000789 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000790 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000791 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
792 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000793 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000794 }
795 }
796
797 assert(0 &&
Gabor Greife9f7f582008-08-31 15:37:04 +0000798 "LowerConstantPool: Relocation model other than static"
799 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000800 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000801}
802
Scott Michel750b93f2009-01-15 04:41:47 +0000803//! Alternate entry point for generating the address of a constant pool entry
804SDValue
805SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
806 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
807}
808
Dan Gohman8181bd12008-07-27 21:46:04 +0000809static SDValue
810LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000811 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000812 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000813 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
814 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000815 const TargetMachine &TM = DAG.getTarget();
816
817 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000818 if (!ST->usingLargeMem()) {
819 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
820 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000821 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
822 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000823 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
824 }
Scott Michel8efdca42007-12-04 22:23:35 +0000825 }
826
827 assert(0 &&
828 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000829 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000830}
831
Dan Gohman8181bd12008-07-27 21:46:04 +0000832static SDValue
833LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000834 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000835 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
836 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000837 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000838 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000839 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel4ec722e2008-07-16 17:17:29 +0000840
Scott Michel8efdca42007-12-04 22:23:35 +0000841 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000842 if (!ST->usingLargeMem()) {
843 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
844 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000845 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
846 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
Scott Michelf9f42e62008-01-29 02:16:57 +0000847 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
848 }
Scott Michel8efdca42007-12-04 22:23:35 +0000849 } else {
850 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000851 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000852 abort();
853 /*NOTREACHED*/
854 }
855
Dan Gohman8181bd12008-07-27 21:46:04 +0000856 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000857}
858
859//! Custom lower i64 integer constants
860/*!
861 This code inserts all of the necessary juggling that needs to occur to load
862 a 64-bit constant into a register.
863 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000864static SDValue
865LowerConstant(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000866 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000867
868 if (VT == MVT::i64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000869 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
870 SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michelc630c412008-11-24 17:11:17 +0000871 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000872 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +0000873 } else {
874 cerr << "LowerConstant: unhandled constant type "
Duncan Sands92c43912008-06-06 12:08:01 +0000875 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +0000876 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000877 abort();
878 /*NOTREACHED*/
879 }
880
Dan Gohman8181bd12008-07-27 21:46:04 +0000881 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000882}
883
Nate Begeman78125042008-02-14 18:43:04 +0000884//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000885static SDValue
886LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000887 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000888
Nate Begeman78125042008-02-14 18:43:04 +0000889 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000890 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
891
892 assert((FP != 0) &&
893 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000894
Scott Michel11e88bb2007-12-19 20:15:47 +0000895 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-12-01 17:56:02 +0000896 SDValue T = DAG.getConstant(dbits, MVT::i64);
897 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T);
898 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
899 DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec));
Scott Michel8efdca42007-12-04 22:23:35 +0000900 }
901
Dan Gohman8181bd12008-07-27 21:46:04 +0000902 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000903}
904
Dan Gohman8181bd12008-07-27 21:46:04 +0000905static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000906LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000907{
908 MachineFunction &MF = DAG.getMachineFunction();
909 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000910 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000911 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000912 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000913 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel8efdca42007-12-04 22:23:35 +0000914
915 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
916 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000917
Scott Michel8efdca42007-12-04 22:23:35 +0000918 unsigned ArgOffset = SPUFrameInfo::minStackSize();
919 unsigned ArgRegIdx = 0;
920 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000921
Duncan Sands92c43912008-06-06 12:08:01 +0000922 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000923
Scott Michel8efdca42007-12-04 22:23:35 +0000924 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000925 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
926 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000927 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
928 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000929 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000930
Scott Michela313fb02008-10-30 01:51:48 +0000931 if (ArgRegIdx < NumArgRegs) {
932 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000933
Scott Michela313fb02008-10-30 01:51:48 +0000934 switch (ObjectVT.getSimpleVT()) {
935 default: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000936 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
937 << ObjectVT.getMVTString()
938 << "\n";
939 abort();
Scott Michela313fb02008-10-30 01:51:48 +0000940 }
941 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000942 ArgRegClass = &SPU::R8CRegClass;
943 break;
Scott Michela313fb02008-10-30 01:51:48 +0000944 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +0000945 ArgRegClass = &SPU::R16CRegClass;
946 break;
Scott Michela313fb02008-10-30 01:51:48 +0000947 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000948 ArgRegClass = &SPU::R32CRegClass;
949 break;
Scott Michela313fb02008-10-30 01:51:48 +0000950 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000951 ArgRegClass = &SPU::R64CRegClass;
952 break;
Scott Michel2ef773a2009-01-06 03:36:14 +0000953 case MVT::i128:
954 ArgRegClass = &SPU::GPRCRegClass;
955 break;
Scott Michela313fb02008-10-30 01:51:48 +0000956 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000957 ArgRegClass = &SPU::R32FPRegClass;
958 break;
Scott Michela313fb02008-10-30 01:51:48 +0000959 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000960 ArgRegClass = &SPU::R64FPRegClass;
961 break;
Scott Michela313fb02008-10-30 01:51:48 +0000962 case MVT::v2f64:
963 case MVT::v4f32:
964 case MVT::v2i64:
965 case MVT::v4i32:
966 case MVT::v8i16:
967 case MVT::v16i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000968 ArgRegClass = &SPU::VECREGRegClass;
969 break;
Scott Michela313fb02008-10-30 01:51:48 +0000970 }
971
972 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
973 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
974 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
975 ++ArgRegIdx;
976 } else {
977 // We need to load the argument to a virtual register if we determined
978 // above that we ran out of physical registers of the appropriate type
979 // or we're forced to do vararg
Chris Lattner60069452008-02-13 07:35:30 +0000980 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +0000981 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner60069452008-02-13 07:35:30 +0000982 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +0000983 ArgOffset += StackSlotSize;
984 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000985
Scott Michel8efdca42007-12-04 22:23:35 +0000986 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +0000987 // Update the chain
988 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000989 }
Scott Michel4ec722e2008-07-16 17:17:29 +0000990
Scott Michela313fb02008-10-30 01:51:48 +0000991 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +0000992 if (isVarArg) {
Scott Michela313fb02008-10-30 01:51:48 +0000993 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
994 // We will spill (79-3)+1 registers to the stack
995 SmallVector<SDValue, 79-3+1> MemOps;
996
997 // Create the frame slot
998
Scott Michel8efdca42007-12-04 22:23:35 +0000999 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-10-30 01:51:48 +00001000 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1001 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1002 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
1003 SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
1004 Root = Store.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001005 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001006
1007 // Increment address by stack slot size for the next stored argument
1008 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001009 }
1010 if (!MemOps.empty())
Scott Michela313fb02008-10-30 01:51:48 +00001011 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001012 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001013
Scott Michel8efdca42007-12-04 22:23:35 +00001014 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001015
Scott Michel8efdca42007-12-04 22:23:35 +00001016 // Return the new list of results.
Duncan Sands42d7bb82008-12-01 11:41:29 +00001017 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1018 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001019}
1020
1021/// isLSAAddress - Return the immediate to use if the specified
1022/// value is representable as a LSA address.
Dan Gohman8181bd12008-07-27 21:46:04 +00001023static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001024 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001025 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001026
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001027 int Addr = C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001028 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1029 (Addr << 14 >> 14) != Addr)
1030 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel4ec722e2008-07-16 17:17:29 +00001031
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001032 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001033}
1034
Scott Michel70741542009-01-06 23:10:38 +00001035static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +00001036LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001037 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1038 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001039 SDValue Callee = TheCall->getCallee();
1040 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-12-04 22:23:35 +00001041 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1042 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1043 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1044
1045 // Handy pointer type
Duncan Sands92c43912008-06-06 12:08:01 +00001046 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001047
Scott Michel8efdca42007-12-04 22:23:35 +00001048 // Accumulate how many bytes are to be pushed on the stack, including the
1049 // linkage area, and parameter passing area. According to the SPU ABI,
1050 // we minimally need space for [LR] and [SP]
1051 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel4ec722e2008-07-16 17:17:29 +00001052
Scott Michel8efdca42007-12-04 22:23:35 +00001053 // Set up a copy of the stack pointer for use loading and storing any
1054 // arguments that may not fit in the registers available for argument
1055 // passing.
Dan Gohman8181bd12008-07-27 21:46:04 +00001056 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001057
Scott Michel8efdca42007-12-04 22:23:35 +00001058 // Figure out which arguments are going to go in registers, and which in
1059 // memory.
1060 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1061 unsigned ArgRegIdx = 0;
1062
1063 // Keep track of registers passing arguments
Dan Gohman8181bd12008-07-27 21:46:04 +00001064 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001065 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001066 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001067
1068 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001069 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001070
Scott Michel8efdca42007-12-04 22:23:35 +00001071 // PtrOff will be used to store the current argument to the stack if a
1072 // register cannot be found for it.
Dan Gohman8181bd12008-07-27 21:46:04 +00001073 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel8efdca42007-12-04 22:23:35 +00001074 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1075
Duncan Sands92c43912008-06-06 12:08:01 +00001076 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001077 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001078 case MVT::i8:
1079 case MVT::i16:
Scott Michel8efdca42007-12-04 22:23:35 +00001080 case MVT::i32:
1081 case MVT::i64:
1082 case MVT::i128:
1083 if (ArgRegIdx != NumArgRegs) {
1084 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1085 } else {
1086 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001087 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001088 }
1089 break;
1090 case MVT::f32:
1091 case MVT::f64:
1092 if (ArgRegIdx != NumArgRegs) {
1093 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1094 } else {
1095 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001096 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001097 }
1098 break;
Scott Michele2641a12008-12-04 21:01:44 +00001099 case MVT::v2i64:
1100 case MVT::v2f64:
Scott Michel8efdca42007-12-04 22:23:35 +00001101 case MVT::v4f32:
1102 case MVT::v4i32:
1103 case MVT::v8i16:
1104 case MVT::v16i8:
1105 if (ArgRegIdx != NumArgRegs) {
1106 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1107 } else {
1108 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001109 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001110 }
1111 break;
1112 }
1113 }
1114
1115 // Update number of stack bytes actually used, insert a call sequence start
1116 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001117 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1118 true));
Scott Michel8efdca42007-12-04 22:23:35 +00001119
1120 if (!MemOpChains.empty()) {
1121 // Adjust the stack pointer for the stack arguments.
1122 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1123 &MemOpChains[0], MemOpChains.size());
1124 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001125
Scott Michel8efdca42007-12-04 22:23:35 +00001126 // Build a sequence of copy-to-reg nodes chained together with token chain
1127 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman8181bd12008-07-27 21:46:04 +00001128 SDValue InFlag;
Scott Michel8efdca42007-12-04 22:23:35 +00001129 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1130 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1131 InFlag);
1132 InFlag = Chain.getValue(1);
1133 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001134
Dan Gohman8181bd12008-07-27 21:46:04 +00001135 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001136 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001137
Bill Wendlingfef06052008-09-16 21:48:12 +00001138 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1139 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1140 // node so that legalize doesn't hack it.
Scott Michel5974f432008-11-11 03:06:06 +00001141 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001142 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001143 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001144 SDValue Zero = DAG.getConstant(0, PtrVT);
1145 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001146
Scott Micheldbac4cf2008-01-11 02:53:15 +00001147 if (!ST->usingLargeMem()) {
1148 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1149 // style calls, otherwise, external symbols are BRASL calls. This assumes
1150 // that declared/defined symbols are in the same compilation unit and can
1151 // be reached through PC-relative jumps.
1152 //
1153 // NOTE:
1154 // This may be an unsafe assumption for JIT and really large compilation
1155 // units.
1156 if (GV->isDeclaration()) {
1157 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1158 } else {
1159 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1160 }
Scott Michel8efdca42007-12-04 22:23:35 +00001161 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001162 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1163 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001164 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001165 }
Scott Michelae5cbf52008-12-29 03:23:36 +00001166 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1167 MVT CalleeVT = Callee.getValueType();
1168 SDValue Zero = DAG.getConstant(0, PtrVT);
1169 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1170 Callee.getValueType());
1171
1172 if (!ST->usingLargeMem()) {
1173 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, ExtSym, Zero);
1174 } else {
1175 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, ExtSym, Zero);
1176 }
1177 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001178 // If this is an absolute destination address that appears to be a legal
1179 // local store address, use the munged value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001180 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001181 }
Scott Michel8efdca42007-12-04 22:23:35 +00001182
1183 Ops.push_back(Chain);
1184 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001185
Scott Michel8efdca42007-12-04 22:23:35 +00001186 // Add argument registers to the end of the list so that they are known live
1187 // into the call.
1188 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel4ec722e2008-07-16 17:17:29 +00001189 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001190 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001191
Gabor Greif1c80d112008-08-28 21:40:38 +00001192 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001193 Ops.push_back(InFlag);
Duncan Sands698842f2008-07-02 17:40:58 +00001194 // Returns a chain and a flag for retval copy to use.
1195 Chain = DAG.getNode(CallOpc, DAG.getVTList(MVT::Other, MVT::Flag),
1196 &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001197 InFlag = Chain.getValue(1);
1198
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001199 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1200 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001201 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001202 InFlag = Chain.getValue(1);
1203
Dan Gohman8181bd12008-07-27 21:46:04 +00001204 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001205 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001206
Scott Michel8efdca42007-12-04 22:23:35 +00001207 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001208 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001209 default: assert(0 && "Unexpected ret value!");
1210 case MVT::Other: break;
1211 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001212 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001213 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1214 ResultVals[0] = Chain.getValue(0);
1215 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1216 Chain.getValue(2)).getValue(1);
1217 ResultVals[1] = Chain.getValue(0);
1218 NumResults = 2;
Scott Michel8efdca42007-12-04 22:23:35 +00001219 } else {
1220 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1221 ResultVals[0] = Chain.getValue(0);
1222 NumResults = 1;
1223 }
Scott Michel8efdca42007-12-04 22:23:35 +00001224 break;
1225 case MVT::i64:
1226 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1227 ResultVals[0] = Chain.getValue(0);
1228 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001229 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001230 case MVT::i128:
1231 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
1232 ResultVals[0] = Chain.getValue(0);
1233 NumResults = 1;
1234 break;
Scott Michel8efdca42007-12-04 22:23:35 +00001235 case MVT::f32:
1236 case MVT::f64:
Dan Gohman705e3f72008-09-13 01:54:27 +00001237 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001238 InFlag).getValue(1);
1239 ResultVals[0] = Chain.getValue(0);
1240 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001241 break;
1242 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001243 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001244 case MVT::v4f32:
1245 case MVT::v4i32:
1246 case MVT::v8i16:
1247 case MVT::v16i8:
Dan Gohman705e3f72008-09-13 01:54:27 +00001248 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001249 InFlag).getValue(1);
1250 ResultVals[0] = Chain.getValue(0);
1251 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001252 break;
1253 }
Duncan Sands698842f2008-07-02 17:40:58 +00001254
Scott Michel8efdca42007-12-04 22:23:35 +00001255 // If the function returns void, just return the chain.
1256 if (NumResults == 0)
1257 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001258
Scott Michel8efdca42007-12-04 22:23:35 +00001259 // Otherwise, merge everything together with a MERGE_VALUES node.
1260 ResultVals[NumResults++] = Chain;
Dan Gohman8181bd12008-07-27 21:46:04 +00001261 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif46bf5472008-08-26 22:36:50 +00001262 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001263}
1264
Dan Gohman8181bd12008-07-27 21:46:04 +00001265static SDValue
1266LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-12-04 22:23:35 +00001267 SmallVector<CCValAssign, 16> RVLocs;
1268 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1269 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1270 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greif1c80d112008-08-28 21:40:38 +00001271 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001272
Scott Michel8efdca42007-12-04 22:23:35 +00001273 // If this is the first return lowered for this function, add the regs to the
1274 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001275 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001276 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001277 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001278 }
1279
Dan Gohman8181bd12008-07-27 21:46:04 +00001280 SDValue Chain = Op.getOperand(0);
1281 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001282
Scott Michel8efdca42007-12-04 22:23:35 +00001283 // Copy the result values into the output registers.
1284 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1285 CCValAssign &VA = RVLocs[i];
1286 assert(VA.isRegLoc() && "Can only return in registers!");
1287 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1288 Flag = Chain.getValue(1);
1289 }
1290
Gabor Greif1c80d112008-08-28 21:40:38 +00001291 if (Flag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001292 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1293 else
1294 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1295}
1296
1297
1298//===----------------------------------------------------------------------===//
1299// Vector related lowering:
1300//===----------------------------------------------------------------------===//
1301
1302static ConstantSDNode *
1303getVecImm(SDNode *N) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001304 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001305
Scott Michel8efdca42007-12-04 22:23:35 +00001306 // Check to see if this buildvec has a single non-undef value in its elements.
1307 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1308 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greif1c80d112008-08-28 21:40:38 +00001309 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001310 OpVal = N->getOperand(i);
1311 else if (OpVal != N->getOperand(i))
1312 return 0;
1313 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001314
Gabor Greif1c80d112008-08-28 21:40:38 +00001315 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001316 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001317 return CN;
1318 }
1319 }
1320
1321 return 0; // All UNDEF: use implicit def.; not Constant node
1322}
1323
1324/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1325/// and the value fits into an unsigned 18-bit constant, and if so, return the
1326/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001327SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001328 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001329 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001330 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001331 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001332 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001333 uint32_t upper = uint32_t(UValue >> 32);
1334 uint32_t lower = uint32_t(UValue);
1335 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001336 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001337 Value = Value >> 32;
1338 }
Scott Michel8efdca42007-12-04 22:23:35 +00001339 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001340 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001341 }
1342
Dan Gohman8181bd12008-07-27 21:46:04 +00001343 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001344}
1345
1346/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1347/// and the value fits into a signed 16-bit constant, and if so, return the
1348/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001349SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001350 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001351 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001352 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001353 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001354 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001355 uint32_t upper = uint32_t(UValue >> 32);
1356 uint32_t lower = uint32_t(UValue);
1357 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001358 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001359 Value = Value >> 32;
1360 }
Scott Michel6baba072008-03-05 23:02:02 +00001361 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001362 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001363 }
1364 }
1365
Dan Gohman8181bd12008-07-27 21:46:04 +00001366 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001367}
1368
1369/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1370/// and the value fits into a signed 10-bit constant, and if so, return the
1371/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001372SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001373 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001374 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001375 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001376 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001377 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001378 uint32_t upper = uint32_t(UValue >> 32);
1379 uint32_t lower = uint32_t(UValue);
1380 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001381 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001382 Value = Value >> 32;
1383 }
Scott Michel6baba072008-03-05 23:02:02 +00001384 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001385 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001386 }
1387
Dan Gohman8181bd12008-07-27 21:46:04 +00001388 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001389}
1390
1391/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1392/// and the value fits into a signed 8-bit constant, and if so, return the
1393/// constant.
1394///
1395/// @note: The incoming vector is v16i8 because that's the only way we can load
1396/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1397/// same value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001398SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001399 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001400 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001401 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001402 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001403 && Value <= 0xffff /* truncated from uint64_t */
1404 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001405 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001406 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001407 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001408 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001409 }
1410
Dan Gohman8181bd12008-07-27 21:46:04 +00001411 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001412}
1413
1414/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1415/// and the value fits into a signed 16-bit constant, and if so, return the
1416/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001417SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001418 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001419 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001420 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001421 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001422 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1423 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001424 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001425 }
1426
Dan Gohman8181bd12008-07-27 21:46:04 +00001427 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001428}
1429
1430/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001431SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001432 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001433 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001434 }
1435
Dan Gohman8181bd12008-07-27 21:46:04 +00001436 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001437}
1438
1439/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001440SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001441 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001442 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001443 }
1444
Dan Gohman8181bd12008-07-27 21:46:04 +00001445 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001446}
1447
1448// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001449// UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001450// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1451// zero. Return true if this is not an array of constants, false if it is.
1452//
1453static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1454 uint64_t UndefBits[2]) {
1455 // Start with zero'd results.
1456 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001457
Duncan Sands92c43912008-06-06 12:08:01 +00001458 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel8efdca42007-12-04 22:23:35 +00001459 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001460 SDValue OpVal = BV->getOperand(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001461
Scott Michel8efdca42007-12-04 22:23:35 +00001462 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1463 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1464
1465 uint64_t EltBits = 0;
1466 if (OpVal.getOpcode() == ISD::UNDEF) {
1467 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1468 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1469 continue;
Scott Michel5974f432008-11-11 03:06:06 +00001470 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001471 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel5974f432008-11-11 03:06:06 +00001472 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001473 const APFloat &apf = CN->getValueAPF();
1474 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001475 ? FloatToBits(apf.convertToFloat())
1476 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001477 } else {
1478 // Nonconstant element.
1479 return true;
1480 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001481
Scott Michel8efdca42007-12-04 22:23:35 +00001482 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1483 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001484
1485 //printf("%llx %llx %llx %llx\n",
Scott Michel8efdca42007-12-04 22:23:35 +00001486 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1487 return false;
1488}
1489
1490/// If this is a splat (repetition) of a value across the whole vector, return
1491/// the smallest size that splats it. For example, "0x01010101010101..." is a
Scott Michel4ec722e2008-07-16 17:17:29 +00001492/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel8efdca42007-12-04 22:23:35 +00001493/// SplatSize = 1 byte.
Scott Michel4ec722e2008-07-16 17:17:29 +00001494static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel8efdca42007-12-04 22:23:35 +00001495 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001496 int MinSplatBits,
Scott Michel8efdca42007-12-04 22:23:35 +00001497 uint64_t &SplatBits, uint64_t &SplatUndef,
1498 int &SplatSize) {
1499 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1500 // the same as the lower 64-bits, ignoring undefs.
1501 uint64_t Bits64 = Bits128[0] | Bits128[1];
1502 uint64_t Undef64 = Undef128[0] & Undef128[1];
1503 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1504 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1505 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1506 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1507
1508 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1509 if (MinSplatBits < 64) {
Scott Michel4ec722e2008-07-16 17:17:29 +00001510
Scott Michel8efdca42007-12-04 22:23:35 +00001511 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1512 // undefs.
1513 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001514 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001515
Scott Michel5a6f17b2008-01-30 02:55:46 +00001516 // If the top 16-bits are different than the lower 16-bits, ignoring
1517 // undefs, we have an i32 splat.
1518 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1519 if (MinSplatBits < 16) {
1520 // If the top 8-bits are different than the lower 8-bits, ignoring
1521 // undefs, we have an i16 splat.
Gabor Greife9f7f582008-08-31 15:37:04 +00001522 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1523 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001524 // Otherwise, we have an 8-bit splat.
1525 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1526 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1527 SplatSize = 1;
1528 return true;
1529 }
1530 } else {
1531 SplatBits = Bits16;
1532 SplatUndef = Undef16;
1533 SplatSize = 2;
1534 return true;
1535 }
1536 }
1537 } else {
1538 SplatBits = Bits32;
1539 SplatUndef = Undef32;
1540 SplatSize = 4;
1541 return true;
1542 }
Scott Michel8efdca42007-12-04 22:23:35 +00001543 }
1544 } else {
1545 SplatBits = Bits128[0];
1546 SplatUndef = Undef128[0];
1547 SplatSize = 8;
1548 return true;
1549 }
1550 }
1551
1552 return false; // Can't be a splat if two pieces don't match.
1553}
1554
1555// If this is a case we can't handle, return null and let the default
1556// expansion code take care of it. If we CAN select this case, and if it
1557// selects to a single instruction, return Op. Otherwise, if we can codegen
1558// this case more efficiently than a constant pool load, lower it to the
1559// sequence of ops that should be used.
Dan Gohman8181bd12008-07-27 21:46:04 +00001560static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001561 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00001562 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001563 // UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001564 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel4ec722e2008-07-16 17:17:29 +00001565 // zero.
Scott Michel8efdca42007-12-04 22:23:35 +00001566 uint64_t VectorBits[2];
1567 uint64_t UndefBits[2];
1568 uint64_t SplatBits, SplatUndef;
1569 int SplatSize;
Gabor Greif1c80d112008-08-28 21:40:38 +00001570 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel8efdca42007-12-04 22:23:35 +00001571 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00001572 VT.getVectorElementType().getSizeInBits(),
Scott Michel8efdca42007-12-04 22:23:35 +00001573 SplatBits, SplatUndef, SplatSize))
Dan Gohman8181bd12008-07-27 21:46:04 +00001574 return SDValue(); // Not a constant vector, not a splat.
Scott Michel4ec722e2008-07-16 17:17:29 +00001575
Duncan Sands92c43912008-06-06 12:08:01 +00001576 switch (VT.getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001577 default:
1578 case MVT::v4f32: {
1579 uint32_t Value32 = SplatBits;
1580 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001581 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001582 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001583 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001584 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001585 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001586 break;
1587 }
1588 case MVT::v2f64: {
1589 uint64_t f64val = SplatBits;
1590 assert(SplatSize == 8
Scott Michelc630c412008-11-24 17:11:17 +00001591 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001592 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001593 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001594 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001595 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001596 break;
1597 }
1598 case MVT::v16i8: {
1599 // 8-bit constants have to be expanded to 16-bits
1600 unsigned short Value16 = SplatBits | (SplatBits << 8);
Dan Gohman8181bd12008-07-27 21:46:04 +00001601 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001602 for (int i = 0; i < 8; ++i)
1603 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1604 return DAG.getNode(ISD::BIT_CONVERT, VT,
1605 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1606 }
1607 case MVT::v8i16: {
1608 unsigned short Value16;
Scott Michel4ec722e2008-07-16 17:17:29 +00001609 if (SplatSize == 2)
Scott Michel8efdca42007-12-04 22:23:35 +00001610 Value16 = (unsigned short) (SplatBits & 0xffff);
1611 else
1612 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman8181bd12008-07-27 21:46:04 +00001613 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1614 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001615 for (int i = 0; i < 8; ++i) Ops[i] = T;
1616 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1617 }
1618 case MVT::v4i32: {
1619 unsigned int Value = SplatBits;
Dan Gohman8181bd12008-07-27 21:46:04 +00001620 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel8efdca42007-12-04 22:23:35 +00001621 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1622 }
Scott Michel70741542009-01-06 23:10:38 +00001623 case MVT::v2i32: {
1624 unsigned int Value = SplatBits;
1625 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
1626 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
1627 }
Scott Michel8efdca42007-12-04 22:23:35 +00001628 case MVT::v2i64: {
1629 uint64_t val = SplatBits;
1630 uint32_t upper = uint32_t(val >> 32);
1631 uint32_t lower = uint32_t(val);
1632
Scott Michelbcc7b672008-03-06 04:02:54 +00001633 if (upper == lower) {
1634 // Magic constant that can be matched by IL, ILA, et. al.
Dan Gohman8181bd12008-07-27 21:46:04 +00001635 SDValue Val = DAG.getTargetConstant(val, MVT::i64);
Scott Michelbcc7b672008-03-06 04:02:54 +00001636 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michel6baba072008-03-05 23:02:02 +00001637 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +00001638 SDValue LO32;
1639 SDValue HI32;
1640 SmallVector<SDValue, 16> ShufBytes;
1641 SDValue Result;
Scott Michel8efdca42007-12-04 22:23:35 +00001642 bool upper_special, lower_special;
1643
1644 // NOTE: This code creates common-case shuffle masks that can be easily
1645 // detected as common expressions. It is not attempting to create highly
1646 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1647
1648 // Detect if the upper or lower half is a special shuffle mask pattern:
Scott Michelc630c412008-11-24 17:11:17 +00001649 upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
1650 lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
Scott Michel8efdca42007-12-04 22:23:35 +00001651
1652 // Create lower vector if not a special pattern
1653 if (!lower_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001654 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001655 LO32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1656 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1657 LO32C, LO32C, LO32C, LO32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001658 }
1659
1660 // Create upper vector if not a special pattern
1661 if (!upper_special) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001662 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001663 HI32 = DAG.getNode(ISD::BIT_CONVERT, VT,
1664 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1665 HI32C, HI32C, HI32C, HI32C));
Scott Michel8efdca42007-12-04 22:23:35 +00001666 }
1667
1668 // If either upper or lower are special, then the two input operands are
1669 // the same (basically, one of them is a "don't care")
1670 if (lower_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001671 LO32 = HI32;
Scott Michel8efdca42007-12-04 22:23:35 +00001672 if (upper_special)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001673 HI32 = LO32;
Scott Michel8efdca42007-12-04 22:23:35 +00001674 if (lower_special && upper_special) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001675 // Unhappy situation... both upper and lower are special, so punt with
1676 // a target constant:
Dan Gohman8181bd12008-07-27 21:46:04 +00001677 SDValue Zero = DAG.getConstant(0, MVT::i32);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001678 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel8efdca42007-12-04 22:23:35 +00001679 Zero, Zero);
1680 }
1681
1682 for (int i = 0; i < 4; ++i) {
Scott Michel67224b22008-06-02 22:18:03 +00001683 uint64_t val = 0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001684 for (int j = 0; j < 4; ++j) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001685 SDValue V;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001686 bool process_upper, process_lower;
Scott Michel67224b22008-06-02 22:18:03 +00001687 val <<= 8;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001688 process_upper = (upper_special && (i & 1) == 0);
1689 process_lower = (lower_special && (i & 1) == 1);
Scott Michel8efdca42007-12-04 22:23:35 +00001690
Scott Michel5a6f17b2008-01-30 02:55:46 +00001691 if (process_upper || process_lower) {
1692 if ((process_upper && upper == 0)
1693 || (process_lower && lower == 0))
Scott Michel67224b22008-06-02 22:18:03 +00001694 val |= 0x80;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001695 else if ((process_upper && upper == 0xffffffff)
1696 || (process_lower && lower == 0xffffffff))
Scott Michel67224b22008-06-02 22:18:03 +00001697 val |= 0xc0;
Scott Michel5a6f17b2008-01-30 02:55:46 +00001698 else if ((process_upper && upper == 0x80000000)
1699 || (process_lower && lower == 0x80000000))
Scott Michel67224b22008-06-02 22:18:03 +00001700 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001701 } else
Scott Michel67224b22008-06-02 22:18:03 +00001702 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel5a6f17b2008-01-30 02:55:46 +00001703 }
Scott Michel67224b22008-06-02 22:18:03 +00001704
1705 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00001706 }
1707
1708 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel67224b22008-06-02 22:18:03 +00001709 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001710 &ShufBytes[0], ShufBytes.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001711 }
1712 }
1713 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001714
Dan Gohman8181bd12008-07-27 21:46:04 +00001715 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001716}
1717
1718/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1719/// which the Cell can operate. The code inspects V3 to ascertain whether the
1720/// permutation vector, V3, is monotonically increasing with one "exception"
1721/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel56a125e2008-11-22 23:50:42 +00001722/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-12-04 22:23:35 +00001723/// In either case, the net result is going to eventually invoke SHUFB to
1724/// permute/shuffle the bytes from V1 and V2.
1725/// \note
Scott Michel56a125e2008-11-22 23:50:42 +00001726/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-12-04 22:23:35 +00001727/// control word for byte/halfword/word insertion. This takes care of a single
1728/// element move from V2 into V1.
1729/// \note
1730/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman8181bd12008-07-27 21:46:04 +00001731static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
1732 SDValue V1 = Op.getOperand(0);
1733 SDValue V2 = Op.getOperand(1);
1734 SDValue PermMask = Op.getOperand(2);
Scott Michel4ec722e2008-07-16 17:17:29 +00001735
Scott Michel8efdca42007-12-04 22:23:35 +00001736 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001737
Scott Michel8efdca42007-12-04 22:23:35 +00001738 // If we have a single element being moved from V1 to V2, this can be handled
1739 // using the C*[DX] compute mask instructions, but the vector elements have
1740 // to be monotonically increasing with one exception element.
Scott Michele2641a12008-12-04 21:01:44 +00001741 MVT VecVT = V1.getValueType();
1742 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001743 unsigned EltsFromV2 = 0;
1744 unsigned V2Elt = 0;
1745 unsigned V2EltIdx0 = 0;
1746 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001747 unsigned MaxElts = VecVT.getVectorNumElements();
1748 unsigned PrevElt = 0;
1749 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001750 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001751 bool rotate = true;
1752
1753 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001754 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001755 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001756 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001757 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001758 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001759 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1760 V2EltIdx0 = 2;
1761 } else
Scott Michel8efdca42007-12-04 22:23:35 +00001762 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1763
Scott Michele2641a12008-12-04 21:01:44 +00001764 for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) {
1765 if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) {
1766 unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001767
Scott Michele2641a12008-12-04 21:01:44 +00001768 if (monotonic) {
1769 if (SrcElt >= V2EltIdx0) {
1770 if (1 >= (++EltsFromV2)) {
1771 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1772 }
1773 } else if (CurrElt != SrcElt) {
1774 monotonic = false;
1775 }
1776
1777 ++CurrElt;
1778 }
1779
1780 if (rotate) {
1781 if (PrevElt > 0 && SrcElt < MaxElts) {
1782 if ((PrevElt == SrcElt - 1)
1783 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
1784 PrevElt = SrcElt;
1785 if (SrcElt == 0)
1786 V0Elt = i;
1787 } else {
1788 rotate = false;
1789 }
1790 } else if (PrevElt == 0) {
1791 // First time through, need to keep track of previous element
1792 PrevElt = SrcElt;
1793 } else {
1794 // This isn't a rotation, takes elements from vector 2
1795 rotate = false;
1796 }
1797 }
Scott Michel8efdca42007-12-04 22:23:35 +00001798 }
Scott Michel8efdca42007-12-04 22:23:35 +00001799 }
1800
1801 if (EltsFromV2 == 1 && monotonic) {
1802 // Compute mask and shuffle
1803 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001804 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1805 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001806 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001807 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001808 SDValue InitTempReg =
Scott Michel8efdca42007-12-04 22:23:35 +00001809 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001810 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001811 SDValue ShufMaskOp =
Scott Michel0718cd82008-12-01 17:56:02 +00001812 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001813 DAG.getTargetConstant(V2Elt, MVT::i32),
1814 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001815 // Use shuffle mask in SHUFB synthetic instruction:
1816 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
Scott Michele2641a12008-12-04 21:01:44 +00001817 } else if (rotate) {
1818 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001819
Scott Michele2641a12008-12-04 21:01:44 +00001820 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1821 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001822 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001823 // Convert the SHUFFLE_VECTOR mask's input element units to the
1824 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001825 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001826
Dan Gohman8181bd12008-07-27 21:46:04 +00001827 SmallVector<SDValue, 16> ResultMask;
Scott Michel8efdca42007-12-04 22:23:35 +00001828 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1829 unsigned SrcElt;
1830 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001831 SrcElt = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001832 else
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001833 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel4ec722e2008-07-16 17:17:29 +00001834
Scott Michel97872d32008-02-23 18:41:37 +00001835 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001836 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1837 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001838 }
1839 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001840
Dan Gohman8181bd12008-07-27 21:46:04 +00001841 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel0718cd82008-12-01 17:56:02 +00001842 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001843 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1844 }
1845}
1846
Dan Gohman8181bd12008-07-27 21:46:04 +00001847static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1848 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001849
Gabor Greif1c80d112008-08-28 21:40:38 +00001850 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-12-04 22:23:35 +00001851 // For a constant, build the appropriate constant vector, which will
1852 // eventually simplify to a vector register load.
1853
Gabor Greif1c80d112008-08-28 21:40:38 +00001854 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001855 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001856 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001857 size_t n_copies;
1858
1859 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001860 switch (Op.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001861 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001862 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001863 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1864 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1865 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1866 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1867 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1868 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1869 }
1870
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001871 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-12-04 22:23:35 +00001872 for (size_t j = 0; j < n_copies; ++j)
1873 ConstVecValues.push_back(CValue);
1874
1875 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001876 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001877 } else {
1878 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001879 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001880 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1881 case MVT::i8:
1882 case MVT::i16:
1883 case MVT::i32:
1884 case MVT::i64:
1885 case MVT::f32:
1886 case MVT::f64:
Scott Michel06eabde2008-12-27 04:51:36 +00001887 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001888 }
1889 }
1890
Dan Gohman8181bd12008-07-27 21:46:04 +00001891 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001892}
1893
Dan Gohman8181bd12008-07-27 21:46:04 +00001894static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001895 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001896 SDValue N = Op.getOperand(0);
1897 SDValue Elt = Op.getOperand(1);
Scott Michel56a125e2008-11-22 23:50:42 +00001898 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001899
Scott Michel56a125e2008-11-22 23:50:42 +00001900 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1901 // Constant argument:
1902 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001903
Scott Michel56a125e2008-11-22 23:50:42 +00001904 // sanity checks:
1905 if (VT == MVT::i8 && EltNo >= 16)
1906 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1907 else if (VT == MVT::i16 && EltNo >= 8)
1908 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1909 else if (VT == MVT::i32 && EltNo >= 4)
1910 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1911 else if (VT == MVT::i64 && EltNo >= 2)
1912 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel8efdca42007-12-04 22:23:35 +00001913
Scott Michel56a125e2008-11-22 23:50:42 +00001914 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1915 // i32 and i64: Element 0 is the preferred slot
Scott Michelc630c412008-11-24 17:11:17 +00001916 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001917 }
Scott Michel8efdca42007-12-04 22:23:35 +00001918
Scott Michel56a125e2008-11-22 23:50:42 +00001919 // Need to generate shuffle mask and extract:
1920 int prefslot_begin = -1, prefslot_end = -1;
1921 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1922
1923 switch (VT.getSimpleVT()) {
1924 default:
1925 assert(false && "Invalid value type!");
1926 case MVT::i8: {
1927 prefslot_begin = prefslot_end = 3;
1928 break;
1929 }
1930 case MVT::i16: {
1931 prefslot_begin = 2; prefslot_end = 3;
1932 break;
1933 }
1934 case MVT::i32:
1935 case MVT::f32: {
1936 prefslot_begin = 0; prefslot_end = 3;
1937 break;
1938 }
1939 case MVT::i64:
1940 case MVT::f64: {
1941 prefslot_begin = 0; prefslot_end = 7;
1942 break;
1943 }
1944 }
1945
1946 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1947 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1948
1949 unsigned int ShufBytes[16];
1950 for (int i = 0; i < 16; ++i) {
1951 // zero fill uppper part of preferred slot, don't care about the
1952 // other slots:
1953 unsigned int mask_val;
1954 if (i <= prefslot_end) {
1955 mask_val =
1956 ((i < prefslot_begin)
1957 ? 0x80
1958 : elt_byte + (i - prefslot_begin));
1959
1960 ShufBytes[i] = mask_val;
1961 } else
1962 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1963 }
1964
1965 SDValue ShufMask[4];
1966 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michele2641a12008-12-04 21:01:44 +00001967 unsigned bidx = i * 4;
Scott Michel56a125e2008-11-22 23:50:42 +00001968 unsigned int bits = ((ShufBytes[bidx] << 24) |
1969 (ShufBytes[bidx+1] << 16) |
1970 (ShufBytes[bidx+2] << 8) |
1971 ShufBytes[bidx+3]);
1972 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1973 }
1974
1975 SDValue ShufMaskVec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1976 &ShufMask[0],
1977 sizeof(ShufMask) / sizeof(ShufMask[0]));
1978
Scott Michelc630c412008-11-24 17:11:17 +00001979 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel56a125e2008-11-22 23:50:42 +00001980 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
1981 N, N, ShufMaskVec));
1982 } else {
1983 // Variable index: Rotate the requested element into slot 0, then replicate
1984 // slot 0 across the vector
1985 MVT VecVT = N.getValueType();
1986 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
1987 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
1988 abort();
1989 }
1990
1991 // Make life easier by making sure the index is zero-extended to i32
1992 if (Elt.getValueType() != MVT::i32)
1993 Elt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Elt);
1994
1995 // Scale the index to a bit/byte shift quantity
1996 APInt scaleFactor =
Scott Michelc630c412008-11-24 17:11:17 +00001997 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1998 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00001999 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00002000
Scott Michelc630c412008-11-24 17:11:17 +00002001 if (scaleShift > 0) {
2002 // Scale the shift factor:
Scott Michel56a125e2008-11-22 23:50:42 +00002003 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00002004 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00002005 }
2006
Scott Michelc630c412008-11-24 17:11:17 +00002007 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt);
2008
2009 // Replicate the bytes starting at byte 0 across the entire vector (for
2010 // consistency with the notion of a unified register set)
Scott Michel56a125e2008-11-22 23:50:42 +00002011 SDValue replicate;
2012
2013 switch (VT.getSimpleVT()) {
2014 default:
2015 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
2016 abort();
2017 /*NOTREACHED*/
2018 case MVT::i8: {
Scott Michelc630c412008-11-24 17:11:17 +00002019 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel56a125e2008-11-22 23:50:42 +00002020 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2021 factor, factor);
2022 break;
2023 }
2024 case MVT::i16: {
Scott Michelc630c412008-11-24 17:11:17 +00002025 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel56a125e2008-11-22 23:50:42 +00002026 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2027 factor, factor);
2028 break;
2029 }
2030 case MVT::i32:
2031 case MVT::f32: {
2032 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
2033 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2034 factor, factor);
2035 break;
2036 }
2037 case MVT::i64:
2038 case MVT::f64: {
2039 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2040 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
2041 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, loFactor, hiFactor,
2042 loFactor, hiFactor);
2043 break;
2044 }
2045 }
2046
Scott Michelc630c412008-11-24 17:11:17 +00002047 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel0718cd82008-12-01 17:56:02 +00002048 DAG.getNode(SPUISD::SHUFB, VecVT,
2049 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002050 }
2051
Scott Michel56a125e2008-11-22 23:50:42 +00002052 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002053}
2054
Dan Gohman8181bd12008-07-27 21:46:04 +00002055static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2056 SDValue VecOp = Op.getOperand(0);
2057 SDValue ValOp = Op.getOperand(1);
2058 SDValue IdxOp = Op.getOperand(2);
Duncan Sands92c43912008-06-06 12:08:01 +00002059 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002060
2061 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2062 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2063
Duncan Sands92c43912008-06-06 12:08:01 +00002064 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-12-01 17:56:02 +00002065 // Use $sp ($1) because it's always 16-byte aligned and it's available:
2066 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
2067 DAG.getRegister(SPU::R1, PtrVT),
2068 DAG.getConstant(CN->getSExtValue(), PtrVT));
2069 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer);
Scott Michel8efdca42007-12-04 22:23:35 +00002070
Dan Gohman8181bd12008-07-27 21:46:04 +00002071 SDValue result =
Scott Michel8efdca42007-12-04 22:23:35 +00002072 DAG.getNode(SPUISD::SHUFB, VT,
2073 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002074 VecOp,
Scott Michel0718cd82008-12-01 17:56:02 +00002075 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002076
2077 return result;
2078}
2079
Scott Michel06eabde2008-12-27 04:51:36 +00002080static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2081 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002082{
Dan Gohman8181bd12008-07-27 21:46:04 +00002083 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michel06eabde2008-12-27 04:51:36 +00002084 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-12-04 22:23:35 +00002085
2086 assert(Op.getValueType() == MVT::i8);
2087 switch (Opc) {
2088 default:
2089 assert(0 && "Unhandled i8 math operator");
2090 /*NOTREACHED*/
2091 break;
Scott Michel4d07fb72008-12-30 23:28:25 +00002092 case ISD::ADD: {
2093 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2094 // the result:
2095 SDValue N1 = Op.getOperand(1);
2096 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2097 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
2098 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2099 DAG.getNode(Opc, MVT::i16, N0, N1));
2100
2101 }
2102
Scott Michel8efdca42007-12-04 22:23:35 +00002103 case ISD::SUB: {
2104 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2105 // the result:
Dan Gohman8181bd12008-07-27 21:46:04 +00002106 SDValue N1 = Op.getOperand(1);
Scott Michel4d07fb72008-12-30 23:28:25 +00002107 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2108 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
Scott Michel4ec722e2008-07-16 17:17:29 +00002109 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002110 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel4ec722e2008-07-16 17:17:29 +00002111 }
Scott Michel8efdca42007-12-04 22:23:35 +00002112 case ISD::ROTR:
2113 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002114 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002115 unsigned N1Opc;
2116 N0 = (N0.getOpcode() != ISD::Constant
2117 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002118 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2119 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002120 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002121 ? ISD::ZERO_EXTEND
2122 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002123 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002124 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002125 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002126 TLI.getShiftAmountTy()));
Dan Gohman8181bd12008-07-27 21:46:04 +00002127 SDValue ExpandArg =
Scott Michel8efdca42007-12-04 22:23:35 +00002128 DAG.getNode(ISD::OR, MVT::i16, N0,
2129 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002130 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel4ec722e2008-07-16 17:17:29 +00002131 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002132 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2133 }
2134 case ISD::SRL:
2135 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002136 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002137 unsigned N1Opc;
2138 N0 = (N0.getOpcode() != ISD::Constant
2139 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002140 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002141 MVT::i32));
2142 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002143 ? ISD::ZERO_EXTEND
2144 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002145 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002146 ? DAG.getNode(N1Opc, ShiftVT, N1)
2147 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002148 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002149 DAG.getNode(Opc, MVT::i16, N0, N1));
2150 }
2151 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002152 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002153 unsigned N1Opc;
2154 N0 = (N0.getOpcode() != ISD::Constant
2155 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michel06eabde2008-12-27 04:51:36 +00002156 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002157 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002158 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002159 ? ISD::SIGN_EXTEND
2160 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002161 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002162 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002163 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002164 ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002165 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002166 DAG.getNode(Opc, MVT::i16, N0, N1));
2167 }
2168 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002169 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002170 unsigned N1Opc;
2171 N0 = (N0.getOpcode() != ISD::Constant
2172 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002173 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2174 MVT::i16));
Duncan Sandsec142ee2008-06-08 20:54:56 +00002175 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002176 N1 = (N1.getOpcode() != ISD::Constant
2177 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michel06eabde2008-12-27 04:51:36 +00002178 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002179 MVT::i16));
Scott Michel4ec722e2008-07-16 17:17:29 +00002180 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002181 DAG.getNode(Opc, MVT::i16, N0, N1));
2182 break;
2183 }
2184 }
2185
Dan Gohman8181bd12008-07-27 21:46:04 +00002186 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002187}
2188
Scott Michel750b93f2009-01-15 04:41:47 +00002189//! Generate the carry-generate shuffle mask.
2190SDValue SPU::getCarryGenerateShufMask(SelectionDAG &DAG) {
2191SmallVector<SDValue, 16> ShufBytes;
Scott Michel97872d32008-02-23 18:41:37 +00002192
Scott Michel750b93f2009-01-15 04:41:47 +00002193// Create the shuffle mask for "rotating" the borrow up one register slot
2194// once the borrow is generated.
2195ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2196ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2197ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2198ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
Scott Michel97872d32008-02-23 18:41:37 +00002199
Scott Michel750b93f2009-01-15 04:41:47 +00002200return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2201 &ShufBytes[0], ShufBytes.size());
2202}
Scott Michel97872d32008-02-23 18:41:37 +00002203
Scott Michel750b93f2009-01-15 04:41:47 +00002204//! Generate the borrow-generate shuffle mask
2205SDValue SPU::getBorrowGenerateShufMask(SelectionDAG &DAG) {
2206SmallVector<SDValue, 16> ShufBytes;
Scott Michel97872d32008-02-23 18:41:37 +00002207
Scott Michel750b93f2009-01-15 04:41:47 +00002208// Create the shuffle mask for "rotating" the borrow up one register slot
2209// once the borrow is generated.
2210ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2211ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2212ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2213ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
Scott Michelf2df6cb2008-11-24 18:20:46 +00002214
Scott Michel750b93f2009-01-15 04:41:47 +00002215return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2216 &ShufBytes[0], ShufBytes.size());
Scott Michel97872d32008-02-23 18:41:37 +00002217}
2218
Scott Michel8efdca42007-12-04 22:23:35 +00002219//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002220static SDValue
2221LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2222 SDValue ConstVec;
2223 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002224 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002225
2226 ConstVec = Op.getOperand(0);
2227 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002228 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2229 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002230 ConstVec = ConstVec.getOperand(0);
2231 } else {
2232 ConstVec = Op.getOperand(1);
2233 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002234 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002235 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002236 }
2237 }
2238 }
2239
Gabor Greif1c80d112008-08-28 21:40:38 +00002240 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel8efdca42007-12-04 22:23:35 +00002241 uint64_t VectorBits[2];
2242 uint64_t UndefBits[2];
2243 uint64_t SplatBits, SplatUndef;
2244 int SplatSize;
2245
Gabor Greif1c80d112008-08-28 21:40:38 +00002246 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002247 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00002248 VT.getVectorElementType().getSizeInBits(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002249 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002250 SDValue tcVec[16];
2251 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002252 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2253
2254 // Turn the BUILD_VECTOR into a set of target constants:
2255 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002256 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002257
Gabor Greif1c80d112008-08-28 21:40:38 +00002258 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002259 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002260 }
2261 }
Nate Begeman7569e762008-07-29 19:07:27 +00002262 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2263 // lowered. Return the operation, rather than a null SDValue.
2264 return Op;
Scott Michel8efdca42007-12-04 22:23:35 +00002265}
2266
Scott Michel8efdca42007-12-04 22:23:35 +00002267//! Custom lowering for CTPOP (count population)
2268/*!
2269 Custom lowering code that counts the number ones in the input
2270 operand. SPU has such an instruction, but it counts the number of
2271 ones per byte, which then have to be accumulated.
2272*/
Dan Gohman8181bd12008-07-27 21:46:04 +00002273static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002274 MVT VT = Op.getValueType();
2275 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +00002276
Duncan Sands92c43912008-06-06 12:08:01 +00002277 switch (VT.getSimpleVT()) {
2278 default:
2279 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002280 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002281 SDValue N = Op.getOperand(0);
2282 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002283
Scott Michel06eabde2008-12-27 04:51:36 +00002284 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002285 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002286
2287 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2288 }
2289
2290 case MVT::i16: {
2291 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002292 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002293
Chris Lattner1b989192007-12-31 04:13:23 +00002294 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002295
Dan Gohman8181bd12008-07-27 21:46:04 +00002296 SDValue N = Op.getOperand(0);
2297 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2298 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sands7aef60d2008-10-30 19:24:28 +00002299 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002300
Scott Michel06eabde2008-12-27 04:51:36 +00002301 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002302 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002303
2304 // CNTB_result becomes the chain to which all of the virtual registers
2305 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002306 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002307 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002308
Dan Gohman8181bd12008-07-27 21:46:04 +00002309 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002310 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2311
Dan Gohman8181bd12008-07-27 21:46:04 +00002312 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002313
2314 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002315 DAG.getNode(ISD::ADD, MVT::i16,
2316 DAG.getNode(ISD::SRL, MVT::i16,
2317 Tmp1, Shift1),
2318 Tmp1),
2319 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002320 }
2321
2322 case MVT::i32: {
2323 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002324 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002325
Chris Lattner1b989192007-12-31 04:13:23 +00002326 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2327 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002328
Dan Gohman8181bd12008-07-27 21:46:04 +00002329 SDValue N = Op.getOperand(0);
2330 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2331 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2332 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2333 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002334
Scott Michel06eabde2008-12-27 04:51:36 +00002335 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002336 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002337
2338 // CNTB_result becomes the chain to which all of the virtual registers
2339 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002340 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002341 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002342
Dan Gohman8181bd12008-07-27 21:46:04 +00002343 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002344 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2345
Dan Gohman8181bd12008-07-27 21:46:04 +00002346 SDValue Comp1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002347 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002348 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002349
Dan Gohman8181bd12008-07-27 21:46:04 +00002350 SDValue Sum1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002351 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002352 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002353
Dan Gohman8181bd12008-07-27 21:46:04 +00002354 SDValue Sum1_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002355 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2356
Dan Gohman8181bd12008-07-27 21:46:04 +00002357 SDValue Comp2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002358 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002359 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2360 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002361 SDValue Sum2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002362 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002363 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002364
2365 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2366 }
2367
2368 case MVT::i64:
2369 break;
2370 }
2371
Dan Gohman8181bd12008-07-27 21:46:04 +00002372 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002373}
2374
Scott Michel56a125e2008-11-22 23:50:42 +00002375//! Lower ISD::SELECT_CC
2376/*!
2377 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2378 SELB instruction.
2379
2380 \note Need to revisit this in the future: if the code path through the true
2381 and false value computations is longer than the latency of a branch (6
2382 cycles), then it would be more advantageous to branch and insert a new basic
2383 block and branch on the condition. However, this code does not make that
2384 assumption, given the simplisitc uses so far.
2385 */
2386
Scott Michel06eabde2008-12-27 04:51:36 +00002387static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2388 const TargetLowering &TLI) {
Scott Michel56a125e2008-11-22 23:50:42 +00002389 MVT VT = Op.getValueType();
2390 SDValue lhs = Op.getOperand(0);
2391 SDValue rhs = Op.getOperand(1);
2392 SDValue trueval = Op.getOperand(2);
2393 SDValue falseval = Op.getOperand(3);
2394 SDValue condition = Op.getOperand(4);
2395
Scott Michel06eabde2008-12-27 04:51:36 +00002396 // NOTE: SELB's arguments: $rA, $rB, $mask
2397 //
2398 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2399 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2400 // condition was true and 0s where the condition was false. Hence, the
2401 // arguments to SELB get reversed.
2402
Scott Michel56a125e2008-11-22 23:50:42 +00002403 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2404 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2405 // with another "cannot select select_cc" assert:
2406
Duncan Sands4a361272009-01-01 15:52:00 +00002407 SDValue compare = DAG.getNode(ISD::SETCC,
2408 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002409 lhs, rhs, condition);
2410 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002411}
2412
Scott Michelec8c82e2008-12-02 19:53:53 +00002413//! Custom lower ISD::TRUNCATE
2414static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2415{
2416 MVT VT = Op.getValueType();
2417 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2418 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
2419
2420 SDValue Op0 = Op.getOperand(0);
2421 MVT Op0VT = Op0.getValueType();
2422 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
2423
Scott Michel06eabde2008-12-27 04:51:36 +00002424 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002425 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-12-27 04:51:36 +00002426 unsigned maskHigh = 0x08090a0b;
2427 unsigned maskLow = 0x0c0d0e0f;
2428 // Use a shuffle to perform the truncation
2429 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2430 DAG.getConstant(maskHigh, MVT::i32),
2431 DAG.getConstant(maskLow, MVT::i32),
2432 DAG.getConstant(maskHigh, MVT::i32),
2433 DAG.getConstant(maskLow, MVT::i32));
2434
2435
2436 SDValue PromoteScalar = DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
2437
2438 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2439 PromoteScalar, PromoteScalar, shufMask);
2440
2441 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2442 DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle));
Scott Michelec8c82e2008-12-02 19:53:53 +00002443 }
2444
Scott Michel06eabde2008-12-27 04:51:36 +00002445 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002446}
2447
Scott Michel56a125e2008-11-22 23:50:42 +00002448//! Custom (target-specific) lowering entry point
2449/*!
2450 This is where LLVM's DAG selection process calls to do target-specific
2451 lowering of nodes.
2452 */
Dan Gohman8181bd12008-07-27 21:46:04 +00002453SDValue
2454SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002455{
Scott Michel97872d32008-02-23 18:41:37 +00002456 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002457 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002458
2459 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002460 default: {
2461 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002462 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002463 cerr << "*Op.getNode():\n";
2464 Op.getNode()->dump();
Scott Michel8efdca42007-12-04 22:23:35 +00002465 abort();
2466 }
2467 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002468 case ISD::EXTLOAD:
Scott Michel8efdca42007-12-04 22:23:35 +00002469 case ISD::SEXTLOAD:
2470 case ISD::ZEXTLOAD:
2471 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2472 case ISD::STORE:
2473 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2474 case ISD::ConstantPool:
2475 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2476 case ISD::GlobalAddress:
2477 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2478 case ISD::JumpTable:
2479 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
2480 case ISD::Constant:
2481 return LowerConstant(Op, DAG);
2482 case ISD::ConstantFP:
2483 return LowerConstantFP(Op, DAG);
2484 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002485 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002486 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002487 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002488 case ISD::RET:
2489 return LowerRET(Op, DAG, getTargetMachine());
2490
Scott Michel4d07fb72008-12-30 23:28:25 +00002491 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002492 case ISD::ADD:
Scott Michel8efdca42007-12-04 22:23:35 +00002493 case ISD::SUB:
2494 case ISD::ROTR:
2495 case ISD::ROTL:
2496 case ISD::SRL:
2497 case ISD::SHL:
Scott Michel67224b22008-06-02 22:18:03 +00002498 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002499 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002500 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002501 break;
Scott Michel67224b22008-06-02 22:18:03 +00002502 }
Scott Michel8efdca42007-12-04 22:23:35 +00002503
2504 // Vector-related lowering.
2505 case ISD::BUILD_VECTOR:
2506 return LowerBUILD_VECTOR(Op, DAG);
2507 case ISD::SCALAR_TO_VECTOR:
2508 return LowerSCALAR_TO_VECTOR(Op, DAG);
2509 case ISD::VECTOR_SHUFFLE:
2510 return LowerVECTOR_SHUFFLE(Op, DAG);
2511 case ISD::EXTRACT_VECTOR_ELT:
2512 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2513 case ISD::INSERT_VECTOR_ELT:
2514 return LowerINSERT_VECTOR_ELT(Op, DAG);
2515
2516 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2517 case ISD::AND:
2518 case ISD::OR:
2519 case ISD::XOR:
2520 return LowerByteImmed(Op, DAG);
2521
2522 // Vector and i8 multiply:
2523 case ISD::MUL:
Scott Michel4d07fb72008-12-30 23:28:25 +00002524 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002525 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002526
Scott Michel8efdca42007-12-04 22:23:35 +00002527 case ISD::CTPOP:
2528 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002529
2530 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002531 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002532
2533 case ISD::TRUNCATE:
2534 return LowerTRUNCATE(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002535 }
2536
Dan Gohman8181bd12008-07-27 21:46:04 +00002537 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002538}
2539
Duncan Sands7d9834b2008-12-01 11:39:25 +00002540void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2541 SmallVectorImpl<SDValue>&Results,
2542 SelectionDAG &DAG)
Scott Michel6e2d68b2008-11-10 23:43:06 +00002543{
2544#if 0
2545 unsigned Opc = (unsigned) N->getOpcode();
2546 MVT OpVT = N->getValueType(0);
2547
2548 switch (Opc) {
2549 default: {
2550 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2551 cerr << "Op.getOpcode() = " << Opc << "\n";
2552 cerr << "*Op.getNode():\n";
2553 N->dump();
2554 abort();
2555 /*NOTREACHED*/
2556 }
2557 }
2558#endif
2559
2560 /* Otherwise, return unchanged */
Scott Michel6e2d68b2008-11-10 23:43:06 +00002561}
2562
Scott Michel8efdca42007-12-04 22:23:35 +00002563//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002564// Target Optimization Hooks
2565//===----------------------------------------------------------------------===//
2566
Dan Gohman8181bd12008-07-27 21:46:04 +00002567SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002568SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2569{
2570#if 0
2571 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002572#endif
2573 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002574 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-12-01 17:56:02 +00002575 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2576 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michel06eabde2008-12-27 04:51:36 +00002577 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002578 SDValue Result; // Initially, empty result
Scott Michel8efdca42007-12-04 22:23:35 +00002579
2580 switch (N->getOpcode()) {
2581 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002582 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002583 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002584
Scott Michel06eabde2008-12-27 04:51:36 +00002585 if (Op0.getOpcode() == SPUISD::IndirectAddr
2586 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2587 // Normalize the operands to reduce repeated code
2588 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michelae5cbf52008-12-29 03:23:36 +00002589
Scott Michel06eabde2008-12-27 04:51:36 +00002590 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2591 IndirectArg = Op1;
2592 AddArg = Op0;
2593 }
2594
2595 if (isa<ConstantSDNode>(AddArg)) {
2596 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2597 SDValue IndOp1 = IndirectArg.getOperand(1);
2598
2599 if (CN0->isNullValue()) {
2600 // (add (SPUindirect <arg>, <arg>), 0) ->
2601 // (SPUindirect <arg>, <arg>)
Scott Michelf9f42e62008-01-29 02:16:57 +00002602
Scott Michel8c2746e2008-12-04 17:16:59 +00002603#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002604 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002605 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002606 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2607 << "With: (SPUindirect <arg>, <arg>)\n";
2608 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002609#endif
2610
Scott Michel06eabde2008-12-27 04:51:36 +00002611 return IndirectArg;
2612 } else if (isa<ConstantSDNode>(IndOp1)) {
2613 // (add (SPUindirect <arg>, <const>), <const>) ->
2614 // (SPUindirect <arg>, <const + const>)
2615 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2616 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2617 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michelf9f42e62008-01-29 02:16:57 +00002618
Scott Michel06eabde2008-12-27 04:51:36 +00002619#if !defined(NDEBUG)
2620 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2621 cerr << "\n"
2622 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2623 << "), " << CN0->getSExtValue() << ")\n"
2624 << "With: (SPUindirect <arg>, "
2625 << combinedConst << ")\n";
2626 }
2627#endif
Scott Michelf9f42e62008-01-29 02:16:57 +00002628
Scott Michel06eabde2008-12-27 04:51:36 +00002629 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2630 IndirectArg, combinedValue);
2631 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002632 }
2633 }
Scott Michel97872d32008-02-23 18:41:37 +00002634 break;
2635 }
2636 case ISD::SIGN_EXTEND:
2637 case ISD::ZERO_EXTEND:
2638 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002639 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002640 // (any_extend (SPUextract_elt0 <arg>)) ->
2641 // (SPUextract_elt0 <arg>)
2642 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002643#if !defined(NDEBUG)
2644 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002645 cerr << "\nReplace: ";
2646 N->dump(&DAG);
2647 cerr << "\nWith: ";
2648 Op0.getNode()->dump(&DAG);
2649 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002650 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002651#endif
Scott Michel97872d32008-02-23 18:41:37 +00002652
2653 return Op0;
2654 }
2655 break;
2656 }
2657 case SPUISD::IndirectAddr: {
2658 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
2659 ConstantSDNode *CN = cast<ConstantSDNode>(N->getOperand(1));
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002660 if (CN->getZExtValue() == 0) {
Scott Michel97872d32008-02-23 18:41:37 +00002661 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2662 // (SPUaform <addr>, 0)
2663
2664 DEBUG(cerr << "Replace: ");
2665 DEBUG(N->dump(&DAG));
2666 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002667 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002668 DEBUG(cerr << "\n");
2669
2670 return Op0;
2671 }
Scott Michel06eabde2008-12-27 04:51:36 +00002672 } else if (Op0.getOpcode() == ISD::ADD) {
2673 SDValue Op1 = N->getOperand(1);
2674 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2675 // (SPUindirect (add <arg>, <arg>), 0) ->
2676 // (SPUindirect <arg>, <arg>)
2677 if (CN1->isNullValue()) {
2678
2679#if !defined(NDEBUG)
2680 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2681 cerr << "\n"
2682 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2683 << "With: (SPUindirect <arg>, <arg>)\n";
2684 }
2685#endif
2686
2687 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2688 Op0.getOperand(0), Op0.getOperand(1));
2689 }
2690 }
Scott Michel97872d32008-02-23 18:41:37 +00002691 }
2692 break;
2693 }
2694 case SPUISD::SHLQUAD_L_BITS:
2695 case SPUISD::SHLQUAD_L_BYTES:
2696 case SPUISD::VEC_SHL:
2697 case SPUISD::VEC_SRL:
2698 case SPUISD::VEC_SRA:
Scott Michel06eabde2008-12-27 04:51:36 +00002699 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002700 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002701
Scott Michel06eabde2008-12-27 04:51:36 +00002702 // Kill degenerate vector shifts:
2703 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2704 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002705 Result = Op0;
2706 }
2707 }
2708 break;
2709 }
Scott Michel06eabde2008-12-27 04:51:36 +00002710 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-02-23 18:41:37 +00002711 switch (Op0.getOpcode()) {
2712 default:
2713 break;
2714 case ISD::ANY_EXTEND:
2715 case ISD::ZERO_EXTEND:
2716 case ISD::SIGN_EXTEND: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002717 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002718 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002719 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002720 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002721 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002722 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002723 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002724 Result = Op000;
2725 }
2726 }
2727 break;
2728 }
Scott Michelc630c412008-11-24 17:11:17 +00002729 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002730 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002731 // <arg>
2732 Result = Op0.getOperand(0);
2733 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002734 }
Scott Michel97872d32008-02-23 18:41:37 +00002735 }
2736 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002737 }
2738 }
Scott Michel750b93f2009-01-15 04:41:47 +00002739
Scott Michel394e26d2008-01-17 20:38:41 +00002740 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002741#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002742 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002743 DEBUG(cerr << "\nReplace.SPU: ");
2744 DEBUG(N->dump(&DAG));
2745 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002746 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002747 DEBUG(cerr << "\n");
2748 }
2749#endif
2750
2751 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002752}
2753
2754//===----------------------------------------------------------------------===//
2755// Inline Assembly Support
2756//===----------------------------------------------------------------------===//
2757
2758/// getConstraintType - Given a constraint letter, return the type of
2759/// constraint it is for this target.
Scott Michel4ec722e2008-07-16 17:17:29 +00002760SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-12-04 22:23:35 +00002761SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2762 if (ConstraintLetter.size() == 1) {
2763 switch (ConstraintLetter[0]) {
2764 default: break;
2765 case 'b':
2766 case 'r':
2767 case 'f':
2768 case 'v':
2769 case 'y':
2770 return C_RegisterClass;
Scott Michel4ec722e2008-07-16 17:17:29 +00002771 }
Scott Michel8efdca42007-12-04 22:23:35 +00002772 }
2773 return TargetLowering::getConstraintType(ConstraintLetter);
2774}
2775
Scott Michel4ec722e2008-07-16 17:17:29 +00002776std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002777SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002778 MVT VT) const
Scott Michel8efdca42007-12-04 22:23:35 +00002779{
2780 if (Constraint.size() == 1) {
2781 // GCC RS6000 Constraint Letters
2782 switch (Constraint[0]) {
2783 case 'b': // R1-R31
2784 case 'r': // R0-R31
2785 if (VT == MVT::i64)
2786 return std::make_pair(0U, SPU::R64CRegisterClass);
2787 return std::make_pair(0U, SPU::R32CRegisterClass);
2788 case 'f':
2789 if (VT == MVT::f32)
2790 return std::make_pair(0U, SPU::R32FPRegisterClass);
2791 else if (VT == MVT::f64)
2792 return std::make_pair(0U, SPU::R64FPRegisterClass);
2793 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002794 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00002795 return std::make_pair(0U, SPU::GPRCRegisterClass);
2796 }
2797 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002798
Scott Michel8efdca42007-12-04 22:23:35 +00002799 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2800}
2801
Scott Michel97872d32008-02-23 18:41:37 +00002802//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002803void
Dan Gohman8181bd12008-07-27 21:46:04 +00002804SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002805 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00002806 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00002807 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002808 const SelectionDAG &DAG,
2809 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00002810#if 0
Scott Michel97872d32008-02-23 18:41:37 +00002811 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michelbc5fbc12008-04-30 00:30:08 +00002812#endif
Scott Michel97872d32008-02-23 18:41:37 +00002813
2814 switch (Op.getOpcode()) {
2815 default:
2816 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2817 break;
2818
2819#if 0
2820 case CALL:
2821 case SHUFB:
Scott Michel56a125e2008-11-22 23:50:42 +00002822 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00002823 case CNTB:
2824#endif
2825
Scott Michel06eabde2008-12-27 04:51:36 +00002826 case SPUISD::PREFSLOT2VEC: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002827 SDValue Op0 = Op.getOperand(0);
Duncan Sands92c43912008-06-06 12:08:01 +00002828 MVT Op0VT = Op0.getValueType();
2829 unsigned Op0VTBits = Op0VT.getSizeInBits();
2830 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002831 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2832 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002833 break;
2834 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002835
Scott Michel97872d32008-02-23 18:41:37 +00002836 case SPUISD::LDRESULT:
Scott Michel6ccefab2008-12-04 03:02:42 +00002837 case SPUISD::VEC2PREFSLOT: {
Duncan Sands92c43912008-06-06 12:08:01 +00002838 MVT OpVT = Op.getValueType();
2839 unsigned OpVTBits = OpVT.getSizeInBits();
2840 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michelbc5fbc12008-04-30 00:30:08 +00002841 KnownZero |= APInt(OpVTBits, ~InMask, false);
2842 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michel97872d32008-02-23 18:41:37 +00002843 break;
2844 }
2845
2846#if 0
Scott Michelbc5fbc12008-04-30 00:30:08 +00002847 case SPUISD::SHLQUAD_L_BITS:
2848 case SPUISD::SHLQUAD_L_BYTES:
2849 case SPUISD::VEC_SHL:
2850 case SPUISD::VEC_SRL:
2851 case SPUISD::VEC_SRA:
2852 case SPUISD::VEC_ROTL:
2853 case SPUISD::VEC_ROTR:
Scott Michelbc5fbc12008-04-30 00:30:08 +00002854 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00002855 case SPUISD::SELECT_MASK:
2856 case SPUISD::SELB:
Scott Michel97872d32008-02-23 18:41:37 +00002857#endif
2858 }
Scott Michel8efdca42007-12-04 22:23:35 +00002859}
Scott Michel4d07fb72008-12-30 23:28:25 +00002860
Scott Michel06eabde2008-12-27 04:51:36 +00002861unsigned
2862SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2863 unsigned Depth) const {
2864 switch (Op.getOpcode()) {
2865 default:
2866 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00002867
Scott Michel06eabde2008-12-27 04:51:36 +00002868 case ISD::SETCC: {
2869 MVT VT = Op.getValueType();
2870
2871 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2872 VT = MVT::i32;
2873 }
2874 return VT.getSizeInBits();
2875 }
2876 }
2877}
Scott Michelae5cbf52008-12-29 03:23:36 +00002878
Scott Michelbc5fbc12008-04-30 00:30:08 +00002879// LowerAsmOperandForConstraint
2880void
Dan Gohman8181bd12008-07-27 21:46:04 +00002881SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002882 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00002883 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00002884 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002885 SelectionDAG &DAG) const {
2886 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00002887 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2888 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00002889}
2890
Scott Michel8efdca42007-12-04 22:23:35 +00002891/// isLegalAddressImmediate - Return true if the integer value can be used
2892/// as the offset of the target addressing mode.
Gabor Greife9f7f582008-08-31 15:37:04 +00002893bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2894 const Type *Ty) const {
Scott Michel8efdca42007-12-04 22:23:35 +00002895 // SPU's addresses are 256K:
2896 return (V > -(1 << 18) && V < (1 << 18) - 1);
2897}
2898
2899bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel4ec722e2008-07-16 17:17:29 +00002900 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00002901}
Dan Gohman36322c72008-10-18 02:06:02 +00002902
2903bool
2904SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
2905 // The SPU target isn't yet aware of offsets.
2906 return false;
2907}