blob: 92bd92886c3d2a809de0a8017755df8b6b8f471e [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michel203b2d62008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michelf0569be2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michel266bc8f2007-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 Lattner84bc5422007-12-31 04:13:23 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000025#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-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 Sands83ec4b62008-06-06 12:08:01 +000041 //! MVT mapping to useful data for Cell SPU
Scott Michel266bc8f2007-12-04 22:23:35 +000042 struct valtype_map_s {
Scott Michel7a1c9e92008-11-22 23:50:42 +000043 const MVT valtype;
44 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000045 };
Scott Michel5af8f0e2008-07-16 17:17:29 +000046
Scott Michel266bc8f2007-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 Sands83ec4b62008-06-06 12:08:01 +000060 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +000065 retval = valtype_map + i;
66 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000067 }
68 }
69
70#ifndef NDEBUG
71 if (retval == 0) {
72 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands83ec4b62008-06-06 12:08:01 +000073 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +000074 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000075 abort();
76 }
77#endif
78
79 return retval;
80 }
Scott Michel94bd57e2009-01-15 04:41:47 +000081
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +000094
Scott Michel266bc8f2007-12-04 22:23:35 +000095 // Set up the SPU's register classes:
Scott Michel504c3692007-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 Michel266bc8f2007-12-04 22:23:35 +0000102 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000103
Scott Michel266bc8f2007-12-04 22:23:35 +0000104 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng03294662008-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 Michel266bc8f2007-12-04 22:23:35 +0000108
Scott Michelf0569be2008-12-27 04:51:36 +0000109 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
110 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelb30e8f62008-12-02 19:53:53 +0000111
Scott Michel266bc8f2007-12-04 22:23:35 +0000112 // SPU constant load actions are custom lowered:
113 setOperationAction(ISD::Constant, MVT::i64, Custom);
Nate Begemanccef5802008-02-14 18:43:04 +0000114 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-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 Micheldd950092009-01-06 03:36:14 +0000118 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel266bc8f2007-12-04 22:23:35 +0000119 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000120 MVT VT = (MVT::SimpleValueType)sctype;
121
Scott Michelf0569be2008-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 Michel1df30c42008-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 Michelf0569be2008-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 Michel266bc8f2007-12-04 22:23:35 +0000136 }
137
Scott Michelf0569be2008-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 Michel266bc8f2007-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 Michel7a1c9e92008-11-22 23:50:42 +0000154
155 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel5af8f0e2008-07-16 17:17:29 +0000156 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-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 Michel266bc8f2007-12-04 22:23:35 +0000161
162 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000163 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
164
Scott Michelf0569be2008-12-27 04:51:36 +0000165 // SPU has no SREM/UREM instructions
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000170
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000178
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000182
Scott Michel266bc8f2007-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 Wendling9440e352008-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 Michel266bc8f2007-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 Micheldc91bea2008-11-20 16:36:33 +0000198
Scott Michel266bc8f2007-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 Michel9c0c6b22008-11-21 02:56:16 +0000203
Scott Michel02d711b2008-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 Michel266bc8f2007-12-04 22:23:35 +0000208
Scott Michel5af8f0e2008-07-16 17:17:29 +0000209 // Custom lower i8, i32 and i64 multiplications
210 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michel1df30c42008-12-29 03:23:36 +0000211 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel94bd57e2009-01-15 04:41:47 +0000212 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000213
Scott Michel8bf61e82008-06-02 22:18:03 +0000214 // Need to custom handle (some) common i8, i64 math ops
Scott Michel02d711b2008-12-30 23:28:25 +0000215 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000216 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000217 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000218 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000219
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000234
Scott Michel8bf61e82008-06-02 22:18:03 +0000235 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000236 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000237 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000238 setOperationAction(ISD::SELECT, MVT::i16, Legal);
239 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michelf0569be2008-12-27 04:51:36 +0000240 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000241
Scott Michel78c47fa2008-03-10 16:58:52 +0000242 setOperationAction(ISD::SETCC, MVT::i8, Legal);
243 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000244 setOperationAction(ISD::SETCC, MVT::i32, Legal);
245 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000246
Scott Michelf0569be2008-12-27 04:51:36 +0000247 // Custom lower i128 -> i64 truncates
Scott Michelb30e8f62008-12-02 19:53:53 +0000248 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
249
Scott Michel266bc8f2007-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 Michelf0569be2008-12-27 04:51:36 +0000257 setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall
Scott Michel266bc8f2007-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 Michel86c041f2007-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 Michel266bc8f2007-12-04 22:23:35 +0000273
274 // We cannot sextinreg(i1). Expand to shifts.
275 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000276
Scott Michel266bc8f2007-12-04 22:23:35 +0000277 // Support label based line numbers.
Dan Gohman7f460202008-06-30 20:59:49 +0000278 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000279 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000280
281 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel266bc8f2007-12-04 22:23:35 +0000282 // appropriate instructions to materialize the address.
Scott Michel9c0c6b22008-11-21 02:56:16 +0000283 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michel053c1da2008-01-29 02:16:57 +0000284 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000285 MVT VT = (MVT::SimpleValueType)sctype;
286
Scott Michel1df30c42008-12-29 03:23:36 +0000287 setOperationAction(ISD::GlobalAddress, VT, Custom);
288 setOperationAction(ISD::ConstantPool, VT, Custom);
289 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michel053c1da2008-01-29 02:16:57 +0000290 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000291
292 // RET must be custom lowered, to meet ABI requirements
293 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000294
Scott Michel266bc8f2007-12-04 22:23:35 +0000295 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
296 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000297
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000302 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +0000310
Scott Michel266bc8f2007-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 Michel21213e72009-01-06 23:10:38 +0000326 // "Odd size" vector classes that we're willing to support:
327 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
328
Duncan Sands83ec4b62008-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 Michel266bc8f2007-12-04 22:23:35 +0000332
Duncan Sands83ec4b62008-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 Michel02d711b2008-12-30 23:28:25 +0000337 // TODO: v2i64 vector multiply
338 setOperationAction(ISD::MUL , VT, Legal);
Duncan Sands83ec4b62008-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 Michel5af8f0e2008-07-16 17:17:29 +0000346
Scott Michel266bc8f2007-12-04 22:23:35 +0000347 // These operations need to be expanded:
Duncan Sands83ec4b62008-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 Michel266bc8f2007-12-04 22:23:35 +0000352
353 // Custom lower build_vector, constant pool spills, insert and
354 // extract vector elements:
Duncan Sands83ec4b62008-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 Michel266bc8f2007-12-04 22:23:35 +0000361 }
362
Scott Michel266bc8f2007-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 Michel9de5d0d2008-01-11 02:53:15 +0000367
Scott Michel02d711b2008-12-30 23:28:25 +0000368 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000369
Scott Michel266bc8f2007-12-04 22:23:35 +0000370 setShiftAmountType(MVT::i32);
Scott Michelf0569be2008-12-27 04:51:36 +0000371 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000372
Scott Michel266bc8f2007-12-04 22:23:35 +0000373 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000374
Scott Michel266bc8f2007-12-04 22:23:35 +0000375 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000376 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000377 setTargetDAGCombine(ISD::ZERO_EXTEND);
378 setTargetDAGCombine(ISD::SIGN_EXTEND);
379 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000380
Scott Michel266bc8f2007-12-04 22:23:35 +0000381 computeRegisterProperties();
Scott Michel7a1c9e92008-11-22 23:50:42 +0000382
Scott Michele07d3de2008-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 Michel266bc8f2007-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 Michel9de5d0d2008-01-11 02:53:15 +0000397 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000398 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-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 Michel7a1c9e92008-11-22 23:50:42 +0000402 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000403 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michel1df30c42008-12-29 03:23:36 +0000404 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michel104de432008-11-24 17:11:17 +0000405 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michela59d4692008-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 Michel266bc8f2007-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 Michel8bf61e82008-06-02 22:18:03 +0000413 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000414 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel94bd57e2009-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 Michel266bc8f2007-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 Michelf0569be2008-12-27 04:51:36 +0000425//===----------------------------------------------------------------------===//
426// Return the Cell SPU's SETCC result type
427//===----------------------------------------------------------------------===//
428
Duncan Sands5480c042009-01-01 15:52:00 +0000429MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michelf0569be2008-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 Michel78c47fa2008-03-10 16:58:52 +0000432}
433
Scott Michel266bc8f2007-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 Michel30ee7df2008-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 Michel1df30c42008-12-29 03:23:36 +0000453%1 v16i8,ch = load
Scott Michel30ee7df2008-12-04 03:02:42 +0000454%2 v16i8,ch = rotate %1
Scott Michel1df30c42008-12-29 03:23:36 +0000455%3 v4f8, ch = bitconvert %2
Scott Michel30ee7df2008-12-04 03:02:42 +0000456%4 f32 = vec2perfslot %3
457%5 f64 = fp_extend %4
458\endverbatim
459*/
Dan Gohman475871a2008-07-27 21:46:04 +0000460static SDValue
461LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000462 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000463 SDValue the_chain = LN->getChain();
Scott Michelf0569be2008-12-27 04:51:36 +0000464 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel30ee7df2008-12-04 03:02:42 +0000465 MVT InVT = LN->getMemoryVT();
466 MVT OutVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000467 ISD::LoadExtType ExtType = LN->getExtensionType();
468 unsigned alignment = LN->getAlignment();
Scott Michelf0569be2008-12-27 04:51:36 +0000469 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000470
Scott Michel266bc8f2007-12-04 22:23:35 +0000471 switch (LN->getAddressingMode()) {
472 case ISD::UNINDEXED: {
Scott Michelf0569be2008-12-27 04:51:36 +0000473 SDValue result;
474 SDValue basePtr = LN->getBasePtr();
475 SDValue rotate;
Scott Michel266bc8f2007-12-04 22:23:35 +0000476
Scott Michelf0569be2008-12-27 04:51:36 +0000477 if (alignment == 16) {
478 ConstantSDNode *CN;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000479
Scott Michelf0569be2008-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 Michel9de5d0d2008-01-11 02:53:15 +0000487
Scott Michelf0569be2008-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 Michel9de5d0d2008-01-11 02:53:15 +0000510 } else {
Scott Michelf0569be2008-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 Michel7f9ba9b2008-01-30 02:55:46 +0000518 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000519 }
Scott Michelf0569be2008-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 Michel9de5d0d2008-01-11 02:53:15 +0000527
Scott Michelf0569be2008-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 Michel266bc8f2007-12-04 22:23:35 +0000554 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000555
Scott Michelf0569be2008-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 Michel30ee7df2008-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 Michel5af8f0e2008-07-16 17:17:29 +0000573
Scott Michel30ee7df2008-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 Michel9de5d0d2008-01-11 02:53:15 +0000581
Scott Michel30ee7df2008-12-04 03:02:42 +0000582 if (OutVT.isFloatingPoint())
583 NewOpc = ISD::FP_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000584
Scott Michel30ee7df2008-12-04 03:02:42 +0000585 result = DAG.getNode(NewOpc, OutVT, result);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000586 }
587
Scott Michel30ee7df2008-12-04 03:02:42 +0000588 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman475871a2008-07-27 21:46:04 +0000589 SDValue retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000590 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000591 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000592 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000593
Scott Michel58c58182008-01-17 20:38:41 +0000594 result = DAG.getNode(SPUISD::LDRESULT, retvts,
595 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000596 return result;
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +0000610 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +0000619static SDValue
620LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000621 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000622 SDValue Value = SN->getValue();
Duncan Sands83ec4b62008-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 Michel9de5d0d2008-01-11 02:53:15 +0000626 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000627
628 switch (SN->getAddressingMode()) {
629 case ISD::UNINDEXED: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000630 // The vector type we really want to load from the 16-byte chunk.
Scott Michel719b0e12008-11-19 17:45:08 +0000631 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
632 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +0000633
Scott Michelf0569be2008-12-27 04:51:36 +0000634 SDValue alignLoadVec;
635 SDValue basePtr = SN->getBasePtr();
636 SDValue the_chain = SN->getChain();
637 SDValue insertEltOffs;
Scott Michel266bc8f2007-12-04 22:23:35 +0000638
Scott Michelf0569be2008-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 Michel266bc8f2007-12-04 22:23:35 +0000708
Scott Michel9de5d0d2008-01-11 02:53:15 +0000709 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman475871a2008-07-27 21:46:04 +0000710 SDValue theValue = SN->getValue();
711 SDValue result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000712
713 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000714 && (theValue.getOpcode() == ISD::AssertZext
715 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000716 // Drill down and get the value for zero- and sign-extended
717 // quantities
Scott Michel5af8f0e2008-07-16 17:17:29 +0000718 theValue = theValue.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000719 }
720
Scott Michel9de5d0d2008-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 Michelf0569be2008-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 Michel9de5d0d2008-01-11 02:53:15 +0000732
Scott Michel430a5552008-11-19 15:24:16 +0000733 SDValue insertEltOp =
Scott Michelf0569be2008-12-27 04:51:36 +0000734 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michel719b0e12008-11-19 17:45:08 +0000735 SDValue vectorizeOp =
736 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michel430a5552008-11-19 15:24:16 +0000737
Scott Michel1a6cdb62008-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 Michel266bc8f2007-12-04 22:23:35 +0000741
Scott Michel9de5d0d2008-01-11 02:53:15 +0000742 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000743 LN->getSrcValue(), LN->getSrcValueOffset(),
744 LN->isVolatile(), LN->getAlignment());
745
Scott Michel23f2ff72008-12-04 17:16:59 +0000746#if 0 && !defined(NDEBUG)
Scott Michel430a5552008-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 Michelb30e8f62008-12-02 19:53:53 +0000757
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +0000773 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000774}
775
Scott Michel94bd57e2009-01-15 04:41:47 +0000776//! Generate the address of a constant pool entry.
777SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000778LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000779 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000780 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
781 Constant *C = CP->getConstVal();
Dan Gohman475871a2008-07-27 21:46:04 +0000782 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
783 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000784 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000785
786 if (TM.getRelocationModel() == Reloc::Static) {
787 if (!ST->usingLargeMem()) {
Dan Gohman475871a2008-07-27 21:46:04 +0000788 // Just return the SDValue with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000789 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000790 } else {
Dan Gohman475871a2008-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 Michela59d4692008-02-23 18:41:37 +0000793 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000794 }
795 }
796
797 assert(0 &&
Gabor Greif93c53e52008-08-31 15:37:04 +0000798 "LowerConstantPool: Relocation model other than static"
799 " not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000800 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000801}
802
Scott Michel94bd57e2009-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 Gohman475871a2008-07-27 21:46:04 +0000809static SDValue
810LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000811 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000812 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000813 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
814 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000815 const TargetMachine &TM = DAG.getTarget();
816
817 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000818 if (!ST->usingLargeMem()) {
819 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
820 } else {
Dan Gohman475871a2008-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 Michela59d4692008-02-23 18:41:37 +0000823 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
824 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000825 }
826
827 assert(0 &&
828 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000829 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000830}
831
Dan Gohman475871a2008-07-27 21:46:04 +0000832static SDValue
833LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000834 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000835 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
836 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman475871a2008-07-27 21:46:04 +0000837 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000838 const TargetMachine &TM = DAG.getTarget();
Dan Gohman475871a2008-07-27 21:46:04 +0000839 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000840
Scott Michel266bc8f2007-12-04 22:23:35 +0000841 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000842 if (!ST->usingLargeMem()) {
843 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
844 } else {
Dan Gohman475871a2008-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 Michel053c1da2008-01-29 02:16:57 +0000847 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
848 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000849 } else {
850 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000851 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000852 abort();
853 /*NOTREACHED*/
854 }
855
Dan Gohman475871a2008-07-27 21:46:04 +0000856 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +0000864static SDValue
865LowerConstant(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000866 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000867
868 if (VT == MVT::i64) {
Scott Michel1a6cdb62008-12-01 17:56:02 +0000869 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
870 SDValue T = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel104de432008-11-24 17:11:17 +0000871 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000872 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +0000873 } else {
874 cerr << "LowerConstant: unhandled constant type "
Duncan Sands83ec4b62008-06-06 12:08:01 +0000875 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000876 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000877 abort();
878 /*NOTREACHED*/
879 }
880
Dan Gohman475871a2008-07-27 21:46:04 +0000881 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000882}
883
Nate Begemanccef5802008-02-14 18:43:04 +0000884//! Custom lower double precision floating point constants
Dan Gohman475871a2008-07-27 21:46:04 +0000885static SDValue
886LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000887 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000888
Nate Begemanccef5802008-02-14 18:43:04 +0000889 if (VT == MVT::f64) {
Scott Michel1a6cdb62008-12-01 17:56:02 +0000890 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
891
892 assert((FP != 0) &&
893 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel1df30c42008-12-29 03:23:36 +0000894
Scott Michel170783a2007-12-19 20:15:47 +0000895 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel1a6cdb62008-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 Michel266bc8f2007-12-04 22:23:35 +0000900 }
901
Dan Gohman475871a2008-07-27 21:46:04 +0000902 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000903}
904
Dan Gohman475871a2008-07-27 21:46:04 +0000905static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000906LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel266bc8f2007-12-04 22:23:35 +0000907{
908 MachineFunction &MF = DAG.getMachineFunction();
909 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000910 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Micheld976c212008-10-30 01:51:48 +0000911 SmallVector<SDValue, 48> ArgValues;
Dan Gohman475871a2008-07-27 21:46:04 +0000912 SDValue Root = Op.getOperand(0);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000913 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel266bc8f2007-12-04 22:23:35 +0000914
915 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
916 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000917
Scott Michel266bc8f2007-12-04 22:23:35 +0000918 unsigned ArgOffset = SPUFrameInfo::minStackSize();
919 unsigned ArgRegIdx = 0;
920 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000921
Duncan Sands83ec4b62008-06-06 12:08:01 +0000922 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000923
Scott Michel266bc8f2007-12-04 22:23:35 +0000924 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif93c53e52008-08-31 15:37:04 +0000925 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
926 ArgNo != e; ++ArgNo) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000927 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
928 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Micheld976c212008-10-30 01:51:48 +0000929 SDValue ArgVal;
Scott Michel266bc8f2007-12-04 22:23:35 +0000930
Scott Micheld976c212008-10-30 01:51:48 +0000931 if (ArgRegIdx < NumArgRegs) {
932 const TargetRegisterClass *ArgRegClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +0000933
Scott Micheld976c212008-10-30 01:51:48 +0000934 switch (ObjectVT.getSimpleVT()) {
935 default: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000936 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
937 << ObjectVT.getMVTString()
938 << "\n";
939 abort();
Scott Micheld976c212008-10-30 01:51:48 +0000940 }
941 case MVT::i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000942 ArgRegClass = &SPU::R8CRegClass;
943 break;
Scott Micheld976c212008-10-30 01:51:48 +0000944 case MVT::i16:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000945 ArgRegClass = &SPU::R16CRegClass;
946 break;
Scott Micheld976c212008-10-30 01:51:48 +0000947 case MVT::i32:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000948 ArgRegClass = &SPU::R32CRegClass;
949 break;
Scott Micheld976c212008-10-30 01:51:48 +0000950 case MVT::i64:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000951 ArgRegClass = &SPU::R64CRegClass;
952 break;
Scott Micheldd950092009-01-06 03:36:14 +0000953 case MVT::i128:
954 ArgRegClass = &SPU::GPRCRegClass;
955 break;
Scott Micheld976c212008-10-30 01:51:48 +0000956 case MVT::f32:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000957 ArgRegClass = &SPU::R32FPRegClass;
958 break;
Scott Micheld976c212008-10-30 01:51:48 +0000959 case MVT::f64:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000960 ArgRegClass = &SPU::R64FPRegClass;
961 break;
Scott Micheld976c212008-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 Michel9c0c6b22008-11-21 02:56:16 +0000968 ArgRegClass = &SPU::VECREGRegClass;
969 break;
Scott Micheld976c212008-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 Lattner9f72d1a2008-02-13 07:35:30 +0000980 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000981 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner9f72d1a2008-02-13 07:35:30 +0000982 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000983 ArgOffset += StackSlotSize;
984 }
Scott Michel5af8f0e2008-07-16 17:17:29 +0000985
Scott Michel266bc8f2007-12-04 22:23:35 +0000986 ArgValues.push_back(ArgVal);
Scott Micheld976c212008-10-30 01:51:48 +0000987 // Update the chain
988 Root = ArgVal.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000989 }
Scott Michel5af8f0e2008-07-16 17:17:29 +0000990
Scott Micheld976c212008-10-30 01:51:48 +0000991 // vararg handling:
Scott Michel266bc8f2007-12-04 22:23:35 +0000992 if (isVarArg) {
Scott Micheld976c212008-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 Michel266bc8f2007-12-04 22:23:35 +0000999 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Micheld976c212008-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 Michel266bc8f2007-12-04 22:23:35 +00001005 MemOps.push_back(Store);
Scott Micheld976c212008-10-30 01:51:48 +00001006
1007 // Increment address by stack slot size for the next stored argument
1008 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001009 }
1010 if (!MemOps.empty())
Scott Micheld976c212008-10-30 01:51:48 +00001011 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001012 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001013
Scott Michel266bc8f2007-12-04 22:23:35 +00001014 ArgValues.push_back(Root);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001015
Scott Michel266bc8f2007-12-04 22:23:35 +00001016 // Return the new list of results.
Duncan Sandsaaffa052008-12-01 11:41:29 +00001017 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1018 &ArgValues[0], ArgValues.size());
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001023static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001024 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +00001025 if (!C) return 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001026
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001027 int Addr = C->getZExtValue();
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001031
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001032 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel266bc8f2007-12-04 22:23:35 +00001033}
1034
Scott Michel21213e72009-01-06 23:10:38 +00001035static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +00001036LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman095cc292008-09-13 01:54:27 +00001037 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1038 SDValue Chain = TheCall->getChain();
Dan Gohman095cc292008-09-13 01:54:27 +00001039 SDValue Callee = TheCall->getCallee();
1040 unsigned NumOps = TheCall->getNumArgs();
Scott Michel266bc8f2007-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 Sands83ec4b62008-06-06 12:08:01 +00001046 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001047
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001052
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001056 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001057
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001064 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel266bc8f2007-12-04 22:23:35 +00001065 // And the arguments passed on the stack
Dan Gohman475871a2008-07-27 21:46:04 +00001066 SmallVector<SDValue, 8> MemOpChains;
Scott Michel266bc8f2007-12-04 22:23:35 +00001067
1068 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman095cc292008-09-13 01:54:27 +00001069 SDValue Arg = TheCall->getArg(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001070
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001073 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001074 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1075
Duncan Sands83ec4b62008-06-06 12:08:01 +00001076 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001077 default: assert(0 && "Unexpected ValueType for argument!");
Scott Micheldd950092009-01-06 03:36:14 +00001078 case MVT::i8:
1079 case MVT::i16:
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001087 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001096 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001097 }
1098 break;
Scott Michelcc188272008-12-04 21:01:44 +00001099 case MVT::v2i64:
1100 case MVT::v2f64:
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001109 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-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 Lattnere563bbc2008-10-11 22:08:30 +00001117 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1118 true));
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001125
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001128 SDValue InFlag;
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001134
Dan Gohman475871a2008-07-27 21:46:04 +00001135 SmallVector<SDValue, 8> Ops;
Scott Michel266bc8f2007-12-04 22:23:35 +00001136 unsigned CallOpc = SPUISD::CALL;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001137
Bill Wendling056292f2008-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 Michel19fd42a2008-11-11 03:06:06 +00001141 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001142 GlobalValue *GV = G->getGlobal();
Duncan Sands83ec4b62008-06-06 12:08:01 +00001143 MVT CalleeVT = Callee.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001144 SDValue Zero = DAG.getConstant(0, PtrVT);
1145 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001146
Scott Michel9de5d0d2008-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 Michel266bc8f2007-12-04 22:23:35 +00001161 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001162 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1163 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001164 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001165 }
Scott Michel1df30c42008-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 Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001180 Callee = SDValue(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001181 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001182
1183 Ops.push_back(Chain);
1184 Ops.push_back(Callee);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001185
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001189 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel266bc8f2007-12-04 22:23:35 +00001190 RegsToPass[i].second.getValueType()));
Scott Michel5af8f0e2008-07-16 17:17:29 +00001191
Gabor Greifba36cb52008-08-28 21:40:38 +00001192 if (InFlag.getNode())
Scott Michel266bc8f2007-12-04 22:23:35 +00001193 Ops.push_back(InFlag);
Duncan Sands4bdcb612008-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 Michel266bc8f2007-12-04 22:23:35 +00001197 InFlag = Chain.getValue(1);
1198
Chris Lattnere563bbc2008-10-11 22:08:30 +00001199 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1200 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman095cc292008-09-13 01:54:27 +00001201 if (TheCall->getValueType(0) != MVT::Other)
Evan Chengebaaa912008-02-05 22:44:06 +00001202 InFlag = Chain.getValue(1);
1203
Dan Gohman475871a2008-07-27 21:46:04 +00001204 SDValue ResultVals[3];
Scott Michel266bc8f2007-12-04 22:23:35 +00001205 unsigned NumResults = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001206
Scott Michel266bc8f2007-12-04 22:23:35 +00001207 // If the call has results, copy the values out of the ret val registers.
Dan Gohman095cc292008-09-13 01:54:27 +00001208 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001209 default: assert(0 && "Unexpected ret value!");
1210 case MVT::Other: break;
1211 case MVT::i32:
Dan Gohman095cc292008-09-13 01:54:27 +00001212 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel266bc8f2007-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 Michel266bc8f2007-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 Michel266bc8f2007-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 Michel266bc8f2007-12-04 22:23:35 +00001229 break;
Scott Micheldd950092009-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 Michel266bc8f2007-12-04 22:23:35 +00001235 case MVT::f32:
1236 case MVT::f64:
Dan Gohman095cc292008-09-13 01:54:27 +00001237 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001238 InFlag).getValue(1);
1239 ResultVals[0] = Chain.getValue(0);
1240 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001241 break;
1242 case MVT::v2f64:
Scott Michelcc188272008-12-04 21:01:44 +00001243 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001244 case MVT::v4f32:
1245 case MVT::v4i32:
1246 case MVT::v8i16:
1247 case MVT::v16i8:
Dan Gohman095cc292008-09-13 01:54:27 +00001248 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001249 InFlag).getValue(1);
1250 ResultVals[0] = Chain.getValue(0);
1251 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001252 break;
1253 }
Duncan Sands4bdcb612008-07-02 17:40:58 +00001254
Scott Michel266bc8f2007-12-04 22:23:35 +00001255 // If the function returns void, just return the chain.
1256 if (NumResults == 0)
1257 return Chain;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001258
Scott Michel266bc8f2007-12-04 22:23:35 +00001259 // Otherwise, merge everything together with a MERGE_VALUES node.
1260 ResultVals[NumResults++] = Chain;
Dan Gohman475871a2008-07-27 21:46:04 +00001261 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif99a6cb92008-08-26 22:36:50 +00001262 return Res.getValue(Op.getResNo());
Scott Michel266bc8f2007-12-04 22:23:35 +00001263}
1264
Dan Gohman475871a2008-07-27 21:46:04 +00001265static SDValue
1266LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel266bc8f2007-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 Greifba36cb52008-08-28 21:40:38 +00001271 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001272
Scott Michel266bc8f2007-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 Lattner84bc5422007-12-31 04:13:23 +00001275 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001276 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001277 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001278 }
1279
Dan Gohman475871a2008-07-27 21:46:04 +00001280 SDValue Chain = Op.getOperand(0);
1281 SDValue Flag;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001282
Scott Michel266bc8f2007-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 Greifba36cb52008-08-28 21:40:38 +00001291 if (Flag.getNode())
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001304 SDValue OpVal(0, 0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001305
Scott Michel266bc8f2007-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 Greifba36cb52008-08-28 21:40:38 +00001309 if (OpVal.getNode() == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +00001310 OpVal = N->getOperand(i);
1311 else if (OpVal != N->getOperand(i))
1312 return 0;
1313 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001314
Gabor Greifba36cb52008-08-28 21:40:38 +00001315 if (OpVal.getNode() != 0) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001316 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001327SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001328 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001329 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001330 uint64_t Value = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001331 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001332 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-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 Gohman475871a2008-07-27 21:46:04 +00001336 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001337 Value = Value >> 32;
1338 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001339 if (Value <= 0x3ffff)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001340 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001341 }
1342
Dan Gohman475871a2008-07-27 21:46:04 +00001343 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001349SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001350 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001351 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001352 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001353 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001354 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-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 Gohman475871a2008-07-27 21:46:04 +00001358 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001359 Value = Value >> 32;
1360 }
Scott Michelad2715e2008-03-05 23:02:02 +00001361 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001362 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001363 }
1364 }
1365
Dan Gohman475871a2008-07-27 21:46:04 +00001366 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001372SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001373 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001374 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001375 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001376 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001377 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-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 Gohman475871a2008-07-27 21:46:04 +00001381 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001382 Value = Value >> 32;
1383 }
Scott Michelad2715e2008-03-05 23:02:02 +00001384 if (isS10Constant(Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001385 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001386 }
1387
Dan Gohman475871a2008-07-27 21:46:04 +00001388 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001398SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001399 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001400 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001401 int Value = (int) CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001402 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001403 && Value <= 0xffff /* truncated from uint64_t */
1404 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001405 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001406 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001407 && (Value & 0xff) == Value)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001408 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001409 }
1410
Dan Gohman475871a2008-07-27 21:46:04 +00001411 return SDValue();
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001417SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001418 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001419 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001420 uint64_t Value = CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001421 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001422 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1423 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001424 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001425 }
1426
Dan Gohman475871a2008-07-27 21:46:04 +00001427 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001428}
1429
1430/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001431SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001432 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001433 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001434 }
1435
Dan Gohman475871a2008-07-27 21:46:04 +00001436 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001437}
1438
1439/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001440SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001441 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001442 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001443 }
1444
Dan Gohman475871a2008-07-27 21:46:04 +00001445 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001446}
1447
1448// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel5af8f0e2008-07-16 17:17:29 +00001449// UndefBits is set if the corresponding element of the vector is an
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001457
Duncan Sands83ec4b62008-06-06 12:08:01 +00001458 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel266bc8f2007-12-04 22:23:35 +00001459 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman475871a2008-07-27 21:46:04 +00001460 SDValue OpVal = BV->getOperand(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001461
Scott Michel266bc8f2007-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 Michel19fd42a2008-11-11 03:06:06 +00001470 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001471 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel19fd42a2008-11-11 03:06:06 +00001472 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001473 const APFloat &apf = CN->getValueAPF();
1474 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001475 ? FloatToBits(apf.convertToFloat())
1476 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001477 } else {
1478 // Nonconstant element.
1479 return true;
1480 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001481
Scott Michel266bc8f2007-12-04 22:23:35 +00001482 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1483 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001484
1485 //printf("%llx %llx %llx %llx\n",
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001492/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel266bc8f2007-12-04 22:23:35 +00001493/// SplatSize = 1 byte.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001494static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel266bc8f2007-12-04 22:23:35 +00001495 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001496 int MinSplatBits,
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001510
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001514 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001515
Scott Michel7f9ba9b2008-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 Greif93c53e52008-08-31 15:37:04 +00001522 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1523 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel7f9ba9b2008-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 Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001560static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001561 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001562 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel5af8f0e2008-07-16 17:17:29 +00001563 // UndefBits is set if the corresponding element of the vector is an
Scott Michel266bc8f2007-12-04 22:23:35 +00001564 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel5af8f0e2008-07-16 17:17:29 +00001565 // zero.
Scott Michel266bc8f2007-12-04 22:23:35 +00001566 uint64_t VectorBits[2];
1567 uint64_t UndefBits[2];
1568 uint64_t SplatBits, SplatUndef;
1569 int SplatSize;
Gabor Greifba36cb52008-08-28 21:40:38 +00001570 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel266bc8f2007-12-04 22:23:35 +00001571 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001572 VT.getVectorElementType().getSizeInBits(),
Scott Michel266bc8f2007-12-04 22:23:35 +00001573 SplatBits, SplatUndef, SplatSize))
Dan Gohman475871a2008-07-27 21:46:04 +00001574 return SDValue(); // Not a constant vector, not a splat.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001575
Duncan Sands83ec4b62008-06-06 12:08:01 +00001576 switch (VT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001577 default:
1578 case MVT::v4f32: {
1579 uint32_t Value32 = SplatBits;
1580 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001581 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001582 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001583 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001584 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001585 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001586 break;
1587 }
1588 case MVT::v2f64: {
1589 uint64_t f64val = SplatBits;
1590 assert(SplatSize == 8
Scott Michel104de432008-11-24 17:11:17 +00001591 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001592 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001593 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001594 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001595 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001601 SDValue Ops[8];
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00001609 if (SplatSize == 2)
Scott Michel266bc8f2007-12-04 22:23:35 +00001610 Value16 = (unsigned short) (SplatBits & 0xffff);
1611 else
1612 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman475871a2008-07-27 21:46:04 +00001613 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1614 SDValue Ops[8];
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00001620 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001621 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1622 }
Scott Michel21213e72009-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 Michel266bc8f2007-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 Michel4cb8bd82008-03-06 04:02:54 +00001633 if (upper == lower) {
1634 // Magic constant that can be matched by IL, ILA, et. al.
Dan Gohman475871a2008-07-27 21:46:04 +00001635 SDValue Val = DAG.getTargetConstant(val, MVT::i64);
Scott Michel4cb8bd82008-03-06 04:02:54 +00001636 return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val);
Scott Michelad2715e2008-03-05 23:02:02 +00001637 } else {
Dan Gohman475871a2008-07-27 21:46:04 +00001638 SDValue LO32;
1639 SDValue HI32;
1640 SmallVector<SDValue, 16> ShufBytes;
1641 SDValue Result;
Scott Michel266bc8f2007-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 Michel104de432008-11-24 17:11:17 +00001649 upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000);
1650 lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000);
Scott Michel266bc8f2007-12-04 22:23:35 +00001651
1652 // Create lower vector if not a special pattern
1653 if (!lower_special) {
Dan Gohman475871a2008-07-27 21:46:04 +00001654 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Scott Michel7f9ba9b2008-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 Michel266bc8f2007-12-04 22:23:35 +00001658 }
1659
1660 // Create upper vector if not a special pattern
1661 if (!upper_special) {
Dan Gohman475871a2008-07-27 21:46:04 +00001662 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Scott Michel7f9ba9b2008-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 Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001671 LO32 = HI32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001672 if (upper_special)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001673 HI32 = LO32;
Scott Michel266bc8f2007-12-04 22:23:35 +00001674 if (lower_special && upper_special) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001675 // Unhappy situation... both upper and lower are special, so punt with
1676 // a target constant:
Dan Gohman475871a2008-07-27 21:46:04 +00001677 SDValue Zero = DAG.getConstant(0, MVT::i32);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001678 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
Scott Michel266bc8f2007-12-04 22:23:35 +00001679 Zero, Zero);
1680 }
1681
1682 for (int i = 0; i < 4; ++i) {
Scott Michel8bf61e82008-06-02 22:18:03 +00001683 uint64_t val = 0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001684 for (int j = 0; j < 4; ++j) {
Dan Gohman475871a2008-07-27 21:46:04 +00001685 SDValue V;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001686 bool process_upper, process_lower;
Scott Michel8bf61e82008-06-02 22:18:03 +00001687 val <<= 8;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001688 process_upper = (upper_special && (i & 1) == 0);
1689 process_lower = (lower_special && (i & 1) == 1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001690
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001691 if (process_upper || process_lower) {
1692 if ((process_upper && upper == 0)
1693 || (process_lower && lower == 0))
Scott Michel8bf61e82008-06-02 22:18:03 +00001694 val |= 0x80;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001695 else if ((process_upper && upper == 0xffffffff)
1696 || (process_lower && lower == 0xffffffff))
Scott Michel8bf61e82008-06-02 22:18:03 +00001697 val |= 0xc0;
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001698 else if ((process_upper && upper == 0x80000000)
1699 || (process_lower && lower == 0x80000000))
Scott Michel8bf61e82008-06-02 22:18:03 +00001700 val |= (j == 0 ? 0xe0 : 0x80);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001701 } else
Scott Michel8bf61e82008-06-02 22:18:03 +00001702 val |= i * 4 + j + ((i & 1) * 16);
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001703 }
Scott Michel8bf61e82008-06-02 22:18:03 +00001704
1705 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00001706 }
1707
1708 return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
Scott Michel8bf61e82008-06-02 22:18:03 +00001709 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001710 &ShufBytes[0], ShufBytes.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001711 }
1712 }
1713 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001714
Dan Gohman475871a2008-07-27 21:46:04 +00001715 return SDValue();
Scott Michel266bc8f2007-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 Michel7a1c9e92008-11-22 23:50:42 +00001722/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel266bc8f2007-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 Michel7a1c9e92008-11-22 23:50:42 +00001726/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel266bc8f2007-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 Gohman475871a2008-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 Michel5af8f0e2008-07-16 17:17:29 +00001735
Scott Michel266bc8f2007-12-04 22:23:35 +00001736 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001737
Scott Michel266bc8f2007-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 Michelcc188272008-12-04 21:01:44 +00001741 MVT VecVT = V1.getValueType();
1742 MVT EltVT = VecVT.getVectorElementType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001743 unsigned EltsFromV2 = 0;
1744 unsigned V2Elt = 0;
1745 unsigned V2EltIdx0 = 0;
1746 unsigned CurrElt = 0;
Scott Michelcc188272008-12-04 21:01:44 +00001747 unsigned MaxElts = VecVT.getVectorNumElements();
1748 unsigned PrevElt = 0;
1749 unsigned V0Elt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001750 bool monotonic = true;
Scott Michelcc188272008-12-04 21:01:44 +00001751 bool rotate = true;
1752
1753 if (EltVT == MVT::i8) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001754 V2EltIdx0 = 16;
Scott Michelcc188272008-12-04 21:01:44 +00001755 } else if (EltVT == MVT::i16) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001756 V2EltIdx0 = 8;
Scott Michelcc188272008-12-04 21:01:44 +00001757 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001758 V2EltIdx0 = 4;
Scott Michelcc188272008-12-04 21:01:44 +00001759 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1760 V2EltIdx0 = 2;
1761 } else
Scott Michel266bc8f2007-12-04 22:23:35 +00001762 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1763
Scott Michelcc188272008-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 Michel266bc8f2007-12-04 22:23:35 +00001767
Scott Michelcc188272008-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 Michel266bc8f2007-12-04 22:23:35 +00001798 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001799 }
1800
1801 if (EltsFromV2 == 1 && monotonic) {
1802 // Compute mask and shuffle
1803 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001804 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1805 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands83ec4b62008-06-06 12:08:01 +00001806 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001807 // Initialize temporary register to 0
Dan Gohman475871a2008-07-27 21:46:04 +00001808 SDValue InitTempReg =
Scott Michel266bc8f2007-12-04 22:23:35 +00001809 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001810 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman475871a2008-07-27 21:46:04 +00001811 SDValue ShufMaskOp =
Scott Michel1a6cdb62008-12-01 17:56:02 +00001812 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001813 DAG.getTargetConstant(V2Elt, MVT::i32),
1814 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-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 Michelcc188272008-12-04 21:01:44 +00001817 } else if (rotate) {
1818 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michel1df30c42008-12-29 03:23:36 +00001819
Scott Michelcc188272008-12-04 21:01:44 +00001820 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1821 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001822 } else {
Gabor Greif93c53e52008-08-31 15:37:04 +00001823 // Convert the SHUFFLE_VECTOR mask's input element units to the
1824 // actual bytes.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001825 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001826
Dan Gohman475871a2008-07-27 21:46:04 +00001827 SmallVector<SDValue, 16> ResultMask;
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001831 SrcElt = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001832 else
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001833 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001834
Scott Michela59d4692008-02-23 18:41:37 +00001835 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001836 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1837 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001838 }
1839 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001840
Dan Gohman475871a2008-07-27 21:46:04 +00001841 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel1a6cdb62008-12-01 17:56:02 +00001842 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001843 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1844 }
1845}
1846
Dan Gohman475871a2008-07-27 21:46:04 +00001847static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1848 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001849
Gabor Greifba36cb52008-08-28 21:40:38 +00001850 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel266bc8f2007-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 Greifba36cb52008-08-28 21:40:38 +00001854 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman475871a2008-07-27 21:46:04 +00001855 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001856 MVT VT;
Scott Michel266bc8f2007-12-04 22:23:35 +00001857 size_t n_copies;
1858
1859 // Create a constant vector:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001860 switch (Op.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001861 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001862 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-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 Gohmanf5aeb1a2008-09-12 16:56:44 +00001871 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00001876 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001877 } else {
1878 // Otherwise, copy the value from one register to another:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001879 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-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 Michelf0569be2008-12-27 04:51:36 +00001887 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001888 }
1889 }
1890
Dan Gohman475871a2008-07-27 21:46:04 +00001891 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001892}
1893
Dan Gohman475871a2008-07-27 21:46:04 +00001894static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001895 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001896 SDValue N = Op.getOperand(0);
1897 SDValue Elt = Op.getOperand(1);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001898 SDValue retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00001899
Scott Michel7a1c9e92008-11-22 23:50:42 +00001900 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1901 // Constant argument:
1902 int EltNo = (int) C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001903
Scott Michel7a1c9e92008-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 Michel266bc8f2007-12-04 22:23:35 +00001913
Scott Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00001916 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001917 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001918
Scott Michel7a1c9e92008-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 Michelcc188272008-12-04 21:01:44 +00001967 unsigned bidx = i * 4;
Scott Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00001979 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00001997 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1998 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel7a1c9e92008-11-22 23:50:42 +00001999 SDValue vecShift;
Scott Michel7a1c9e92008-11-22 23:50:42 +00002000
Scott Michel104de432008-11-24 17:11:17 +00002001 if (scaleShift > 0) {
2002 // Scale the shift factor:
Scott Michel7a1c9e92008-11-22 23:50:42 +00002003 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002004 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel7a1c9e92008-11-22 23:50:42 +00002005 }
2006
Scott Michel104de432008-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 Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00002019 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00002025 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel7a1c9e92008-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 Michel104de432008-11-24 17:11:17 +00002047 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002048 DAG.getNode(SPUISD::SHUFB, VecVT,
2049 vecShift, vecShift, replicate));
Scott Michel266bc8f2007-12-04 22:23:35 +00002050 }
2051
Scott Michel7a1c9e92008-11-22 23:50:42 +00002052 return retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00002053}
2054
Dan Gohman475871a2008-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 Sands83ec4b62008-06-06 12:08:01 +00002059 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-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 Sands83ec4b62008-06-06 12:08:01 +00002064 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel1a6cdb62008-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 Michel266bc8f2007-12-04 22:23:35 +00002070
Dan Gohman475871a2008-07-27 21:46:04 +00002071 SDValue result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002072 DAG.getNode(SPUISD::SHUFB, VT,
2073 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michel1df30c42008-12-29 03:23:36 +00002074 VecOp,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002075 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00002076
2077 return result;
2078}
2079
Scott Michelf0569be2008-12-27 04:51:36 +00002080static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2081 const TargetLowering &TLI)
Scott Michela59d4692008-02-23 18:41:37 +00002082{
Dan Gohman475871a2008-07-27 21:46:04 +00002083 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michelf0569be2008-12-27 04:51:36 +00002084 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel266bc8f2007-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 Michel02d711b2008-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 Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00002106 SDValue N1 = Op.getOperand(1);
Scott Michel02d711b2008-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 Michel5af8f0e2008-07-16 17:17:29 +00002109 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002110 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002111 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002112 case ISD::ROTR:
2113 case ISD::ROTL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002114 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002115 unsigned N1Opc;
2116 N0 = (N0.getOpcode() != ISD::Constant
2117 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002118 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2119 MVT::i16));
Scott Michelf0569be2008-12-27 04:51:36 +00002120 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002121 ? ISD::ZERO_EXTEND
2122 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002123 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002124 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002125 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002126 TLI.getShiftAmountTy()));
Dan Gohman475871a2008-07-27 21:46:04 +00002127 SDValue ExpandArg =
Scott Michel266bc8f2007-12-04 22:23:35 +00002128 DAG.getNode(ISD::OR, MVT::i16, N0,
2129 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002130 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002131 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002132 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2133 }
2134 case ISD::SRL:
2135 case ISD::SHL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002136 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002137 unsigned N1Opc;
2138 N0 = (N0.getOpcode() != ISD::Constant
2139 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002140 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002141 MVT::i32));
2142 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002143 ? ISD::ZERO_EXTEND
2144 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002145 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002146 ? DAG.getNode(N1Opc, ShiftVT, N1)
2147 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002148 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002149 DAG.getNode(Opc, MVT::i16, N0, N1));
2150 }
2151 case ISD::SRA: {
Dan Gohman475871a2008-07-27 21:46:04 +00002152 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002153 unsigned N1Opc;
2154 N0 = (N0.getOpcode() != ISD::Constant
2155 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michelf0569be2008-12-27 04:51:36 +00002156 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002157 MVT::i16));
Scott Michelf0569be2008-12-27 04:51:36 +00002158 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002159 ? ISD::SIGN_EXTEND
2160 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002161 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002162 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002163 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002164 ShiftVT));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002165 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002166 DAG.getNode(Opc, MVT::i16, N0, N1));
2167 }
2168 case ISD::MUL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002169 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002170 unsigned N1Opc;
2171 N0 = (N0.getOpcode() != ISD::Constant
2172 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002173 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2174 MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002175 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002176 N1 = (N1.getOpcode() != ISD::Constant
2177 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michelf0569be2008-12-27 04:51:36 +00002178 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002179 MVT::i16));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002180 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002181 DAG.getNode(Opc, MVT::i16, N0, N1));
2182 break;
2183 }
2184 }
2185
Dan Gohman475871a2008-07-27 21:46:04 +00002186 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002187}
2188
Scott Michel94bd57e2009-01-15 04:41:47 +00002189//! Generate the carry-generate shuffle mask.
2190SDValue SPU::getCarryGenerateShufMask(SelectionDAG &DAG) {
2191SmallVector<SDValue, 16> ShufBytes;
Scott Michela59d4692008-02-23 18:41:37 +00002192
Scott Michel94bd57e2009-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 Michela59d4692008-02-23 18:41:37 +00002199
Scott Michel94bd57e2009-01-15 04:41:47 +00002200return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2201 &ShufBytes[0], ShufBytes.size());
2202}
Scott Michela59d4692008-02-23 18:41:37 +00002203
Scott Michel94bd57e2009-01-15 04:41:47 +00002204//! Generate the borrow-generate shuffle mask
2205SDValue SPU::getBorrowGenerateShufMask(SelectionDAG &DAG) {
2206SmallVector<SDValue, 16> ShufBytes;
Scott Michela59d4692008-02-23 18:41:37 +00002207
Scott Michel94bd57e2009-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 Michel045a1452008-11-24 18:20:46 +00002214
Scott Michel94bd57e2009-01-15 04:41:47 +00002215return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2216 &ShufBytes[0], ShufBytes.size());
Scott Michela59d4692008-02-23 18:41:37 +00002217}
2218
Scott Michel266bc8f2007-12-04 22:23:35 +00002219//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman475871a2008-07-27 21:46:04 +00002220static SDValue
2221LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2222 SDValue ConstVec;
2223 SDValue Arg;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002224 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002225
2226 ConstVec = Op.getOperand(0);
2227 Arg = Op.getOperand(1);
Gabor Greifba36cb52008-08-28 21:40:38 +00002228 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2229 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002230 ConstVec = ConstVec.getOperand(0);
2231 } else {
2232 ConstVec = Op.getOperand(1);
2233 Arg = Op.getOperand(0);
Gabor Greifba36cb52008-08-28 21:40:38 +00002234 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002235 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002236 }
2237 }
2238 }
2239
Gabor Greifba36cb52008-08-28 21:40:38 +00002240 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel266bc8f2007-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 Greifba36cb52008-08-28 21:40:38 +00002246 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002247 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002248 VT.getVectorElementType().getSizeInBits(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002249 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman475871a2008-07-27 21:46:04 +00002250 SDValue tcVec[16];
2251 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +00002256 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002257
Gabor Greifba36cb52008-08-28 21:40:38 +00002258 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002259 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002260 }
2261 }
Nate Begeman24dc3462008-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 Michel266bc8f2007-12-04 22:23:35 +00002265}
2266
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00002273static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002274 MVT VT = Op.getValueType();
2275 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +00002276
Duncan Sands83ec4b62008-06-06 12:08:01 +00002277 switch (VT.getSimpleVT()) {
2278 default:
2279 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002280 case MVT::i8: {
Dan Gohman475871a2008-07-27 21:46:04 +00002281 SDValue N = Op.getOperand(0);
2282 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002283
Scott Michelf0569be2008-12-27 04:51:36 +00002284 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002285 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-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 Lattner84bc5422007-12-31 04:13:23 +00002292 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002293
Chris Lattner84bc5422007-12-31 04:13:23 +00002294 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002295
Dan Gohman475871a2008-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 Sandsfa7935f2008-10-30 19:24:28 +00002299 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002300
Scott Michelf0569be2008-12-27 04:51:36 +00002301 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002302 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00002306 SDValue CNTB_result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002307 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002308
Dan Gohman475871a2008-07-27 21:46:04 +00002309 SDValue CNTB_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002310 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2311
Dan Gohman475871a2008-07-27 21:46:04 +00002312 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002313
2314 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-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 Michel266bc8f2007-12-04 22:23:35 +00002320 }
2321
2322 case MVT::i32: {
2323 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002324 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002325
Chris Lattner84bc5422007-12-31 04:13:23 +00002326 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2327 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002328
Dan Gohman475871a2008-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 Michel266bc8f2007-12-04 22:23:35 +00002334
Scott Michelf0569be2008-12-27 04:51:36 +00002335 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002336 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00002340 SDValue CNTB_result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002341 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002342
Dan Gohman475871a2008-07-27 21:46:04 +00002343 SDValue CNTB_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002344 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2345
Dan Gohman475871a2008-07-27 21:46:04 +00002346 SDValue Comp1 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002347 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002348 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002349
Dan Gohman475871a2008-07-27 21:46:04 +00002350 SDValue Sum1 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002351 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002352 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002353
Dan Gohman475871a2008-07-27 21:46:04 +00002354 SDValue Sum1_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002355 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2356
Dan Gohman475871a2008-07-27 21:46:04 +00002357 SDValue Comp2 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002358 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002359 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2360 Shift2);
Dan Gohman475871a2008-07-27 21:46:04 +00002361 SDValue Sum2 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002362 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002363 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-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 Gohman475871a2008-07-27 21:46:04 +00002372 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002373}
2374
Scott Michel7a1c9e92008-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 Michelf0569be2008-12-27 04:51:36 +00002387static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2388 const TargetLowering &TLI) {
Scott Michel7a1c9e92008-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 Michelf0569be2008-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 Michel7a1c9e92008-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 Sands5480c042009-01-01 15:52:00 +00002407 SDValue compare = DAG.getNode(ISD::SETCC,
2408 TLI.getSetCCResultType(Op.getValueType()),
Scott Michelf0569be2008-12-27 04:51:36 +00002409 lhs, rhs, condition);
2410 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002411}
2412
Scott Michelb30e8f62008-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 Michelf0569be2008-12-27 04:51:36 +00002424 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel52d00012009-01-03 00:27:53 +00002425 // Create shuffle mask, least significant doubleword of quadword
Scott Michelf0569be2008-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 Michelb30e8f62008-12-02 19:53:53 +00002443 }
2444
Scott Michelf0569be2008-12-27 04:51:36 +00002445 return SDValue(); // Leave the truncate unmolested
Scott Michelb30e8f62008-12-02 19:53:53 +00002446}
2447
Scott Michel7a1c9e92008-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 Gohman475871a2008-07-27 21:46:04 +00002453SDValue
2454SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel266bc8f2007-12-04 22:23:35 +00002455{
Scott Michela59d4692008-02-23 18:41:37 +00002456 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002457 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002458
2459 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002460 default: {
2461 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002462 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greifba36cb52008-08-28 21:40:38 +00002463 cerr << "*Op.getNode():\n";
2464 Op.getNode()->dump();
Scott Michel266bc8f2007-12-04 22:23:35 +00002465 abort();
2466 }
2467 case ISD::LOAD:
Scott Michelb30e8f62008-12-02 19:53:53 +00002468 case ISD::EXTLOAD:
Scott Michel266bc8f2007-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 Michel58c58182008-01-17 20:38:41 +00002485 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002486 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002487 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002488 case ISD::RET:
2489 return LowerRET(Op, DAG, getTargetMachine());
2490
Scott Michel02d711b2008-12-30 23:28:25 +00002491 // i8, i64 math ops:
Scott Michel8bf61e82008-06-02 22:18:03 +00002492 case ISD::ADD:
Scott Michel266bc8f2007-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 Michel8bf61e82008-06-02 22:18:03 +00002498 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002499 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002500 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michela59d4692008-02-23 18:41:37 +00002501 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002502 }
Scott Michel266bc8f2007-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 Michel02d711b2008-12-30 23:28:25 +00002524 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002525 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel266bc8f2007-12-04 22:23:35 +00002526
Scott Michel266bc8f2007-12-04 22:23:35 +00002527 case ISD::CTPOP:
2528 return LowerCTPOP(Op, DAG);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002529
2530 case ISD::SELECT_CC:
Scott Michelf0569be2008-12-27 04:51:36 +00002531 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelb30e8f62008-12-02 19:53:53 +00002532
2533 case ISD::TRUNCATE:
2534 return LowerTRUNCATE(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002535 }
2536
Dan Gohman475871a2008-07-27 21:46:04 +00002537 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002538}
2539
Duncan Sands1607f052008-12-01 11:39:25 +00002540void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2541 SmallVectorImpl<SDValue>&Results,
2542 SelectionDAG &DAG)
Scott Michel73ce1c52008-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 Michel73ce1c52008-11-10 23:43:06 +00002561}
2562
Scott Michel266bc8f2007-12-04 22:23:35 +00002563//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002564// Target Optimization Hooks
2565//===----------------------------------------------------------------------===//
2566
Dan Gohman475871a2008-07-27 21:46:04 +00002567SDValue
Scott Michel266bc8f2007-12-04 22:23:35 +00002568SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2569{
2570#if 0
2571 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002572#endif
2573 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002574 SelectionDAG &DAG = DCI.DAG;
Scott Michel1a6cdb62008-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 Michelf0569be2008-12-27 04:51:36 +00002577 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel1a6cdb62008-12-01 17:56:02 +00002578 SDValue Result; // Initially, empty result
Scott Michel266bc8f2007-12-04 22:23:35 +00002579
2580 switch (N->getOpcode()) {
2581 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002582 case ISD::ADD: {
Dan Gohman475871a2008-07-27 21:46:04 +00002583 SDValue Op1 = N->getOperand(1);
Scott Michel053c1da2008-01-29 02:16:57 +00002584
Scott Michelf0569be2008-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 Michel1df30c42008-12-29 03:23:36 +00002589
Scott Michelf0569be2008-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 Michel053c1da2008-01-29 02:16:57 +00002602
Scott Michel23f2ff72008-12-04 17:16:59 +00002603#if !defined(NDEBUG)
Scott Michelf0569be2008-12-27 04:51:36 +00002604 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002605 cerr << "\n"
Scott Michelf0569be2008-12-27 04:51:36 +00002606 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2607 << "With: (SPUindirect <arg>, <arg>)\n";
2608 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002609#endif
2610
Scott Michelf0569be2008-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 Michel053c1da2008-01-29 02:16:57 +00002618
Scott Michelf0569be2008-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 Michel053c1da2008-01-29 02:16:57 +00002628
Scott Michelf0569be2008-12-27 04:51:36 +00002629 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2630 IndirectArg, combinedValue);
2631 }
Scott Michel053c1da2008-01-29 02:16:57 +00002632 }
2633 }
Scott Michela59d4692008-02-23 18:41:37 +00002634 break;
2635 }
2636 case ISD::SIGN_EXTEND:
2637 case ISD::ZERO_EXTEND:
2638 case ISD::ANY_EXTEND: {
Scott Michel1a6cdb62008-12-01 17:56:02 +00002639 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michela59d4692008-02-23 18:41:37 +00002640 // (any_extend (SPUextract_elt0 <arg>)) ->
2641 // (SPUextract_elt0 <arg>)
2642 // Types must match, however...
Scott Michel23f2ff72008-12-04 17:16:59 +00002643#if !defined(NDEBUG)
2644 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002645 cerr << "\nReplace: ";
2646 N->dump(&DAG);
2647 cerr << "\nWith: ";
2648 Op0.getNode()->dump(&DAG);
2649 cerr << "\n";
Scott Michel23f2ff72008-12-04 17:16:59 +00002650 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002651#endif
Scott Michela59d4692008-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 Gohmanf5aeb1a2008-09-12 16:56:44 +00002660 if (CN->getZExtValue() == 0) {
Scott Michela59d4692008-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 Greifba36cb52008-08-28 21:40:38 +00002667 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002668 DEBUG(cerr << "\n");
2669
2670 return Op0;
2671 }
Scott Michelf0569be2008-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 Michela59d4692008-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 Michelf0569be2008-12-27 04:51:36 +00002699 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman475871a2008-07-27 21:46:04 +00002700 SDValue Op1 = N->getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00002701
Scott Michelf0569be2008-12-27 04:51:36 +00002702 // Kill degenerate vector shifts:
2703 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2704 if (CN->isNullValue()) {
Scott Michela59d4692008-02-23 18:41:37 +00002705 Result = Op0;
2706 }
2707 }
2708 break;
2709 }
Scott Michelf0569be2008-12-27 04:51:36 +00002710 case SPUISD::PREFSLOT2VEC: {
Scott Michela59d4692008-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 Michel1df30c42008-12-29 03:23:36 +00002717 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michela59d4692008-02-23 18:41:37 +00002718 // <arg>
Scott Michel1df30c42008-12-29 03:23:36 +00002719 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman475871a2008-07-27 21:46:04 +00002720 SDValue Op00 = Op0.getOperand(0);
Scott Michel104de432008-11-24 17:11:17 +00002721 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman475871a2008-07-27 21:46:04 +00002722 SDValue Op000 = Op00.getOperand(0);
Scott Michel1a6cdb62008-12-01 17:56:02 +00002723 if (Op000.getValueType() == NodeVT) {
Scott Michela59d4692008-02-23 18:41:37 +00002724 Result = Op000;
2725 }
2726 }
2727 break;
2728 }
Scott Michel104de432008-11-24 17:11:17 +00002729 case SPUISD::VEC2PREFSLOT: {
Scott Michel1df30c42008-12-29 03:23:36 +00002730 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michela59d4692008-02-23 18:41:37 +00002731 // <arg>
2732 Result = Op0.getOperand(0);
2733 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002734 }
Scott Michela59d4692008-02-23 18:41:37 +00002735 }
2736 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002737 }
2738 }
Scott Michel94bd57e2009-01-15 04:41:47 +00002739
Scott Michel58c58182008-01-17 20:38:41 +00002740 // Otherwise, return unchanged.
Scott Michel1a6cdb62008-12-01 17:56:02 +00002741#ifndef NDEBUG
Gabor Greifba36cb52008-08-28 21:40:38 +00002742 if (Result.getNode()) {
Scott Michela59d4692008-02-23 18:41:37 +00002743 DEBUG(cerr << "\nReplace.SPU: ");
2744 DEBUG(N->dump(&DAG));
2745 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002746 DEBUG(Result.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002747 DEBUG(cerr << "\n");
2748 }
2749#endif
2750
2751 return Result;
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00002760SPUTargetLowering::ConstraintType
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00002771 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002772 }
2773 return TargetLowering::getConstraintType(ConstraintLetter);
2774}
2775
Scott Michel5af8f0e2008-07-16 17:17:29 +00002776std::pair<unsigned, const TargetRegisterClass*>
Scott Michel266bc8f2007-12-04 22:23:35 +00002777SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002778 MVT VT) const
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00002794 case 'v':
Scott Michel266bc8f2007-12-04 22:23:35 +00002795 return std::make_pair(0U, SPU::GPRCRegisterClass);
2796 }
2797 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00002798
Scott Michel266bc8f2007-12-04 22:23:35 +00002799 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2800}
2801
Scott Michela59d4692008-02-23 18:41:37 +00002802//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002803void
Dan Gohman475871a2008-07-27 21:46:04 +00002804SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002805 const APInt &Mask,
Scott Michel5af8f0e2008-07-16 17:17:29 +00002806 APInt &KnownZero,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002807 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002808 const SelectionDAG &DAG,
2809 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00002810#if 0
Scott Michela59d4692008-02-23 18:41:37 +00002811 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
Scott Michel203b2d62008-04-30 00:30:08 +00002812#endif
Scott Michela59d4692008-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 Michel7a1c9e92008-11-22 23:50:42 +00002822 case SHUFFLE_MASK:
Scott Michela59d4692008-02-23 18:41:37 +00002823 case CNTB:
2824#endif
2825
Scott Michelf0569be2008-12-27 04:51:36 +00002826 case SPUISD::PREFSLOT2VEC: {
Dan Gohman475871a2008-07-27 21:46:04 +00002827 SDValue Op0 = Op.getOperand(0);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002828 MVT Op0VT = Op0.getValueType();
2829 unsigned Op0VTBits = Op0VT.getSizeInBits();
2830 uint64_t InMask = Op0VT.getIntegerVTBitMask();
Scott Michel203b2d62008-04-30 00:30:08 +00002831 KnownZero |= APInt(Op0VTBits, ~InMask, false);
2832 KnownOne |= APInt(Op0VTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002833 break;
2834 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00002835
Scott Michela59d4692008-02-23 18:41:37 +00002836 case SPUISD::LDRESULT:
Scott Michel30ee7df2008-12-04 03:02:42 +00002837 case SPUISD::VEC2PREFSLOT: {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002838 MVT OpVT = Op.getValueType();
2839 unsigned OpVTBits = OpVT.getSizeInBits();
2840 uint64_t InMask = OpVT.getIntegerVTBitMask();
Scott Michel203b2d62008-04-30 00:30:08 +00002841 KnownZero |= APInt(OpVTBits, ~InMask, false);
2842 KnownOne |= APInt(OpVTBits, InMask, false);
Scott Michela59d4692008-02-23 18:41:37 +00002843 break;
2844 }
2845
2846#if 0
Scott Michel203b2d62008-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 Michel203b2d62008-04-30 00:30:08 +00002854 case SPUISD::ROTBYTES_LEFT:
Scott Michel8bf61e82008-06-02 22:18:03 +00002855 case SPUISD::SELECT_MASK:
2856 case SPUISD::SELB:
Scott Michela59d4692008-02-23 18:41:37 +00002857#endif
2858 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002859}
Scott Michel02d711b2008-12-30 23:28:25 +00002860
Scott Michelf0569be2008-12-27 04:51:36 +00002861unsigned
2862SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2863 unsigned Depth) const {
2864 switch (Op.getOpcode()) {
2865 default:
2866 return 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002867
Scott Michelf0569be2008-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 Michel1df30c42008-12-29 03:23:36 +00002878
Scott Michel203b2d62008-04-30 00:30:08 +00002879// LowerAsmOperandForConstraint
2880void
Dan Gohman475871a2008-07-27 21:46:04 +00002881SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michel203b2d62008-04-30 00:30:08 +00002882 char ConstraintLetter,
Evan Chengda43bcf2008-09-24 00:05:32 +00002883 bool hasMemory,
Dan Gohman475871a2008-07-27 21:46:04 +00002884 std::vector<SDValue> &Ops,
Scott Michel203b2d62008-04-30 00:30:08 +00002885 SelectionDAG &DAG) const {
2886 // Default, for the time being, to the base class handler
Evan Chengda43bcf2008-09-24 00:05:32 +00002887 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2888 Ops, DAG);
Scott Michel203b2d62008-04-30 00:30:08 +00002889}
2890
Scott Michel266bc8f2007-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 Greif93c53e52008-08-31 15:37:04 +00002893bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2894 const Type *Ty) const {
Scott Michel266bc8f2007-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 Michel5af8f0e2008-07-16 17:17:29 +00002900 return false;
Scott Michel266bc8f2007-12-04 22:23:35 +00002901}
Dan Gohman6520e202008-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}