blob: d8a77766bd598635f728cb6d0933e401ade99860 [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//
Scott Michel7ea02ff2009-03-17 01:15:45 +00002//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00003// 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 Michelc9c8b2a2009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000021#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000027#include "llvm/Constants.h"
28#include "llvm/Function.h"
29#include "llvm/Intrinsics.h"
30#include "llvm/Support/Debug.h"
31#include "llvm/Support/MathExtras.h"
32#include "llvm/Target/TargetOptions.h"
33
34#include <map>
35
36using namespace llvm;
37
38// Used in getTargetNodeName() below
39namespace {
40 std::map<unsigned, const char *> node_names;
41
Duncan Sands83ec4b62008-06-06 12:08:01 +000042 //! MVT mapping to useful data for Cell SPU
Scott Michel266bc8f2007-12-04 22:23:35 +000043 struct valtype_map_s {
Scott Michel7a1c9e92008-11-22 23:50:42 +000044 const MVT valtype;
45 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000046 };
Scott Michel5af8f0e2008-07-16 17:17:29 +000047
Scott Michel266bc8f2007-12-04 22:23:35 +000048 const valtype_map_s valtype_map[] = {
49 { MVT::i1, 3 },
50 { MVT::i8, 3 },
51 { MVT::i16, 2 },
52 { MVT::i32, 0 },
53 { MVT::f32, 0 },
54 { MVT::i64, 0 },
55 { MVT::f64, 0 },
56 { MVT::i128, 0 }
57 };
58
59 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
60
Duncan Sands83ec4b62008-06-06 12:08:01 +000061 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel266bc8f2007-12-04 22:23:35 +000062 const valtype_map_s *retval = 0;
63
64 for (size_t i = 0; i < n_valtype_map; ++i) {
65 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000066 retval = valtype_map + i;
67 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000068 }
69 }
70
71#ifndef NDEBUG
72 if (retval == 0) {
73 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands83ec4b62008-06-06 12:08:01 +000074 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +000075 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000076 abort();
77 }
78#endif
79
80 return retval;
81 }
Scott Michel94bd57e2009-01-15 04:41:47 +000082
Scott Michelc9c8b2a2009-01-26 03:31:40 +000083 //! Expand a library call into an actual call DAG node
84 /*!
85 \note
86 This code is taken from SelectionDAGLegalize, since it is not exposed as
87 part of the LLVM SelectionDAG API.
88 */
89
90 SDValue
91 ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG,
92 bool isSigned, SDValue &Hi, SPUTargetLowering &TLI) {
93 // The input chain to this libcall is the entry node of the function.
94 // Legalizing the call will automatically add the previous call to the
95 // dependence.
96 SDValue InChain = DAG.getEntryNode();
97
98 TargetLowering::ArgListTy Args;
99 TargetLowering::ArgListEntry Entry;
100 for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
101 MVT ArgVT = Op.getOperand(i).getValueType();
102 const Type *ArgTy = ArgVT.getTypeForMVT();
103 Entry.Node = Op.getOperand(i);
104 Entry.Ty = ArgTy;
105 Entry.isSExt = isSigned;
106 Entry.isZExt = !isSigned;
107 Args.push_back(Entry);
108 }
109 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
110 TLI.getPointerTy());
111
112 // Splice the libcall in wherever FindInputOutputChains tells us to.
113 const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
114 std::pair<SDValue, SDValue> CallInfo =
115 TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
Tilmann Scheller6b61cd12009-07-03 06:44:53 +0000116 0, CallingConv::C, false, Callee, Args, DAG,
Dale Johannesen6f38cb62009-02-07 19:59:05 +0000117 Op.getDebugLoc());
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000118
119 return CallInfo.first;
120 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000121}
122
123SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
124 : TargetLowering(TM),
125 SPUTM(TM)
126{
127 // Fold away setcc operations if possible.
128 setPow2DivIsCheap();
129
130 // Use _setjmp/_longjmp instead of setjmp/longjmp.
131 setUseUnderscoreSetJmp(true);
132 setUseUnderscoreLongJmp(true);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000133
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000134 // Set RTLIB libcall names as used by SPU:
135 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
136
Scott Michel266bc8f2007-12-04 22:23:35 +0000137 // Set up the SPU's register classes:
Scott Michel504c3692007-12-17 22:32:34 +0000138 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
139 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
140 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
141 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
142 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
143 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000144 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000145
Scott Michel266bc8f2007-12-04 22:23:35 +0000146 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng03294662008-10-14 21:26:46 +0000147 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
148 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
149 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000150
Scott Michelf0569be2008-12-27 04:51:36 +0000151 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
152 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelb30e8f62008-12-02 19:53:53 +0000153
Scott Michel266bc8f2007-12-04 22:23:35 +0000154 // SPU constant load actions are custom lowered:
Nate Begemanccef5802008-02-14 18:43:04 +0000155 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000156 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
157
158 // SPU's loads and stores have to be custom lowered:
Scott Micheldd950092009-01-06 03:36:14 +0000159 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel266bc8f2007-12-04 22:23:35 +0000160 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000161 MVT VT = (MVT::SimpleValueType)sctype;
162
Scott Michelf0569be2008-12-27 04:51:36 +0000163 setOperationAction(ISD::LOAD, VT, Custom);
164 setOperationAction(ISD::STORE, VT, Custom);
165 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
166 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
167 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
168
169 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
170 MVT StoreVT = (MVT::SimpleValueType) stype;
171 setTruncStoreAction(VT, StoreVT, Expand);
172 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000173 }
174
Scott Michelf0569be2008-12-27 04:51:36 +0000175 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
176 ++sctype) {
177 MVT VT = (MVT::SimpleValueType) sctype;
178
179 setOperationAction(ISD::LOAD, VT, Custom);
180 setOperationAction(ISD::STORE, VT, Custom);
181
182 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
183 MVT StoreVT = (MVT::SimpleValueType) stype;
184 setTruncStoreAction(VT, StoreVT, Expand);
185 }
186 }
187
Scott Michel266bc8f2007-12-04 22:23:35 +0000188 // Expand the jumptable branches
189 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
190 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000191
192 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel5af8f0e2008-07-16 17:17:29 +0000193 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000194 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
195 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
196 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
197 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000198
199 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000200 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
201
Scott Michelf0569be2008-12-27 04:51:36 +0000202 // SPU has no SREM/UREM instructions
Scott Michel266bc8f2007-12-04 22:23:35 +0000203 setOperationAction(ISD::SREM, MVT::i32, Expand);
204 setOperationAction(ISD::UREM, MVT::i32, Expand);
205 setOperationAction(ISD::SREM, MVT::i64, Expand);
206 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000207
Scott Michel266bc8f2007-12-04 22:23:35 +0000208 // We don't support sin/cos/sqrt/fmod
209 setOperationAction(ISD::FSIN , MVT::f64, Expand);
210 setOperationAction(ISD::FCOS , MVT::f64, Expand);
211 setOperationAction(ISD::FREM , MVT::f64, Expand);
212 setOperationAction(ISD::FSIN , MVT::f32, Expand);
213 setOperationAction(ISD::FCOS , MVT::f32, Expand);
214 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000215
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000216 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
217 // for f32!)
Scott Michel266bc8f2007-12-04 22:23:35 +0000218 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
219 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000220
Scott Michel266bc8f2007-12-04 22:23:35 +0000221 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
222 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
223
224 // SPU can do rotate right and left, so legalize it... but customize for i8
225 // because instructions don't exist.
Bill Wendling9440e352008-08-31 02:59:23 +0000226
227 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
228 // .td files.
229 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
230 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
231 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
232
Scott Michel266bc8f2007-12-04 22:23:35 +0000233 setOperationAction(ISD::ROTL, MVT::i32, Legal);
234 setOperationAction(ISD::ROTL, MVT::i16, Legal);
235 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Micheldc91bea2008-11-20 16:36:33 +0000236
Scott Michel266bc8f2007-12-04 22:23:35 +0000237 // SPU has no native version of shift left/right for i8
238 setOperationAction(ISD::SHL, MVT::i8, Custom);
239 setOperationAction(ISD::SRL, MVT::i8, Custom);
240 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000241
Scott Michel02d711b2008-12-30 23:28:25 +0000242 // Make these operations legal and handle them during instruction selection:
243 setOperationAction(ISD::SHL, MVT::i64, Legal);
244 setOperationAction(ISD::SRL, MVT::i64, Legal);
245 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000246
Scott Michel5af8f0e2008-07-16 17:17:29 +0000247 // Custom lower i8, i32 and i64 multiplications
248 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michel1df30c42008-12-29 03:23:36 +0000249 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel94bd57e2009-01-15 04:41:47 +0000250 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000251
Eli Friedman6314ac22009-06-16 06:40:59 +0000252 // Expand double-width multiplication
253 // FIXME: It would probably be reasonable to support some of these operations
254 setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand);
255 setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand);
256 setOperationAction(ISD::MULHU, MVT::i8, Expand);
257 setOperationAction(ISD::MULHS, MVT::i8, Expand);
258 setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand);
259 setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand);
260 setOperationAction(ISD::MULHU, MVT::i16, Expand);
261 setOperationAction(ISD::MULHS, MVT::i16, Expand);
262 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
263 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
264 setOperationAction(ISD::MULHU, MVT::i32, Expand);
265 setOperationAction(ISD::MULHS, MVT::i32, Expand);
266 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
267 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
268 setOperationAction(ISD::MULHU, MVT::i64, Expand);
269 setOperationAction(ISD::MULHS, MVT::i64, Expand);
270
Scott Michel8bf61e82008-06-02 22:18:03 +0000271 // Need to custom handle (some) common i8, i64 math ops
Scott Michel02d711b2008-12-30 23:28:25 +0000272 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000273 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000274 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000275 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000276
Scott Michel266bc8f2007-12-04 22:23:35 +0000277 // SPU does not have BSWAP. It does have i32 support CTLZ.
278 // CTPOP has to be custom lowered.
279 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
280 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
281
282 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
283 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
284 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
285 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
286
287 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
288 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
289
290 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000291
Scott Michel8bf61e82008-06-02 22:18:03 +0000292 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000293 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000294 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000295 setOperationAction(ISD::SELECT, MVT::i16, Legal);
296 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michelf0569be2008-12-27 04:51:36 +0000297 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000298
Scott Michel78c47fa2008-03-10 16:58:52 +0000299 setOperationAction(ISD::SETCC, MVT::i8, Legal);
300 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000301 setOperationAction(ISD::SETCC, MVT::i32, Legal);
302 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000303 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michelad2715e2008-03-05 23:02:02 +0000304
Scott Michelf0569be2008-12-27 04:51:36 +0000305 // Custom lower i128 -> i64 truncates
Scott Michelb30e8f62008-12-02 19:53:53 +0000306 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
307
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000308 // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
309 // to expand to a libcall, hence the custom lowering:
310 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
311 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000312
313 // FDIV on SPU requires custom lowering
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000314 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel266bc8f2007-12-04 22:23:35 +0000315
Scott Michel9de57a92009-01-26 22:33:37 +0000316 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000317 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000318 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000319 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
320 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000321 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000322 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000323 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
324 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
325
Scott Michel86c041f2007-12-20 00:44:13 +0000326 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
327 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
328 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
329 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000330
331 // We cannot sextinreg(i1). Expand to shifts.
332 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000333
Scott Michel266bc8f2007-12-04 22:23:35 +0000334 // Support label based line numbers.
Dan Gohman7f460202008-06-30 20:59:49 +0000335 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000336 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000337
338 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel266bc8f2007-12-04 22:23:35 +0000339 // appropriate instructions to materialize the address.
Scott Michel9c0c6b22008-11-21 02:56:16 +0000340 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michel053c1da2008-01-29 02:16:57 +0000341 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000342 MVT VT = (MVT::SimpleValueType)sctype;
343
Scott Michel1df30c42008-12-29 03:23:36 +0000344 setOperationAction(ISD::GlobalAddress, VT, Custom);
345 setOperationAction(ISD::ConstantPool, VT, Custom);
346 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michel053c1da2008-01-29 02:16:57 +0000347 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000348
349 // RET must be custom lowered, to meet ABI requirements
350 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000351
Scott Michel266bc8f2007-12-04 22:23:35 +0000352 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
353 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000354
Scott Michel266bc8f2007-12-04 22:23:35 +0000355 // Use the default implementation.
356 setOperationAction(ISD::VAARG , MVT::Other, Expand);
357 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
358 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000359 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000360 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
361 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
362 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
363
364 // Cell SPU has instructions for converting between i64 and fp.
365 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
366 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000367
Scott Michel266bc8f2007-12-04 22:23:35 +0000368 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
369 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
370
371 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
372 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
373
374 // First set operation action for all vector types to expand. Then we
375 // will selectively turn on ones that can be effectively codegen'd.
376 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
377 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
378 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
379 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
380 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
381 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
382
Scott Michel21213e72009-01-06 23:10:38 +0000383 // "Odd size" vector classes that we're willing to support:
384 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
385
Duncan Sands83ec4b62008-06-06 12:08:01 +0000386 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
387 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
388 MVT VT = (MVT::SimpleValueType)i;
Scott Michel266bc8f2007-12-04 22:23:35 +0000389
Duncan Sands83ec4b62008-06-06 12:08:01 +0000390 // add/sub are legal for all supported vector VT's.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000391 setOperationAction(ISD::ADD, VT, Legal);
392 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000393 // mul has to be custom lowered.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000394 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000395
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000396 setOperationAction(ISD::AND, VT, Legal);
397 setOperationAction(ISD::OR, VT, Legal);
398 setOperationAction(ISD::XOR, VT, Legal);
399 setOperationAction(ISD::LOAD, VT, Legal);
400 setOperationAction(ISD::SELECT, VT, Legal);
401 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000402
Scott Michel266bc8f2007-12-04 22:23:35 +0000403 // These operations need to be expanded:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000404 setOperationAction(ISD::SDIV, VT, Expand);
405 setOperationAction(ISD::SREM, VT, Expand);
406 setOperationAction(ISD::UDIV, VT, Expand);
407 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000408
409 // Custom lower build_vector, constant pool spills, insert and
410 // extract vector elements:
Duncan Sands83ec4b62008-06-06 12:08:01 +0000411 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
412 setOperationAction(ISD::ConstantPool, VT, Custom);
413 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
414 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
415 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
416 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000417 }
418
Scott Michel266bc8f2007-12-04 22:23:35 +0000419 setOperationAction(ISD::AND, MVT::v16i8, Custom);
420 setOperationAction(ISD::OR, MVT::v16i8, Custom);
421 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
422 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000423
Scott Michel02d711b2008-12-30 23:28:25 +0000424 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000425
Scott Michel266bc8f2007-12-04 22:23:35 +0000426 setShiftAmountType(MVT::i32);
Scott Michelf0569be2008-12-27 04:51:36 +0000427 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000428
Scott Michel266bc8f2007-12-04 22:23:35 +0000429 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000430
Scott Michel266bc8f2007-12-04 22:23:35 +0000431 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000432 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000433 setTargetDAGCombine(ISD::ZERO_EXTEND);
434 setTargetDAGCombine(ISD::SIGN_EXTEND);
435 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000436
Scott Michel266bc8f2007-12-04 22:23:35 +0000437 computeRegisterProperties();
Scott Michel7a1c9e92008-11-22 23:50:42 +0000438
Scott Michele07d3de2008-12-09 03:37:19 +0000439 // Set pre-RA register scheduler default to BURR, which produces slightly
440 // better code than the default (could also be TDRR, but TargetLowering.h
441 // needs a mod to support that model):
442 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel266bc8f2007-12-04 22:23:35 +0000443}
444
445const char *
446SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
447{
448 if (node_names.empty()) {
449 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
450 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
451 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
452 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000453 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000454 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000455 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
456 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
457 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel7a1c9e92008-11-22 23:50:42 +0000458 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000459 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michel1df30c42008-12-29 03:23:36 +0000460 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michel104de432008-11-24 17:11:17 +0000461 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michela59d4692008-02-23 18:41:37 +0000462 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
463 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000464 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
465 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
466 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
467 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
468 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000469 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
470 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
471 "SPUISD::ROTBYTES_LEFT_BITS";
Scott Michel8bf61e82008-06-02 22:18:03 +0000472 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000473 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel94bd57e2009-01-15 04:41:47 +0000474 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
475 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
476 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel266bc8f2007-12-04 22:23:35 +0000477 }
478
479 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
480
481 return ((i != node_names.end()) ? i->second : 0);
482}
483
Bill Wendlingb4202b82009-07-01 18:50:55 +0000484/// getFunctionAlignment - Return the Log2 alignment of this function.
Bill Wendling20c568f2009-06-30 22:38:32 +0000485unsigned SPUTargetLowering::getFunctionAlignment(const Function *) const {
486 return 3;
487}
488
Scott Michelf0569be2008-12-27 04:51:36 +0000489//===----------------------------------------------------------------------===//
490// Return the Cell SPU's SETCC result type
491//===----------------------------------------------------------------------===//
492
Duncan Sands5480c042009-01-01 15:52:00 +0000493MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michelf0569be2008-12-27 04:51:36 +0000494 // i16 and i32 are valid SETCC result types
495 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel78c47fa2008-03-10 16:58:52 +0000496}
497
Scott Michel266bc8f2007-12-04 22:23:35 +0000498//===----------------------------------------------------------------------===//
499// Calling convention code:
500//===----------------------------------------------------------------------===//
501
502#include "SPUGenCallingConv.inc"
503
504//===----------------------------------------------------------------------===//
505// LowerOperation implementation
506//===----------------------------------------------------------------------===//
507
508/// Custom lower loads for CellSPU
509/*!
510 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
511 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel30ee7df2008-12-04 03:02:42 +0000512
513 For extending loads, we also want to ensure that the following sequence is
514 emitted, e.g. for MVT::f32 extending load to MVT::f64:
515
516\verbatim
Scott Michel1df30c42008-12-29 03:23:36 +0000517%1 v16i8,ch = load
Scott Michel30ee7df2008-12-04 03:02:42 +0000518%2 v16i8,ch = rotate %1
Scott Michel1df30c42008-12-29 03:23:36 +0000519%3 v4f8, ch = bitconvert %2
Scott Michel30ee7df2008-12-04 03:02:42 +0000520%4 f32 = vec2perfslot %3
521%5 f64 = fp_extend %4
522\endverbatim
523*/
Dan Gohman475871a2008-07-27 21:46:04 +0000524static SDValue
525LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000526 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000527 SDValue the_chain = LN->getChain();
Scott Michelf0569be2008-12-27 04:51:36 +0000528 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel30ee7df2008-12-04 03:02:42 +0000529 MVT InVT = LN->getMemoryVT();
530 MVT OutVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000531 ISD::LoadExtType ExtType = LN->getExtensionType();
532 unsigned alignment = LN->getAlignment();
Scott Michelf0569be2008-12-27 04:51:36 +0000533 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000534 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000535
Scott Michel266bc8f2007-12-04 22:23:35 +0000536 switch (LN->getAddressingMode()) {
537 case ISD::UNINDEXED: {
Scott Michelf0569be2008-12-27 04:51:36 +0000538 SDValue result;
539 SDValue basePtr = LN->getBasePtr();
540 SDValue rotate;
Scott Michel266bc8f2007-12-04 22:23:35 +0000541
Scott Michelf0569be2008-12-27 04:51:36 +0000542 if (alignment == 16) {
543 ConstantSDNode *CN;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000544
Scott Michelf0569be2008-12-27 04:51:36 +0000545 // Special cases for a known aligned load to simplify the base pointer
546 // and the rotation amount:
547 if (basePtr.getOpcode() == ISD::ADD
548 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
549 // Known offset into basePtr
550 int64_t offset = CN->getSExtValue();
551 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000552
Scott Michelf0569be2008-12-27 04:51:36 +0000553 if (rotamt < 0)
554 rotamt += 16;
555
556 rotate = DAG.getConstant(rotamt, MVT::i16);
557
558 // Simplify the base pointer for this case:
559 basePtr = basePtr.getOperand(0);
560 if ((offset & ~0xf) > 0) {
Dale Johannesende064702009-02-06 21:50:26 +0000561 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000562 basePtr,
563 DAG.getConstant((offset & ~0xf), PtrVT));
564 }
565 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
566 || (basePtr.getOpcode() == SPUISD::IndirectAddr
567 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
568 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
569 // Plain aligned a-form address: rotate into preferred slot
570 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
571 int64_t rotamt = -vtm->prefslot_byte;
572 if (rotamt < 0)
573 rotamt += 16;
574 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000575 } else {
Scott Michelf0569be2008-12-27 04:51:36 +0000576 // Offset the rotate amount by the basePtr and the preferred slot
577 // byte offset
578 int64_t rotamt = -vtm->prefslot_byte;
579 if (rotamt < 0)
580 rotamt += 16;
Dale Johannesen33c960f2009-02-04 20:06:27 +0000581 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000582 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000583 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000584 }
Scott Michelf0569be2008-12-27 04:51:36 +0000585 } else {
586 // Unaligned load: must be more pessimistic about addressing modes:
587 if (basePtr.getOpcode() == ISD::ADD) {
588 MachineFunction &MF = DAG.getMachineFunction();
589 MachineRegisterInfo &RegInfo = MF.getRegInfo();
590 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
591 SDValue Flag;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000592
Scott Michelf0569be2008-12-27 04:51:36 +0000593 SDValue Op0 = basePtr.getOperand(0);
594 SDValue Op1 = basePtr.getOperand(1);
595
596 if (isa<ConstantSDNode>(Op1)) {
597 // Convert the (add <ptr>, <const>) to an indirect address contained
598 // in a register. Note that this is done because we need to avoid
599 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesende064702009-02-06 21:50:26 +0000600 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000601 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
602 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michelf0569be2008-12-27 04:51:36 +0000603 } else {
604 // Convert the (add <arg1>, <arg2>) to an indirect address, which
605 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesende064702009-02-06 21:50:26 +0000606 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michelf0569be2008-12-27 04:51:36 +0000607 }
608 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000609 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000610 basePtr,
611 DAG.getConstant(0, PtrVT));
612 }
613
614 // Offset the rotate amount by the basePtr and the preferred slot
615 // byte offset
Dale Johannesen33c960f2009-02-04 20:06:27 +0000616 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000617 basePtr,
618 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +0000619 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000620
Scott Michelf0569be2008-12-27 04:51:36 +0000621 // Re-emit as a v16i8 vector load
Dale Johannesen33c960f2009-02-04 20:06:27 +0000622 result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michelf0569be2008-12-27 04:51:36 +0000623 LN->getSrcValue(), LN->getSrcValueOffset(),
624 LN->isVolatile(), 16);
625
626 // Update the chain
627 the_chain = result.getValue(1);
628
629 // Rotate into the preferred slot:
Dale Johannesen33c960f2009-02-04 20:06:27 +0000630 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::v16i8,
Scott Michelf0569be2008-12-27 04:51:36 +0000631 result.getValue(0), rotate);
632
Scott Michel30ee7df2008-12-04 03:02:42 +0000633 // Convert the loaded v16i8 vector to the appropriate vector type
634 // specified by the operand:
635 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
Dale Johannesen33c960f2009-02-04 20:06:27 +0000636 result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT,
637 DAG.getNode(ISD::BIT_CONVERT, dl, vecVT, result));
Scott Michel5af8f0e2008-07-16 17:17:29 +0000638
Scott Michel30ee7df2008-12-04 03:02:42 +0000639 // Handle extending loads by extending the scalar result:
640 if (ExtType == ISD::SEXTLOAD) {
Dale Johannesen33c960f2009-02-04 20:06:27 +0000641 result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result);
Scott Michel30ee7df2008-12-04 03:02:42 +0000642 } else if (ExtType == ISD::ZEXTLOAD) {
Dale Johannesen33c960f2009-02-04 20:06:27 +0000643 result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result);
Scott Michel30ee7df2008-12-04 03:02:42 +0000644 } else if (ExtType == ISD::EXTLOAD) {
645 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000646
Scott Michel30ee7df2008-12-04 03:02:42 +0000647 if (OutVT.isFloatingPoint())
Scott Michel19c10e62009-01-26 03:37:41 +0000648 NewOpc = ISD::FP_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000649
Dale Johannesen33c960f2009-02-04 20:06:27 +0000650 result = DAG.getNode(NewOpc, dl, OutVT, result);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000651 }
652
Scott Michel30ee7df2008-12-04 03:02:42 +0000653 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman475871a2008-07-27 21:46:04 +0000654 SDValue retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000655 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000656 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000657 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000658
Dale Johannesen33c960f2009-02-04 20:06:27 +0000659 result = DAG.getNode(SPUISD::LDRESULT, dl, retvts,
Scott Michel58c58182008-01-17 20:38:41 +0000660 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000661 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000662 }
663 case ISD::PRE_INC:
664 case ISD::PRE_DEC:
665 case ISD::POST_INC:
666 case ISD::POST_DEC:
667 case ISD::LAST_INDEXED_MODE:
668 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
669 "UNINDEXED\n";
670 cerr << (unsigned) LN->getAddressingMode() << "\n";
671 abort();
672 /*NOTREACHED*/
673 }
674
Dan Gohman475871a2008-07-27 21:46:04 +0000675 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000676}
677
678/// Custom lower stores for CellSPU
679/*!
680 All CellSPU stores are aligned to 16-byte boundaries, so for elements
681 within a 16-byte block, we have to generate a shuffle to insert the
682 requested element into its place, then store the resulting block.
683 */
Dan Gohman475871a2008-07-27 21:46:04 +0000684static SDValue
685LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000686 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000687 SDValue Value = SN->getValue();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000688 MVT VT = Value.getValueType();
689 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
690 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000691 DebugLoc dl = Op.getDebugLoc();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000692 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000693
694 switch (SN->getAddressingMode()) {
695 case ISD::UNINDEXED: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000696 // The vector type we really want to load from the 16-byte chunk.
Scott Michel719b0e12008-11-19 17:45:08 +0000697 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
698 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +0000699
Scott Michelf0569be2008-12-27 04:51:36 +0000700 SDValue alignLoadVec;
701 SDValue basePtr = SN->getBasePtr();
702 SDValue the_chain = SN->getChain();
703 SDValue insertEltOffs;
Scott Michel266bc8f2007-12-04 22:23:35 +0000704
Scott Michelf0569be2008-12-27 04:51:36 +0000705 if (alignment == 16) {
706 ConstantSDNode *CN;
707
708 // Special cases for a known aligned load to simplify the base pointer
709 // and insertion byte:
710 if (basePtr.getOpcode() == ISD::ADD
711 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
712 // Known offset into basePtr
713 int64_t offset = CN->getSExtValue();
714
715 // Simplify the base pointer for this case:
716 basePtr = basePtr.getOperand(0);
Dale Johannesende064702009-02-06 21:50:26 +0000717 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000718 basePtr,
719 DAG.getConstant((offset & 0xf), PtrVT));
720
721 if ((offset & ~0xf) > 0) {
Dale Johannesende064702009-02-06 21:50:26 +0000722 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000723 basePtr,
724 DAG.getConstant((offset & ~0xf), PtrVT));
725 }
726 } else {
727 // Otherwise, assume it's at byte 0 of basePtr
Dale Johannesende064702009-02-06 21:50:26 +0000728 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000729 basePtr,
730 DAG.getConstant(0, PtrVT));
731 }
732 } else {
733 // Unaligned load: must be more pessimistic about addressing modes:
734 if (basePtr.getOpcode() == ISD::ADD) {
735 MachineFunction &MF = DAG.getMachineFunction();
736 MachineRegisterInfo &RegInfo = MF.getRegInfo();
737 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
738 SDValue Flag;
739
740 SDValue Op0 = basePtr.getOperand(0);
741 SDValue Op1 = basePtr.getOperand(1);
742
743 if (isa<ConstantSDNode>(Op1)) {
744 // Convert the (add <ptr>, <const>) to an indirect address contained
745 // in a register. Note that this is done because we need to avoid
746 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesende064702009-02-06 21:50:26 +0000747 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000748 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
749 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michelf0569be2008-12-27 04:51:36 +0000750 } else {
751 // Convert the (add <arg1>, <arg2>) to an indirect address, which
752 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesende064702009-02-06 21:50:26 +0000753 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michelf0569be2008-12-27 04:51:36 +0000754 }
755 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000756 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000757 basePtr,
758 DAG.getConstant(0, PtrVT));
759 }
760
761 // Insertion point is solely determined by basePtr's contents
Dale Johannesen33c960f2009-02-04 20:06:27 +0000762 insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000763 basePtr,
764 DAG.getConstant(0, PtrVT));
765 }
766
767 // Re-emit as a v16i8 vector load
Dale Johannesen33c960f2009-02-04 20:06:27 +0000768 alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michelf0569be2008-12-27 04:51:36 +0000769 SN->getSrcValue(), SN->getSrcValueOffset(),
770 SN->isVolatile(), 16);
771
772 // Update the chain
773 the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000774
Scott Michel9de5d0d2008-01-11 02:53:15 +0000775 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman475871a2008-07-27 21:46:04 +0000776 SDValue theValue = SN->getValue();
777 SDValue result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000778
779 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000780 && (theValue.getOpcode() == ISD::AssertZext
781 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000782 // Drill down and get the value for zero- and sign-extended
783 // quantities
Scott Michel5af8f0e2008-07-16 17:17:29 +0000784 theValue = theValue.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000785 }
786
Scott Michel9de5d0d2008-01-11 02:53:15 +0000787 // If the base pointer is already a D-form address, then just create
788 // a new D-form address with a slot offset and the orignal base pointer.
789 // Otherwise generate a D-form address with the slot offset relative
790 // to the stack pointer, which is always aligned.
Scott Michelf0569be2008-12-27 04:51:36 +0000791#if !defined(NDEBUG)
792 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
793 cerr << "CellSPU LowerSTORE: basePtr = ";
794 basePtr.getNode()->dump(&DAG);
795 cerr << "\n";
796 }
797#endif
Scott Michel9de5d0d2008-01-11 02:53:15 +0000798
Scott Michel430a5552008-11-19 15:24:16 +0000799 SDValue insertEltOp =
Dale Johannesen33c960f2009-02-04 20:06:27 +0000800 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, insertEltOffs);
Scott Michel719b0e12008-11-19 17:45:08 +0000801 SDValue vectorizeOp =
Dale Johannesen33c960f2009-02-04 20:06:27 +0000802 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, theValue);
Scott Michel430a5552008-11-19 15:24:16 +0000803
Dale Johannesen33c960f2009-02-04 20:06:27 +0000804 result = DAG.getNode(SPUISD::SHUFB, dl, vecVT,
Scott Michel19c10e62009-01-26 03:37:41 +0000805 vectorizeOp, alignLoadVec,
Scott Michel6e1d1472009-03-16 18:47:25 +0000806 DAG.getNode(ISD::BIT_CONVERT, dl,
Dale Johannesen33c960f2009-02-04 20:06:27 +0000807 MVT::v4i32, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000808
Dale Johannesen33c960f2009-02-04 20:06:27 +0000809 result = DAG.getStore(the_chain, dl, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000810 LN->getSrcValue(), LN->getSrcValueOffset(),
811 LN->isVolatile(), LN->getAlignment());
812
Scott Michel23f2ff72008-12-04 17:16:59 +0000813#if 0 && !defined(NDEBUG)
Scott Michel430a5552008-11-19 15:24:16 +0000814 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
815 const SDValue &currentRoot = DAG.getRoot();
816
817 DAG.setRoot(result);
818 cerr << "------- CellSPU:LowerStore result:\n";
819 DAG.dump();
820 cerr << "-------\n";
821 DAG.setRoot(currentRoot);
822 }
823#endif
Scott Michelb30e8f62008-12-02 19:53:53 +0000824
Scott Michel266bc8f2007-12-04 22:23:35 +0000825 return result;
826 /*UNREACHED*/
827 }
828 case ISD::PRE_INC:
829 case ISD::PRE_DEC:
830 case ISD::POST_INC:
831 case ISD::POST_DEC:
832 case ISD::LAST_INDEXED_MODE:
833 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
834 "UNINDEXED\n";
835 cerr << (unsigned) SN->getAddressingMode() << "\n";
836 abort();
837 /*NOTREACHED*/
838 }
839
Dan Gohman475871a2008-07-27 21:46:04 +0000840 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000841}
842
Scott Michel94bd57e2009-01-15 04:41:47 +0000843//! Generate the address of a constant pool entry.
844SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000845LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000846 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000847 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
848 Constant *C = CP->getConstVal();
Dan Gohman475871a2008-07-27 21:46:04 +0000849 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
850 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000851 const TargetMachine &TM = DAG.getTarget();
Dale Johannesende064702009-02-06 21:50:26 +0000852 // FIXME there is no actual debug info here
853 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000854
855 if (TM.getRelocationModel() == Reloc::Static) {
856 if (!ST->usingLargeMem()) {
Dan Gohman475871a2008-07-27 21:46:04 +0000857 // Just return the SDValue with the constant pool address in it.
Dale Johannesende064702009-02-06 21:50:26 +0000858 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000859 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000860 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, CPI, Zero);
861 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, CPI, Zero);
862 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000863 }
864 }
865
866 assert(0 &&
Gabor Greif93c53e52008-08-31 15:37:04 +0000867 "LowerConstantPool: Relocation model other than static"
868 " not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000869 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000870}
871
Scott Michel94bd57e2009-01-15 04:41:47 +0000872//! Alternate entry point for generating the address of a constant pool entry
873SDValue
874SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
875 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
876}
877
Dan Gohman475871a2008-07-27 21:46:04 +0000878static SDValue
879LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000880 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000881 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000882 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
883 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000884 const TargetMachine &TM = DAG.getTarget();
Dale Johannesende064702009-02-06 21:50:26 +0000885 // FIXME there is no actual debug info here
886 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000887
888 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000889 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +0000890 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000891 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000892 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, JTI, Zero);
893 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, JTI, Zero);
894 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michela59d4692008-02-23 18:41:37 +0000895 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000896 }
897
898 assert(0 &&
899 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000900 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000901}
902
Dan Gohman475871a2008-07-27 21:46:04 +0000903static SDValue
904LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000905 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000906 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
907 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman475871a2008-07-27 21:46:04 +0000908 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000909 const TargetMachine &TM = DAG.getTarget();
Dan Gohman475871a2008-07-27 21:46:04 +0000910 SDValue Zero = DAG.getConstant(0, PtrVT);
Dale Johannesende064702009-02-06 21:50:26 +0000911 // FIXME there is no actual debug info here
912 DebugLoc dl = Op.getDebugLoc();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000913
Scott Michel266bc8f2007-12-04 22:23:35 +0000914 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000915 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +0000916 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero);
Scott Michel053c1da2008-01-29 02:16:57 +0000917 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000918 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, GA, Zero);
919 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, GA, Zero);
920 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel053c1da2008-01-29 02:16:57 +0000921 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000922 } else {
923 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000924 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000925 abort();
926 /*NOTREACHED*/
927 }
928
Dan Gohman475871a2008-07-27 21:46:04 +0000929 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000930}
931
Nate Begemanccef5802008-02-14 18:43:04 +0000932//! Custom lower double precision floating point constants
Dan Gohman475871a2008-07-27 21:46:04 +0000933static SDValue
934LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000935 MVT VT = Op.getValueType();
Dale Johannesende064702009-02-06 21:50:26 +0000936 // FIXME there is no actual debug info here
937 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000938
Nate Begemanccef5802008-02-14 18:43:04 +0000939 if (VT == MVT::f64) {
Scott Michel1a6cdb62008-12-01 17:56:02 +0000940 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
941
942 assert((FP != 0) &&
943 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel1df30c42008-12-29 03:23:36 +0000944
Scott Michel170783a2007-12-19 20:15:47 +0000945 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel1a6cdb62008-12-01 17:56:02 +0000946 SDValue T = DAG.getConstant(dbits, MVT::i64);
Evan Chenga87008d2009-02-25 22:49:59 +0000947 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T);
Dale Johannesende064702009-02-06 21:50:26 +0000948 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000949 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Tvec));
Scott Michel266bc8f2007-12-04 22:23:35 +0000950 }
951
Dan Gohman475871a2008-07-27 21:46:04 +0000952 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000953}
954
Dan Gohman475871a2008-07-27 21:46:04 +0000955static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000956LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel266bc8f2007-12-04 22:23:35 +0000957{
958 MachineFunction &MF = DAG.getMachineFunction();
959 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000960 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Micheld976c212008-10-30 01:51:48 +0000961 SmallVector<SDValue, 48> ArgValues;
Dan Gohman475871a2008-07-27 21:46:04 +0000962 SDValue Root = Op.getOperand(0);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000963 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Dale Johannesen33c960f2009-02-04 20:06:27 +0000964 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000965
966 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
967 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000968
Scott Michel266bc8f2007-12-04 22:23:35 +0000969 unsigned ArgOffset = SPUFrameInfo::minStackSize();
970 unsigned ArgRegIdx = 0;
971 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000972
Duncan Sands83ec4b62008-06-06 12:08:01 +0000973 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000974
Scott Michel266bc8f2007-12-04 22:23:35 +0000975 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif93c53e52008-08-31 15:37:04 +0000976 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
977 ArgNo != e; ++ArgNo) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000978 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
979 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Micheld976c212008-10-30 01:51:48 +0000980 SDValue ArgVal;
Scott Michel266bc8f2007-12-04 22:23:35 +0000981
Scott Micheld976c212008-10-30 01:51:48 +0000982 if (ArgRegIdx < NumArgRegs) {
983 const TargetRegisterClass *ArgRegClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +0000984
Scott Micheld976c212008-10-30 01:51:48 +0000985 switch (ObjectVT.getSimpleVT()) {
986 default: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000987 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
988 << ObjectVT.getMVTString()
989 << "\n";
990 abort();
Scott Micheld976c212008-10-30 01:51:48 +0000991 }
992 case MVT::i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000993 ArgRegClass = &SPU::R8CRegClass;
994 break;
Scott Micheld976c212008-10-30 01:51:48 +0000995 case MVT::i16:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000996 ArgRegClass = &SPU::R16CRegClass;
997 break;
Scott Micheld976c212008-10-30 01:51:48 +0000998 case MVT::i32:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000999 ArgRegClass = &SPU::R32CRegClass;
1000 break;
Scott Micheld976c212008-10-30 01:51:48 +00001001 case MVT::i64:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001002 ArgRegClass = &SPU::R64CRegClass;
1003 break;
Scott Micheldd950092009-01-06 03:36:14 +00001004 case MVT::i128:
1005 ArgRegClass = &SPU::GPRCRegClass;
1006 break;
Scott Micheld976c212008-10-30 01:51:48 +00001007 case MVT::f32:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001008 ArgRegClass = &SPU::R32FPRegClass;
1009 break;
Scott Micheld976c212008-10-30 01:51:48 +00001010 case MVT::f64:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001011 ArgRegClass = &SPU::R64FPRegClass;
1012 break;
Scott Micheld976c212008-10-30 01:51:48 +00001013 case MVT::v2f64:
1014 case MVT::v4f32:
1015 case MVT::v2i64:
1016 case MVT::v4i32:
1017 case MVT::v8i16:
1018 case MVT::v16i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001019 ArgRegClass = &SPU::VECREGRegClass;
1020 break;
Scott Micheld976c212008-10-30 01:51:48 +00001021 }
1022
1023 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
1024 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001025 ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT);
Scott Micheld976c212008-10-30 01:51:48 +00001026 ++ArgRegIdx;
1027 } else {
1028 // We need to load the argument to a virtual register if we determined
1029 // above that we ran out of physical registers of the appropriate type
1030 // or we're forced to do vararg
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001031 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +00001032 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001033 ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001034 ArgOffset += StackSlotSize;
1035 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001036
Scott Michel266bc8f2007-12-04 22:23:35 +00001037 ArgValues.push_back(ArgVal);
Scott Micheld976c212008-10-30 01:51:48 +00001038 // Update the chain
1039 Root = ArgVal.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001040 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001041
Scott Micheld976c212008-10-30 01:51:48 +00001042 // vararg handling:
Scott Michel266bc8f2007-12-04 22:23:35 +00001043 if (isVarArg) {
Scott Micheld976c212008-10-30 01:51:48 +00001044 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
1045 // We will spill (79-3)+1 registers to the stack
1046 SmallVector<SDValue, 79-3+1> MemOps;
1047
1048 // Create the frame slot
1049
Scott Michel266bc8f2007-12-04 22:23:35 +00001050 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Micheld976c212008-10-30 01:51:48 +00001051 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1052 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1053 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001054 SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0);
Scott Micheld976c212008-10-30 01:51:48 +00001055 Root = Store.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001056 MemOps.push_back(Store);
Scott Micheld976c212008-10-30 01:51:48 +00001057
1058 // Increment address by stack slot size for the next stored argument
1059 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001060 }
1061 if (!MemOps.empty())
Scott Michel6e1d1472009-03-16 18:47:25 +00001062 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001063 &MemOps[0], MemOps.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001064 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001065
Scott Michel266bc8f2007-12-04 22:23:35 +00001066 ArgValues.push_back(Root);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001067
Scott Michel266bc8f2007-12-04 22:23:35 +00001068 // Return the new list of results.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001069 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
Duncan Sandsaaffa052008-12-01 11:41:29 +00001070 &ArgValues[0], ArgValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001071}
1072
1073/// isLSAAddress - Return the immediate to use if the specified
1074/// value is representable as a LSA address.
Dan Gohman475871a2008-07-27 21:46:04 +00001075static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001076 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +00001077 if (!C) return 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001078
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001079 int Addr = C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001080 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1081 (Addr << 14 >> 14) != Addr)
1082 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001083
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001084 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel266bc8f2007-12-04 22:23:35 +00001085}
1086
Scott Michel21213e72009-01-06 23:10:38 +00001087static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +00001088LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman095cc292008-09-13 01:54:27 +00001089 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1090 SDValue Chain = TheCall->getChain();
Dan Gohman095cc292008-09-13 01:54:27 +00001091 SDValue Callee = TheCall->getCallee();
1092 unsigned NumOps = TheCall->getNumArgs();
Scott Michel266bc8f2007-12-04 22:23:35 +00001093 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1094 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1095 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Dale Johannesen33c960f2009-02-04 20:06:27 +00001096 DebugLoc dl = TheCall->getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001097
1098 // Handy pointer type
Duncan Sands83ec4b62008-06-06 12:08:01 +00001099 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001100
Scott Michel266bc8f2007-12-04 22:23:35 +00001101 // Accumulate how many bytes are to be pushed on the stack, including the
1102 // linkage area, and parameter passing area. According to the SPU ABI,
1103 // we minimally need space for [LR] and [SP]
1104 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001105
Scott Michel266bc8f2007-12-04 22:23:35 +00001106 // Set up a copy of the stack pointer for use loading and storing any
1107 // arguments that may not fit in the registers available for argument
1108 // passing.
Dan Gohman475871a2008-07-27 21:46:04 +00001109 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001110
Scott Michel266bc8f2007-12-04 22:23:35 +00001111 // Figure out which arguments are going to go in registers, and which in
1112 // memory.
1113 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1114 unsigned ArgRegIdx = 0;
1115
1116 // Keep track of registers passing arguments
Dan Gohman475871a2008-07-27 21:46:04 +00001117 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel266bc8f2007-12-04 22:23:35 +00001118 // And the arguments passed on the stack
Dan Gohman475871a2008-07-27 21:46:04 +00001119 SmallVector<SDValue, 8> MemOpChains;
Scott Michel266bc8f2007-12-04 22:23:35 +00001120
1121 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman095cc292008-09-13 01:54:27 +00001122 SDValue Arg = TheCall->getArg(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001123
Scott Michel266bc8f2007-12-04 22:23:35 +00001124 // PtrOff will be used to store the current argument to the stack if a
1125 // register cannot be found for it.
Dan Gohman475871a2008-07-27 21:46:04 +00001126 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Dale Johannesen33c960f2009-02-04 20:06:27 +00001127 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
Scott Michel266bc8f2007-12-04 22:23:35 +00001128
Duncan Sands83ec4b62008-06-06 12:08:01 +00001129 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001130 default: assert(0 && "Unexpected ValueType for argument!");
Scott Micheldd950092009-01-06 03:36:14 +00001131 case MVT::i8:
1132 case MVT::i16:
Scott Michel266bc8f2007-12-04 22:23:35 +00001133 case MVT::i32:
1134 case MVT::i64:
1135 case MVT::i128:
1136 if (ArgRegIdx != NumArgRegs) {
1137 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1138 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001139 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001140 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001141 }
1142 break;
1143 case MVT::f32:
1144 case MVT::f64:
1145 if (ArgRegIdx != NumArgRegs) {
1146 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1147 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001148 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001149 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001150 }
1151 break;
Scott Michelcc188272008-12-04 21:01:44 +00001152 case MVT::v2i64:
1153 case MVT::v2f64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001154 case MVT::v4f32:
1155 case MVT::v4i32:
1156 case MVT::v8i16:
1157 case MVT::v16i8:
1158 if (ArgRegIdx != NumArgRegs) {
1159 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1160 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001161 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001162 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001163 }
1164 break;
1165 }
1166 }
1167
1168 // Update number of stack bytes actually used, insert a call sequence start
1169 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnere563bbc2008-10-11 22:08:30 +00001170 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1171 true));
Scott Michel266bc8f2007-12-04 22:23:35 +00001172
1173 if (!MemOpChains.empty()) {
1174 // Adjust the stack pointer for the stack arguments.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001175 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Scott Michel266bc8f2007-12-04 22:23:35 +00001176 &MemOpChains[0], MemOpChains.size());
1177 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001178
Scott Michel266bc8f2007-12-04 22:23:35 +00001179 // Build a sequence of copy-to-reg nodes chained together with token chain
1180 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman475871a2008-07-27 21:46:04 +00001181 SDValue InFlag;
Scott Michel266bc8f2007-12-04 22:23:35 +00001182 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
Scott Michel6e1d1472009-03-16 18:47:25 +00001183 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001184 RegsToPass[i].second, InFlag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001185 InFlag = Chain.getValue(1);
1186 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001187
Dan Gohman475871a2008-07-27 21:46:04 +00001188 SmallVector<SDValue, 8> Ops;
Scott Michel266bc8f2007-12-04 22:23:35 +00001189 unsigned CallOpc = SPUISD::CALL;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001190
Bill Wendling056292f2008-09-16 21:48:12 +00001191 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1192 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1193 // node so that legalize doesn't hack it.
Scott Michel19fd42a2008-11-11 03:06:06 +00001194 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001195 GlobalValue *GV = G->getGlobal();
Duncan Sands83ec4b62008-06-06 12:08:01 +00001196 MVT CalleeVT = Callee.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001197 SDValue Zero = DAG.getConstant(0, PtrVT);
1198 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001199
Scott Michel9de5d0d2008-01-11 02:53:15 +00001200 if (!ST->usingLargeMem()) {
1201 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1202 // style calls, otherwise, external symbols are BRASL calls. This assumes
1203 // that declared/defined symbols are in the same compilation unit and can
1204 // be reached through PC-relative jumps.
1205 //
1206 // NOTE:
1207 // This may be an unsafe assumption for JIT and really large compilation
1208 // units.
1209 if (GV->isDeclaration()) {
Dale Johannesende064702009-02-06 21:50:26 +00001210 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001211 } else {
Dale Johannesende064702009-02-06 21:50:26 +00001212 Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001213 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001214 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001215 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1216 // address pairs:
Dale Johannesende064702009-02-06 21:50:26 +00001217 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001218 }
Scott Michel1df30c42008-12-29 03:23:36 +00001219 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1220 MVT CalleeVT = Callee.getValueType();
1221 SDValue Zero = DAG.getConstant(0, PtrVT);
1222 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1223 Callee.getValueType());
1224
1225 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +00001226 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero);
Scott Michel1df30c42008-12-29 03:23:36 +00001227 } else {
Dale Johannesende064702009-02-06 21:50:26 +00001228 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero);
Scott Michel1df30c42008-12-29 03:23:36 +00001229 }
1230 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001231 // If this is an absolute destination address that appears to be a legal
1232 // local store address, use the munged value.
Dan Gohman475871a2008-07-27 21:46:04 +00001233 Callee = SDValue(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001234 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001235
1236 Ops.push_back(Chain);
1237 Ops.push_back(Callee);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001238
Scott Michel266bc8f2007-12-04 22:23:35 +00001239 // Add argument registers to the end of the list so that they are known live
1240 // into the call.
1241 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel5af8f0e2008-07-16 17:17:29 +00001242 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel266bc8f2007-12-04 22:23:35 +00001243 RegsToPass[i].second.getValueType()));
Scott Michel5af8f0e2008-07-16 17:17:29 +00001244
Gabor Greifba36cb52008-08-28 21:40:38 +00001245 if (InFlag.getNode())
Scott Michel266bc8f2007-12-04 22:23:35 +00001246 Ops.push_back(InFlag);
Duncan Sands4bdcb612008-07-02 17:40:58 +00001247 // Returns a chain and a flag for retval copy to use.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001248 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag),
Duncan Sands4bdcb612008-07-02 17:40:58 +00001249 &Ops[0], Ops.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001250 InFlag = Chain.getValue(1);
1251
Chris Lattnere563bbc2008-10-11 22:08:30 +00001252 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1253 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman095cc292008-09-13 01:54:27 +00001254 if (TheCall->getValueType(0) != MVT::Other)
Evan Chengebaaa912008-02-05 22:44:06 +00001255 InFlag = Chain.getValue(1);
1256
Dan Gohman475871a2008-07-27 21:46:04 +00001257 SDValue ResultVals[3];
Scott Michel266bc8f2007-12-04 22:23:35 +00001258 unsigned NumResults = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001259
Scott Michel266bc8f2007-12-04 22:23:35 +00001260 // If the call has results, copy the values out of the ret val registers.
Dan Gohman095cc292008-09-13 01:54:27 +00001261 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001262 default: assert(0 && "Unexpected ret value!");
1263 case MVT::Other: break;
1264 case MVT::i32:
Dan Gohman095cc292008-09-13 01:54:27 +00001265 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel6e1d1472009-03-16 18:47:25 +00001266 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001267 MVT::i32, InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001268 ResultVals[0] = Chain.getValue(0);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001269 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Scott Michel266bc8f2007-12-04 22:23:35 +00001270 Chain.getValue(2)).getValue(1);
1271 ResultVals[1] = Chain.getValue(0);
1272 NumResults = 2;
Scott Michel266bc8f2007-12-04 22:23:35 +00001273 } else {
Scott Michel6e1d1472009-03-16 18:47:25 +00001274 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001275 InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001276 ResultVals[0] = Chain.getValue(0);
1277 NumResults = 1;
1278 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001279 break;
1280 case MVT::i64:
Scott Michel6e1d1472009-03-16 18:47:25 +00001281 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001282 InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001283 ResultVals[0] = Chain.getValue(0);
1284 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001285 break;
Scott Micheldd950092009-01-06 03:36:14 +00001286 case MVT::i128:
Scott Michel6e1d1472009-03-16 18:47:25 +00001287 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001288 InFlag).getValue(1);
Scott Micheldd950092009-01-06 03:36:14 +00001289 ResultVals[0] = Chain.getValue(0);
1290 NumResults = 1;
1291 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00001292 case MVT::f32:
1293 case MVT::f64:
Dale Johannesen33c960f2009-02-04 20:06:27 +00001294 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001295 InFlag).getValue(1);
1296 ResultVals[0] = Chain.getValue(0);
1297 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001298 break;
1299 case MVT::v2f64:
Scott Michelcc188272008-12-04 21:01:44 +00001300 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001301 case MVT::v4f32:
1302 case MVT::v4i32:
1303 case MVT::v8i16:
1304 case MVT::v16i8:
Dale Johannesen33c960f2009-02-04 20:06:27 +00001305 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001306 InFlag).getValue(1);
1307 ResultVals[0] = Chain.getValue(0);
1308 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001309 break;
1310 }
Duncan Sands4bdcb612008-07-02 17:40:58 +00001311
Scott Michel266bc8f2007-12-04 22:23:35 +00001312 // If the function returns void, just return the chain.
1313 if (NumResults == 0)
1314 return Chain;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001315
Scott Michel266bc8f2007-12-04 22:23:35 +00001316 // Otherwise, merge everything together with a MERGE_VALUES node.
1317 ResultVals[NumResults++] = Chain;
Dale Johannesen33c960f2009-02-04 20:06:27 +00001318 SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl);
Gabor Greif99a6cb92008-08-26 22:36:50 +00001319 return Res.getValue(Op.getResNo());
Scott Michel266bc8f2007-12-04 22:23:35 +00001320}
1321
Dan Gohman475871a2008-07-27 21:46:04 +00001322static SDValue
1323LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001324 SmallVector<CCValAssign, 16> RVLocs;
1325 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1326 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
Dale Johannesena05dca42009-02-04 23:02:30 +00001327 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001328 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greifba36cb52008-08-28 21:40:38 +00001329 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001330
Scott Michel266bc8f2007-12-04 22:23:35 +00001331 // If this is the first return lowered for this function, add the regs to the
1332 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001333 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001334 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001335 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001336 }
1337
Dan Gohman475871a2008-07-27 21:46:04 +00001338 SDValue Chain = Op.getOperand(0);
1339 SDValue Flag;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001340
Scott Michel266bc8f2007-12-04 22:23:35 +00001341 // Copy the result values into the output registers.
1342 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1343 CCValAssign &VA = RVLocs[i];
1344 assert(VA.isRegLoc() && "Can only return in registers!");
Dale Johannesena05dca42009-02-04 23:02:30 +00001345 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
1346 Op.getOperand(i*2+1), Flag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001347 Flag = Chain.getValue(1);
1348 }
1349
Gabor Greifba36cb52008-08-28 21:40:38 +00001350 if (Flag.getNode())
Dale Johannesena05dca42009-02-04 23:02:30 +00001351 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001352 else
Dale Johannesena05dca42009-02-04 23:02:30 +00001353 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain);
Scott Michel266bc8f2007-12-04 22:23:35 +00001354}
1355
1356
1357//===----------------------------------------------------------------------===//
1358// Vector related lowering:
1359//===----------------------------------------------------------------------===//
1360
1361static ConstantSDNode *
1362getVecImm(SDNode *N) {
Dan Gohman475871a2008-07-27 21:46:04 +00001363 SDValue OpVal(0, 0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001364
Scott Michel266bc8f2007-12-04 22:23:35 +00001365 // Check to see if this buildvec has a single non-undef value in its elements.
1366 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1367 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greifba36cb52008-08-28 21:40:38 +00001368 if (OpVal.getNode() == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +00001369 OpVal = N->getOperand(i);
1370 else if (OpVal != N->getOperand(i))
1371 return 0;
1372 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001373
Gabor Greifba36cb52008-08-28 21:40:38 +00001374 if (OpVal.getNode() != 0) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001375 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001376 return CN;
1377 }
1378 }
1379
Scott Michel7ea02ff2009-03-17 01:15:45 +00001380 return 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001381}
1382
1383/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1384/// and the value fits into an unsigned 18-bit constant, and if so, return the
1385/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001386SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001387 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001388 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001389 uint64_t Value = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001390 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001391 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001392 uint32_t upper = uint32_t(UValue >> 32);
1393 uint32_t lower = uint32_t(UValue);
1394 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001395 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001396 Value = Value >> 32;
1397 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001398 if (Value <= 0x3ffff)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001399 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001400 }
1401
Dan Gohman475871a2008-07-27 21:46:04 +00001402 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001403}
1404
1405/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1406/// and the value fits into a signed 16-bit constant, and if so, return the
1407/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001408SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001409 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001410 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001411 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001412 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001413 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001414 uint32_t upper = uint32_t(UValue >> 32);
1415 uint32_t lower = uint32_t(UValue);
1416 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001417 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001418 Value = Value >> 32;
1419 }
Scott Michelad2715e2008-03-05 23:02:02 +00001420 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001421 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001422 }
1423 }
1424
Dan Gohman475871a2008-07-27 21:46:04 +00001425 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001426}
1427
1428/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1429/// and the value fits into a signed 10-bit constant, and if so, return the
1430/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001431SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001432 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001433 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001434 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001435 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001436 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001437 uint32_t upper = uint32_t(UValue >> 32);
1438 uint32_t lower = uint32_t(UValue);
1439 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001440 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001441 Value = Value >> 32;
1442 }
Scott Michelad2715e2008-03-05 23:02:02 +00001443 if (isS10Constant(Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001444 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001445 }
1446
Dan Gohman475871a2008-07-27 21:46:04 +00001447 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001448}
1449
1450/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1451/// and the value fits into a signed 8-bit constant, and if so, return the
1452/// constant.
1453///
1454/// @note: The incoming vector is v16i8 because that's the only way we can load
1455/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1456/// same value.
Dan Gohman475871a2008-07-27 21:46:04 +00001457SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001458 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001459 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001460 int Value = (int) CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001461 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001462 && Value <= 0xffff /* truncated from uint64_t */
1463 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001464 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001465 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001466 && (Value & 0xff) == Value)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001467 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001468 }
1469
Dan Gohman475871a2008-07-27 21:46:04 +00001470 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001471}
1472
1473/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1474/// and the value fits into a signed 16-bit constant, and if so, return the
1475/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001476SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001477 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001478 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001479 uint64_t Value = CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001480 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001481 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1482 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001483 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001484 }
1485
Dan Gohman475871a2008-07-27 21:46:04 +00001486 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001487}
1488
1489/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001490SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001491 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001492 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001493 }
1494
Dan Gohman475871a2008-07-27 21:46:04 +00001495 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001496}
1497
1498/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001499SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001500 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001501 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001502 }
1503
Dan Gohman475871a2008-07-27 21:46:04 +00001504 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001505}
1506
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001507//! Lower a BUILD_VECTOR instruction creatively:
1508SDValue
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001509LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001510 MVT VT = Op.getValueType();
Scott Michel7ea02ff2009-03-17 01:15:45 +00001511 MVT EltVT = VT.getVectorElementType();
Dale Johannesened2eee62009-02-06 01:31:28 +00001512 DebugLoc dl = Op.getDebugLoc();
Scott Michel7ea02ff2009-03-17 01:15:45 +00001513 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(Op.getNode());
1514 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerBUILD_VECTOR");
1515 unsigned minSplatBits = EltVT.getSizeInBits();
1516
1517 if (minSplatBits < 16)
1518 minSplatBits = 16;
1519
1520 APInt APSplatBits, APSplatUndef;
1521 unsigned SplatBitSize;
1522 bool HasAnyUndefs;
1523
1524 if (!BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
1525 HasAnyUndefs, minSplatBits)
1526 || minSplatBits < SplatBitSize)
1527 return SDValue(); // Wasn't a constant vector or splat exceeded min
1528
1529 uint64_t SplatBits = APSplatBits.getZExtValue();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001530
Duncan Sands83ec4b62008-06-06 12:08:01 +00001531 switch (VT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001532 default:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001533 cerr << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
1534 << VT.getMVTString()
1535 << "\n";
1536 abort();
1537 /*NOTREACHED*/
Scott Michel266bc8f2007-12-04 22:23:35 +00001538 case MVT::v4f32: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001539 uint32_t Value32 = uint32_t(SplatBits);
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001540 assert(SplatBitSize == 32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001541 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001542 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001543 SDValue T = DAG.getConstant(Value32, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001544 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4f32,
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001545 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001546 break;
1547 }
1548 case MVT::v2f64: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001549 uint64_t f64val = uint64_t(SplatBits);
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001550 assert(SplatBitSize == 64
Scott Michel104de432008-11-24 17:11:17 +00001551 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001552 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001553 SDValue T = DAG.getConstant(f64val, MVT::i64);
Dale Johannesened2eee62009-02-06 01:31:28 +00001554 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64,
Evan Chenga87008d2009-02-25 22:49:59 +00001555 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001556 break;
1557 }
1558 case MVT::v16i8: {
1559 // 8-bit constants have to be expanded to 16-bits
Scott Michel7ea02ff2009-03-17 01:15:45 +00001560 unsigned short Value16 = SplatBits /* | (SplatBits << 8) */;
1561 SmallVector<SDValue, 8> Ops;
1562
1563 Ops.assign(8, DAG.getConstant(Value16, MVT::i16));
Dale Johannesened2eee62009-02-06 01:31:28 +00001564 return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
Scott Michel7ea02ff2009-03-17 01:15:45 +00001565 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001566 }
1567 case MVT::v8i16: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001568 unsigned short Value16 = SplatBits;
1569 SDValue T = DAG.getConstant(Value16, EltVT);
1570 SmallVector<SDValue, 8> Ops;
1571
1572 Ops.assign(8, T);
1573 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001574 }
1575 case MVT::v4i32: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001576 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga87008d2009-02-25 22:49:59 +00001577 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
Scott Michel266bc8f2007-12-04 22:23:35 +00001578 }
Scott Michel21213e72009-01-06 23:10:38 +00001579 case MVT::v2i32: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001580 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga87008d2009-02-25 22:49:59 +00001581 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T);
Scott Michel21213e72009-01-06 23:10:38 +00001582 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001583 case MVT::v2i64: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001584 return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
Scott Michel266bc8f2007-12-04 22:23:35 +00001585 }
1586 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001587
Dan Gohman475871a2008-07-27 21:46:04 +00001588 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001589}
1590
Scott Michel7ea02ff2009-03-17 01:15:45 +00001591/*!
1592 */
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001593SDValue
Scott Michel7ea02ff2009-03-17 01:15:45 +00001594SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal,
1595 DebugLoc dl) {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001596 uint32_t upper = uint32_t(SplatVal >> 32);
1597 uint32_t lower = uint32_t(SplatVal);
1598
1599 if (upper == lower) {
1600 // Magic constant that can be matched by IL, ILA, et. al.
1601 SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001602 return DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001603 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1604 Val, Val, Val, Val));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001605 } else {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001606 bool upper_special, lower_special;
1607
1608 // NOTE: This code creates common-case shuffle masks that can be easily
1609 // detected as common expressions. It is not attempting to create highly
1610 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1611
1612 // Detect if the upper or lower half is a special shuffle mask pattern:
1613 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1614 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1615
Scott Michel7ea02ff2009-03-17 01:15:45 +00001616 // Both upper and lower are special, lower to a constant pool load:
1617 if (lower_special && upper_special) {
1618 SDValue SplatValCN = DAG.getConstant(SplatVal, MVT::i64);
1619 return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
1620 SplatValCN, SplatValCN);
1621 }
1622
1623 SDValue LO32;
1624 SDValue HI32;
1625 SmallVector<SDValue, 16> ShufBytes;
1626 SDValue Result;
1627
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001628 // Create lower vector if not a special pattern
1629 if (!lower_special) {
1630 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001631 LO32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001632 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1633 LO32C, LO32C, LO32C, LO32C));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001634 }
1635
1636 // Create upper vector if not a special pattern
1637 if (!upper_special) {
1638 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001639 HI32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001640 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1641 HI32C, HI32C, HI32C, HI32C));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001642 }
1643
1644 // If either upper or lower are special, then the two input operands are
1645 // the same (basically, one of them is a "don't care")
1646 if (lower_special)
1647 LO32 = HI32;
1648 if (upper_special)
1649 HI32 = LO32;
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001650
1651 for (int i = 0; i < 4; ++i) {
1652 uint64_t val = 0;
1653 for (int j = 0; j < 4; ++j) {
1654 SDValue V;
1655 bool process_upper, process_lower;
1656 val <<= 8;
1657 process_upper = (upper_special && (i & 1) == 0);
1658 process_lower = (lower_special && (i & 1) == 1);
1659
1660 if (process_upper || process_lower) {
1661 if ((process_upper && upper == 0)
1662 || (process_lower && lower == 0))
1663 val |= 0x80;
1664 else if ((process_upper && upper == 0xffffffff)
1665 || (process_lower && lower == 0xffffffff))
1666 val |= 0xc0;
1667 else if ((process_upper && upper == 0x80000000)
1668 || (process_lower && lower == 0x80000000))
1669 val |= (j == 0 ? 0xe0 : 0x80);
1670 } else
1671 val |= i * 4 + j + ((i & 1) * 16);
1672 }
1673
1674 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
1675 }
1676
Dale Johannesened2eee62009-02-06 01:31:28 +00001677 return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32,
Evan Chenga87008d2009-02-25 22:49:59 +00001678 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1679 &ShufBytes[0], ShufBytes.size()));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001680 }
1681}
1682
Scott Michel266bc8f2007-12-04 22:23:35 +00001683/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1684/// which the Cell can operate. The code inspects V3 to ascertain whether the
1685/// permutation vector, V3, is monotonically increasing with one "exception"
1686/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel7a1c9e92008-11-22 23:50:42 +00001687/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel266bc8f2007-12-04 22:23:35 +00001688/// In either case, the net result is going to eventually invoke SHUFB to
1689/// permute/shuffle the bytes from V1 and V2.
1690/// \note
Scott Michel7a1c9e92008-11-22 23:50:42 +00001691/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel266bc8f2007-12-04 22:23:35 +00001692/// control word for byte/halfword/word insertion. This takes care of a single
1693/// element move from V2 into V1.
1694/// \note
1695/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman475871a2008-07-27 21:46:04 +00001696static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
Nate Begeman9008ca62009-04-27 18:41:29 +00001697 const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +00001698 SDValue V1 = Op.getOperand(0);
1699 SDValue V2 = Op.getOperand(1);
Dale Johannesena05dca42009-02-04 23:02:30 +00001700 DebugLoc dl = Op.getDebugLoc();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001701
Scott Michel266bc8f2007-12-04 22:23:35 +00001702 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001703
Scott Michel266bc8f2007-12-04 22:23:35 +00001704 // If we have a single element being moved from V1 to V2, this can be handled
1705 // using the C*[DX] compute mask instructions, but the vector elements have
1706 // to be monotonically increasing with one exception element.
Scott Michelcc188272008-12-04 21:01:44 +00001707 MVT VecVT = V1.getValueType();
1708 MVT EltVT = VecVT.getVectorElementType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001709 unsigned EltsFromV2 = 0;
1710 unsigned V2Elt = 0;
1711 unsigned V2EltIdx0 = 0;
1712 unsigned CurrElt = 0;
Scott Michelcc188272008-12-04 21:01:44 +00001713 unsigned MaxElts = VecVT.getVectorNumElements();
1714 unsigned PrevElt = 0;
1715 unsigned V0Elt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001716 bool monotonic = true;
Scott Michelcc188272008-12-04 21:01:44 +00001717 bool rotate = true;
1718
1719 if (EltVT == MVT::i8) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001720 V2EltIdx0 = 16;
Scott Michelcc188272008-12-04 21:01:44 +00001721 } else if (EltVT == MVT::i16) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001722 V2EltIdx0 = 8;
Scott Michelcc188272008-12-04 21:01:44 +00001723 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001724 V2EltIdx0 = 4;
Scott Michelcc188272008-12-04 21:01:44 +00001725 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1726 V2EltIdx0 = 2;
1727 } else
Scott Michel266bc8f2007-12-04 22:23:35 +00001728 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1729
Nate Begeman9008ca62009-04-27 18:41:29 +00001730 for (unsigned i = 0; i != MaxElts; ++i) {
1731 if (SVN->getMaskElt(i) < 0)
1732 continue;
1733
1734 unsigned SrcElt = SVN->getMaskElt(i);
Scott Michel266bc8f2007-12-04 22:23:35 +00001735
Nate Begeman9008ca62009-04-27 18:41:29 +00001736 if (monotonic) {
1737 if (SrcElt >= V2EltIdx0) {
1738 if (1 >= (++EltsFromV2)) {
1739 V2Elt = (V2EltIdx0 - SrcElt) << 2;
Scott Michelcc188272008-12-04 21:01:44 +00001740 }
Nate Begeman9008ca62009-04-27 18:41:29 +00001741 } else if (CurrElt != SrcElt) {
1742 monotonic = false;
Scott Michelcc188272008-12-04 21:01:44 +00001743 }
1744
Nate Begeman9008ca62009-04-27 18:41:29 +00001745 ++CurrElt;
1746 }
1747
1748 if (rotate) {
1749 if (PrevElt > 0 && SrcElt < MaxElts) {
1750 if ((PrevElt == SrcElt - 1)
1751 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
Scott Michelcc188272008-12-04 21:01:44 +00001752 PrevElt = SrcElt;
Nate Begeman9008ca62009-04-27 18:41:29 +00001753 if (SrcElt == 0)
1754 V0Elt = i;
Scott Michelcc188272008-12-04 21:01:44 +00001755 } else {
Scott Michelcc188272008-12-04 21:01:44 +00001756 rotate = false;
1757 }
Nate Begeman9008ca62009-04-27 18:41:29 +00001758 } else if (PrevElt == 0) {
1759 // First time through, need to keep track of previous element
1760 PrevElt = SrcElt;
1761 } else {
1762 // This isn't a rotation, takes elements from vector 2
1763 rotate = false;
Scott Michelcc188272008-12-04 21:01:44 +00001764 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001765 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001766 }
1767
1768 if (EltsFromV2 == 1 && monotonic) {
1769 // Compute mask and shuffle
1770 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001771 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1772 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands83ec4b62008-06-06 12:08:01 +00001773 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001774 // Initialize temporary register to 0
Dan Gohman475871a2008-07-27 21:46:04 +00001775 SDValue InitTempReg =
Dale Johannesena05dca42009-02-04 23:02:30 +00001776 DAG.getCopyToReg(DAG.getEntryNode(), dl, VReg, DAG.getConstant(0, PtrVT));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001777 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman475871a2008-07-27 21:46:04 +00001778 SDValue ShufMaskOp =
Dale Johannesena05dca42009-02-04 23:02:30 +00001779 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001780 DAG.getTargetConstant(V2Elt, MVT::i32),
Dale Johannesena05dca42009-02-04 23:02:30 +00001781 DAG.getCopyFromReg(InitTempReg, dl, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001782 // Use shuffle mask in SHUFB synthetic instruction:
Scott Michel6e1d1472009-03-16 18:47:25 +00001783 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1,
Dale Johannesena05dca42009-02-04 23:02:30 +00001784 ShufMaskOp);
Scott Michelcc188272008-12-04 21:01:44 +00001785 } else if (rotate) {
1786 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michel1df30c42008-12-29 03:23:36 +00001787
Dale Johannesena05dca42009-02-04 23:02:30 +00001788 return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(),
Scott Michelcc188272008-12-04 21:01:44 +00001789 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001790 } else {
Gabor Greif93c53e52008-08-31 15:37:04 +00001791 // Convert the SHUFFLE_VECTOR mask's input element units to the
1792 // actual bytes.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001793 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001794
Dan Gohman475871a2008-07-27 21:46:04 +00001795 SmallVector<SDValue, 16> ResultMask;
Nate Begeman9008ca62009-04-27 18:41:29 +00001796 for (unsigned i = 0, e = MaxElts; i != e; ++i) {
1797 unsigned SrcElt = SVN->getMaskElt(i) < 0 ? 0 : SVN->getMaskElt(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001798
Nate Begeman9008ca62009-04-27 18:41:29 +00001799 for (unsigned j = 0; j < BytesPerElement; ++j)
1800 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001801 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001802
Evan Chenga87008d2009-02-25 22:49:59 +00001803 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
1804 &ResultMask[0], ResultMask.size());
Dale Johannesena05dca42009-02-04 23:02:30 +00001805 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
Scott Michel266bc8f2007-12-04 22:23:35 +00001806 }
1807}
1808
Dan Gohman475871a2008-07-27 21:46:04 +00001809static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1810 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Dale Johannesened2eee62009-02-06 01:31:28 +00001811 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001812
Gabor Greifba36cb52008-08-28 21:40:38 +00001813 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001814 // For a constant, build the appropriate constant vector, which will
1815 // eventually simplify to a vector register load.
1816
Gabor Greifba36cb52008-08-28 21:40:38 +00001817 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman475871a2008-07-27 21:46:04 +00001818 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001819 MVT VT;
Scott Michel266bc8f2007-12-04 22:23:35 +00001820 size_t n_copies;
1821
1822 // Create a constant vector:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001823 switch (Op.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001824 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001825 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001826 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1827 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1828 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1829 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1830 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1831 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1832 }
1833
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001834 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001835 for (size_t j = 0; j < n_copies; ++j)
1836 ConstVecValues.push_back(CValue);
1837
Evan Chenga87008d2009-02-25 22:49:59 +00001838 return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(),
1839 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001840 } else {
1841 // Otherwise, copy the value from one register to another:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001842 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001843 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1844 case MVT::i8:
1845 case MVT::i16:
1846 case MVT::i32:
1847 case MVT::i64:
1848 case MVT::f32:
1849 case MVT::f64:
Dale Johannesened2eee62009-02-06 01:31:28 +00001850 return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001851 }
1852 }
1853
Dan Gohman475871a2008-07-27 21:46:04 +00001854 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001855}
1856
Dan Gohman475871a2008-07-27 21:46:04 +00001857static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001858 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001859 SDValue N = Op.getOperand(0);
1860 SDValue Elt = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00001861 DebugLoc dl = Op.getDebugLoc();
Scott Michel7a1c9e92008-11-22 23:50:42 +00001862 SDValue retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00001863
Scott Michel7a1c9e92008-11-22 23:50:42 +00001864 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1865 // Constant argument:
1866 int EltNo = (int) C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001867
Scott Michel7a1c9e92008-11-22 23:50:42 +00001868 // sanity checks:
1869 if (VT == MVT::i8 && EltNo >= 16)
1870 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1871 else if (VT == MVT::i16 && EltNo >= 8)
1872 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1873 else if (VT == MVT::i32 && EltNo >= 4)
1874 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1875 else if (VT == MVT::i64 && EltNo >= 2)
1876 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel266bc8f2007-12-04 22:23:35 +00001877
Scott Michel7a1c9e92008-11-22 23:50:42 +00001878 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1879 // i32 and i64: Element 0 is the preferred slot
Dale Johannesened2eee62009-02-06 01:31:28 +00001880 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001881 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001882
Scott Michel7a1c9e92008-11-22 23:50:42 +00001883 // Need to generate shuffle mask and extract:
1884 int prefslot_begin = -1, prefslot_end = -1;
1885 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1886
1887 switch (VT.getSimpleVT()) {
1888 default:
1889 assert(false && "Invalid value type!");
1890 case MVT::i8: {
1891 prefslot_begin = prefslot_end = 3;
1892 break;
1893 }
1894 case MVT::i16: {
1895 prefslot_begin = 2; prefslot_end = 3;
1896 break;
1897 }
1898 case MVT::i32:
1899 case MVT::f32: {
1900 prefslot_begin = 0; prefslot_end = 3;
1901 break;
1902 }
1903 case MVT::i64:
1904 case MVT::f64: {
1905 prefslot_begin = 0; prefslot_end = 7;
1906 break;
1907 }
1908 }
1909
1910 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1911 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1912
1913 unsigned int ShufBytes[16];
1914 for (int i = 0; i < 16; ++i) {
1915 // zero fill uppper part of preferred slot, don't care about the
1916 // other slots:
1917 unsigned int mask_val;
1918 if (i <= prefslot_end) {
1919 mask_val =
1920 ((i < prefslot_begin)
1921 ? 0x80
1922 : elt_byte + (i - prefslot_begin));
1923
1924 ShufBytes[i] = mask_val;
1925 } else
1926 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1927 }
1928
1929 SDValue ShufMask[4];
1930 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michelcc188272008-12-04 21:01:44 +00001931 unsigned bidx = i * 4;
Scott Michel7a1c9e92008-11-22 23:50:42 +00001932 unsigned int bits = ((ShufBytes[bidx] << 24) |
1933 (ShufBytes[bidx+1] << 16) |
1934 (ShufBytes[bidx+2] << 8) |
1935 ShufBytes[bidx+3]);
1936 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1937 }
1938
Scott Michel7ea02ff2009-03-17 01:15:45 +00001939 SDValue ShufMaskVec =
1940 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1941 &ShufMask[0], sizeof(ShufMask)/sizeof(ShufMask[0]));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001942
Dale Johannesened2eee62009-02-06 01:31:28 +00001943 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
1944 DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(),
Scott Michel7a1c9e92008-11-22 23:50:42 +00001945 N, N, ShufMaskVec));
1946 } else {
1947 // Variable index: Rotate the requested element into slot 0, then replicate
1948 // slot 0 across the vector
1949 MVT VecVT = N.getValueType();
1950 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
1951 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
1952 abort();
1953 }
1954
1955 // Make life easier by making sure the index is zero-extended to i32
1956 if (Elt.getValueType() != MVT::i32)
Dale Johannesened2eee62009-02-06 01:31:28 +00001957 Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001958
1959 // Scale the index to a bit/byte shift quantity
1960 APInt scaleFactor =
Scott Michel104de432008-11-24 17:11:17 +00001961 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1962 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel7a1c9e92008-11-22 23:50:42 +00001963 SDValue vecShift;
Scott Michel7a1c9e92008-11-22 23:50:42 +00001964
Scott Michel104de432008-11-24 17:11:17 +00001965 if (scaleShift > 0) {
1966 // Scale the shift factor:
Dale Johannesened2eee62009-02-06 01:31:28 +00001967 Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt,
Scott Michel1a6cdb62008-12-01 17:56:02 +00001968 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001969 }
1970
Dale Johannesened2eee62009-02-06 01:31:28 +00001971 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, dl, VecVT, N, Elt);
Scott Michel104de432008-11-24 17:11:17 +00001972
1973 // Replicate the bytes starting at byte 0 across the entire vector (for
1974 // consistency with the notion of a unified register set)
Scott Michel7a1c9e92008-11-22 23:50:42 +00001975 SDValue replicate;
1976
1977 switch (VT.getSimpleVT()) {
1978 default:
1979 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
1980 abort();
1981 /*NOTREACHED*/
1982 case MVT::i8: {
Scott Michel104de432008-11-24 17:11:17 +00001983 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00001984 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1985 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001986 break;
1987 }
1988 case MVT::i16: {
Scott Michel104de432008-11-24 17:11:17 +00001989 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00001990 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1991 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001992 break;
1993 }
1994 case MVT::i32:
1995 case MVT::f32: {
1996 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00001997 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1998 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001999 break;
2000 }
2001 case MVT::i64:
2002 case MVT::f64: {
2003 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2004 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002005 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
Evan Chenga87008d2009-02-25 22:49:59 +00002006 loFactor, hiFactor, loFactor, hiFactor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002007 break;
2008 }
2009 }
2010
Dale Johannesened2eee62009-02-06 01:31:28 +00002011 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
2012 DAG.getNode(SPUISD::SHUFB, dl, VecVT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002013 vecShift, vecShift, replicate));
Scott Michel266bc8f2007-12-04 22:23:35 +00002014 }
2015
Scott Michel7a1c9e92008-11-22 23:50:42 +00002016 return retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00002017}
2018
Dan Gohman475871a2008-07-27 21:46:04 +00002019static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2020 SDValue VecOp = Op.getOperand(0);
2021 SDValue ValOp = Op.getOperand(1);
2022 SDValue IdxOp = Op.getOperand(2);
Dale Johannesened2eee62009-02-06 01:31:28 +00002023 DebugLoc dl = Op.getDebugLoc();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002024 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002025
2026 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2027 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2028
Duncan Sands83ec4b62008-06-06 12:08:01 +00002029 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel1a6cdb62008-12-01 17:56:02 +00002030 // Use $sp ($1) because it's always 16-byte aligned and it's available:
Dale Johannesened2eee62009-02-06 01:31:28 +00002031 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002032 DAG.getRegister(SPU::R1, PtrVT),
2033 DAG.getConstant(CN->getSExtValue(), PtrVT));
Dale Johannesened2eee62009-02-06 01:31:28 +00002034 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, VT, Pointer);
Scott Michel266bc8f2007-12-04 22:23:35 +00002035
Dan Gohman475871a2008-07-27 21:46:04 +00002036 SDValue result =
Dale Johannesened2eee62009-02-06 01:31:28 +00002037 DAG.getNode(SPUISD::SHUFB, dl, VT,
2038 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp),
Scott Michel1df30c42008-12-29 03:23:36 +00002039 VecOp,
Dale Johannesened2eee62009-02-06 01:31:28 +00002040 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, ShufMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00002041
2042 return result;
2043}
2044
Scott Michelf0569be2008-12-27 04:51:36 +00002045static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2046 const TargetLowering &TLI)
Scott Michela59d4692008-02-23 18:41:37 +00002047{
Dan Gohman475871a2008-07-27 21:46:04 +00002048 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Dale Johannesened2eee62009-02-06 01:31:28 +00002049 DebugLoc dl = Op.getDebugLoc();
Scott Michelf0569be2008-12-27 04:51:36 +00002050 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00002051
2052 assert(Op.getValueType() == MVT::i8);
2053 switch (Opc) {
2054 default:
2055 assert(0 && "Unhandled i8 math operator");
2056 /*NOTREACHED*/
2057 break;
Scott Michel02d711b2008-12-30 23:28:25 +00002058 case ISD::ADD: {
2059 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2060 // the result:
2061 SDValue N1 = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002062 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2063 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2064 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2065 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel02d711b2008-12-30 23:28:25 +00002066
2067 }
2068
Scott Michel266bc8f2007-12-04 22:23:35 +00002069 case ISD::SUB: {
2070 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2071 // the result:
Dan Gohman475871a2008-07-27 21:46:04 +00002072 SDValue N1 = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002073 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2074 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2075 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2076 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002077 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002078 case ISD::ROTR:
2079 case ISD::ROTL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002080 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002081 MVT N1VT = N1.getValueType();
2082
2083 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2084 if (!N1VT.bitsEq(ShiftVT)) {
2085 unsigned N1Opc = N1.getValueType().bitsLT(ShiftVT)
2086 ? ISD::ZERO_EXTEND
2087 : ISD::TRUNCATE;
2088 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2089 }
2090
2091 // Replicate lower 8-bits into upper 8:
Dan Gohman475871a2008-07-27 21:46:04 +00002092 SDValue ExpandArg =
Dale Johannesened2eee62009-02-06 01:31:28 +00002093 DAG.getNode(ISD::OR, dl, MVT::i16, N0,
2094 DAG.getNode(ISD::SHL, dl, MVT::i16,
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002095 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel7ea02ff2009-03-17 01:15:45 +00002096
2097 // Truncate back down to i8
Dale Johannesened2eee62009-02-06 01:31:28 +00002098 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2099 DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002100 }
2101 case ISD::SRL:
2102 case ISD::SHL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002103 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002104 MVT N1VT = N1.getValueType();
2105
2106 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2107 if (!N1VT.bitsEq(ShiftVT)) {
2108 unsigned N1Opc = ISD::ZERO_EXTEND;
2109
2110 if (N1.getValueType().bitsGT(ShiftVT))
2111 N1Opc = ISD::TRUNCATE;
2112
2113 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2114 }
2115
Dale Johannesened2eee62009-02-06 01:31:28 +00002116 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2117 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002118 }
2119 case ISD::SRA: {
Dan Gohman475871a2008-07-27 21:46:04 +00002120 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002121 MVT N1VT = N1.getValueType();
2122
2123 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2124 if (!N1VT.bitsEq(ShiftVT)) {
2125 unsigned N1Opc = ISD::SIGN_EXTEND;
2126
2127 if (N1VT.bitsGT(ShiftVT))
2128 N1Opc = ISD::TRUNCATE;
2129 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2130 }
2131
Dale Johannesened2eee62009-02-06 01:31:28 +00002132 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2133 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002134 }
2135 case ISD::MUL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002136 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002137
2138 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2139 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002140 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2141 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002142 break;
2143 }
2144 }
2145
Dan Gohman475871a2008-07-27 21:46:04 +00002146 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002147}
2148
2149//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman475871a2008-07-27 21:46:04 +00002150static SDValue
2151LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2152 SDValue ConstVec;
2153 SDValue Arg;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002154 MVT VT = Op.getValueType();
Dale Johannesened2eee62009-02-06 01:31:28 +00002155 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002156
2157 ConstVec = Op.getOperand(0);
2158 Arg = Op.getOperand(1);
Gabor Greifba36cb52008-08-28 21:40:38 +00002159 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2160 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002161 ConstVec = ConstVec.getOperand(0);
2162 } else {
2163 ConstVec = Op.getOperand(1);
2164 Arg = Op.getOperand(0);
Gabor Greifba36cb52008-08-28 21:40:38 +00002165 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002166 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002167 }
2168 }
2169 }
2170
Gabor Greifba36cb52008-08-28 21:40:38 +00002171 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel7ea02ff2009-03-17 01:15:45 +00002172 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode());
2173 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed");
Scott Michel266bc8f2007-12-04 22:23:35 +00002174
Scott Michel7ea02ff2009-03-17 01:15:45 +00002175 APInt APSplatBits, APSplatUndef;
2176 unsigned SplatBitSize;
2177 bool HasAnyUndefs;
2178 unsigned minSplatBits = VT.getVectorElementType().getSizeInBits();
2179
2180 if (BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
2181 HasAnyUndefs, minSplatBits)
2182 && minSplatBits <= SplatBitSize) {
2183 uint64_t SplatBits = APSplatBits.getZExtValue();
Dan Gohman475871a2008-07-27 21:46:04 +00002184 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002185
Scott Michel7ea02ff2009-03-17 01:15:45 +00002186 SmallVector<SDValue, 16> tcVec;
2187 tcVec.assign(16, tc);
Dale Johannesened2eee62009-02-06 01:31:28 +00002188 return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg,
Scott Michel7ea02ff2009-03-17 01:15:45 +00002189 DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00002190 }
2191 }
Scott Michel9de57a92009-01-26 22:33:37 +00002192
Nate Begeman24dc3462008-07-29 19:07:27 +00002193 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2194 // lowered. Return the operation, rather than a null SDValue.
2195 return Op;
Scott Michel266bc8f2007-12-04 22:23:35 +00002196}
2197
Scott Michel266bc8f2007-12-04 22:23:35 +00002198//! Custom lowering for CTPOP (count population)
2199/*!
2200 Custom lowering code that counts the number ones in the input
2201 operand. SPU has such an instruction, but it counts the number of
2202 ones per byte, which then have to be accumulated.
2203*/
Dan Gohman475871a2008-07-27 21:46:04 +00002204static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002205 MVT VT = Op.getValueType();
2206 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesena05dca42009-02-04 23:02:30 +00002207 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002208
Duncan Sands83ec4b62008-06-06 12:08:01 +00002209 switch (VT.getSimpleVT()) {
2210 default:
2211 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002212 case MVT::i8: {
Dan Gohman475871a2008-07-27 21:46:04 +00002213 SDValue N = Op.getOperand(0);
2214 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002215
Dale Johannesena05dca42009-02-04 23:02:30 +00002216 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2217 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002218
Dale Johannesena05dca42009-02-04 23:02:30 +00002219 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002220 }
2221
2222 case MVT::i16: {
2223 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002224 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002225
Chris Lattner84bc5422007-12-31 04:13:23 +00002226 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002227
Dan Gohman475871a2008-07-27 21:46:04 +00002228 SDValue N = Op.getOperand(0);
2229 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2230 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002231 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002232
Dale Johannesena05dca42009-02-04 23:02:30 +00002233 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2234 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002235
2236 // CNTB_result becomes the chain to which all of the virtual registers
2237 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002238 SDValue CNTB_result =
Dale Johannesena05dca42009-02-04 23:02:30 +00002239 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002240
Dan Gohman475871a2008-07-27 21:46:04 +00002241 SDValue CNTB_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002242 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel266bc8f2007-12-04 22:23:35 +00002243
Dale Johannesena05dca42009-02-04 23:02:30 +00002244 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002245
Dale Johannesena05dca42009-02-04 23:02:30 +00002246 return DAG.getNode(ISD::AND, dl, MVT::i16,
2247 DAG.getNode(ISD::ADD, dl, MVT::i16,
2248 DAG.getNode(ISD::SRL, dl, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002249 Tmp1, Shift1),
2250 Tmp1),
2251 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002252 }
2253
2254 case MVT::i32: {
2255 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002256 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002257
Chris Lattner84bc5422007-12-31 04:13:23 +00002258 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2259 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002260
Dan Gohman475871a2008-07-27 21:46:04 +00002261 SDValue N = Op.getOperand(0);
2262 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2263 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2264 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2265 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002266
Dale Johannesena05dca42009-02-04 23:02:30 +00002267 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2268 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002269
2270 // CNTB_result becomes the chain to which all of the virtual registers
2271 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002272 SDValue CNTB_result =
Dale Johannesena05dca42009-02-04 23:02:30 +00002273 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002274
Dan Gohman475871a2008-07-27 21:46:04 +00002275 SDValue CNTB_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002276 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel266bc8f2007-12-04 22:23:35 +00002277
Dan Gohman475871a2008-07-27 21:46:04 +00002278 SDValue Comp1 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002279 DAG.getNode(ISD::SRL, dl, MVT::i32,
Scott Michel6e1d1472009-03-16 18:47:25 +00002280 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32),
Dale Johannesena05dca42009-02-04 23:02:30 +00002281 Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002282
Dan Gohman475871a2008-07-27 21:46:04 +00002283 SDValue Sum1 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002284 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp1,
2285 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002286
Dan Gohman475871a2008-07-27 21:46:04 +00002287 SDValue Sum1_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002288 DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002289
Dan Gohman475871a2008-07-27 21:46:04 +00002290 SDValue Comp2 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002291 DAG.getNode(ISD::SRL, dl, MVT::i32,
2292 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002293 Shift2);
Dan Gohman475871a2008-07-27 21:46:04 +00002294 SDValue Sum2 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002295 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp2,
2296 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002297
Dale Johannesena05dca42009-02-04 23:02:30 +00002298 return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002299 }
2300
2301 case MVT::i64:
2302 break;
2303 }
2304
Dan Gohman475871a2008-07-27 21:46:04 +00002305 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002306}
2307
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002308//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002309/*!
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002310 f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
2311 All conversions to i64 are expanded to a libcall.
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002312 */
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002313static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2314 SPUTargetLowering &TLI) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002315 MVT OpVT = Op.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002316 SDValue Op0 = Op.getOperand(0);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002317 MVT Op0VT = Op0.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002318
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002319 if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
2320 || OpVT == MVT::i64) {
2321 // Convert f32 / f64 to i32 / i64 via libcall.
2322 RTLIB::Libcall LC =
2323 (Op.getOpcode() == ISD::FP_TO_SINT)
2324 ? RTLIB::getFPTOSINT(Op0VT, OpVT)
2325 : RTLIB::getFPTOUINT(Op0VT, OpVT);
2326 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
2327 SDValue Dummy;
2328 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2329 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002330
Eli Friedman36df4992009-05-27 00:47:34 +00002331 return Op;
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002332}
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002333
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002334//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
2335/*!
2336 i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
2337 All conversions from i64 are expanded to a libcall.
2338 */
2339static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
2340 SPUTargetLowering &TLI) {
2341 MVT OpVT = Op.getValueType();
2342 SDValue Op0 = Op.getOperand(0);
2343 MVT Op0VT = Op0.getValueType();
2344
2345 if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
2346 || Op0VT == MVT::i64) {
2347 // Convert i32, i64 to f64 via libcall:
2348 RTLIB::Libcall LC =
2349 (Op.getOpcode() == ISD::SINT_TO_FP)
2350 ? RTLIB::getSINTTOFP(Op0VT, OpVT)
2351 : RTLIB::getUINTTOFP(Op0VT, OpVT);
2352 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
2353 SDValue Dummy;
2354 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2355 }
2356
Eli Friedman36df4992009-05-27 00:47:34 +00002357 return Op;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002358}
2359
2360//! Lower ISD::SETCC
2361/*!
2362 This handles MVT::f64 (double floating point) condition lowering
2363 */
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002364static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2365 const TargetLowering &TLI) {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002366 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen6f38cb62009-02-07 19:59:05 +00002367 DebugLoc dl = Op.getDebugLoc();
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002368 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2369
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002370 SDValue lhs = Op.getOperand(0);
2371 SDValue rhs = Op.getOperand(1);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002372 MVT lhsVT = lhs.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002373 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2374
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002375 MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
2376 APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2377 MVT IntVT(MVT::i64);
2378
2379 // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
2380 // selected to a NOP:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002381 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002382 SDValue lhsHi32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002383 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2384 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002385 i64lhs, DAG.getConstant(32, MVT::i32)));
2386 SDValue lhsHi32abs =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002387 DAG.getNode(ISD::AND, dl, MVT::i32,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002388 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2389 SDValue lhsLo32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002390 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002391
2392 // SETO and SETUO only use the lhs operand:
2393 if (CC->get() == ISD::SETO) {
2394 // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
2395 // SETUO
2396 APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
Dale Johannesenf5d97892009-02-04 01:48:28 +00002397 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2398 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002399 lhs, DAG.getConstantFP(0.0, lhsVT),
2400 ISD::SETUO),
2401 DAG.getConstant(ccResultAllOnes, ccResultVT));
2402 } else if (CC->get() == ISD::SETUO) {
2403 // Evaluates to true if Op0 is [SQ]NaN
Dale Johannesenf5d97892009-02-04 01:48:28 +00002404 return DAG.getNode(ISD::AND, dl, ccResultVT,
2405 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002406 lhsHi32abs,
2407 DAG.getConstant(0x7ff00000, MVT::i32),
2408 ISD::SETGE),
Dale Johannesenf5d97892009-02-04 01:48:28 +00002409 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002410 lhsLo32,
2411 DAG.getConstant(0, MVT::i32),
2412 ISD::SETGT));
2413 }
2414
Dale Johannesenb300d2a2009-02-07 00:55:49 +00002415 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, rhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002416 SDValue rhsHi32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002417 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2418 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002419 i64rhs, DAG.getConstant(32, MVT::i32)));
2420
2421 // If a value is negative, subtract from the sign magnitude constant:
2422 SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
2423
2424 // Convert the sign-magnitude representation into 2's complement:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002425 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002426 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf5d97892009-02-04 01:48:28 +00002427 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002428 SDValue lhsSelect =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002429 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002430 lhsSelectMask, lhsSignMag2TC, i64lhs);
2431
Dale Johannesenf5d97892009-02-04 01:48:28 +00002432 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002433 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf5d97892009-02-04 01:48:28 +00002434 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002435 SDValue rhsSelect =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002436 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002437 rhsSelectMask, rhsSignMag2TC, i64rhs);
2438
2439 unsigned compareOp;
2440
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002441 switch (CC->get()) {
2442 case ISD::SETOEQ:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002443 case ISD::SETUEQ:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002444 compareOp = ISD::SETEQ; break;
2445 case ISD::SETOGT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002446 case ISD::SETUGT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002447 compareOp = ISD::SETGT; break;
2448 case ISD::SETOGE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002449 case ISD::SETUGE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002450 compareOp = ISD::SETGE; break;
2451 case ISD::SETOLT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002452 case ISD::SETULT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002453 compareOp = ISD::SETLT; break;
2454 case ISD::SETOLE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002455 case ISD::SETULE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002456 compareOp = ISD::SETLE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002457 case ISD::SETUNE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002458 case ISD::SETONE:
2459 compareOp = ISD::SETNE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002460 default:
2461 cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
2462 abort();
2463 break;
2464 }
2465
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002466 SDValue result =
Scott Michel6e1d1472009-03-16 18:47:25 +00002467 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
Dale Johannesenf5d97892009-02-04 01:48:28 +00002468 (ISD::CondCode) compareOp);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002469
2470 if ((CC->get() & 0x8) == 0) {
2471 // Ordered comparison:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002472 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002473 lhs, DAG.getConstantFP(0.0, MVT::f64),
2474 ISD::SETO);
Dale Johannesenf5d97892009-02-04 01:48:28 +00002475 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002476 rhs, DAG.getConstantFP(0.0, MVT::f64),
2477 ISD::SETO);
Dale Johannesenf5d97892009-02-04 01:48:28 +00002478 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002479
Dale Johannesenf5d97892009-02-04 01:48:28 +00002480 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002481 }
2482
2483 return result;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002484}
2485
Scott Michel7a1c9e92008-11-22 23:50:42 +00002486//! Lower ISD::SELECT_CC
2487/*!
2488 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2489 SELB instruction.
2490
2491 \note Need to revisit this in the future: if the code path through the true
2492 and false value computations is longer than the latency of a branch (6
2493 cycles), then it would be more advantageous to branch and insert a new basic
2494 block and branch on the condition. However, this code does not make that
2495 assumption, given the simplisitc uses so far.
2496 */
2497
Scott Michelf0569be2008-12-27 04:51:36 +00002498static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2499 const TargetLowering &TLI) {
Scott Michel7a1c9e92008-11-22 23:50:42 +00002500 MVT VT = Op.getValueType();
2501 SDValue lhs = Op.getOperand(0);
2502 SDValue rhs = Op.getOperand(1);
2503 SDValue trueval = Op.getOperand(2);
2504 SDValue falseval = Op.getOperand(3);
2505 SDValue condition = Op.getOperand(4);
Dale Johannesende064702009-02-06 21:50:26 +00002506 DebugLoc dl = Op.getDebugLoc();
Scott Michel7a1c9e92008-11-22 23:50:42 +00002507
Scott Michelf0569be2008-12-27 04:51:36 +00002508 // NOTE: SELB's arguments: $rA, $rB, $mask
2509 //
2510 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2511 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2512 // condition was true and 0s where the condition was false. Hence, the
2513 // arguments to SELB get reversed.
2514
Scott Michel7a1c9e92008-11-22 23:50:42 +00002515 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2516 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2517 // with another "cannot select select_cc" assert:
2518
Dale Johannesende064702009-02-06 21:50:26 +00002519 SDValue compare = DAG.getNode(ISD::SETCC, dl,
Duncan Sands5480c042009-01-01 15:52:00 +00002520 TLI.getSetCCResultType(Op.getValueType()),
Scott Michelf0569be2008-12-27 04:51:36 +00002521 lhs, rhs, condition);
Dale Johannesende064702009-02-06 21:50:26 +00002522 return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002523}
2524
Scott Michelb30e8f62008-12-02 19:53:53 +00002525//! Custom lower ISD::TRUNCATE
2526static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2527{
Scott Michel6e1d1472009-03-16 18:47:25 +00002528 // Type to truncate to
Scott Michelb30e8f62008-12-02 19:53:53 +00002529 MVT VT = Op.getValueType();
2530 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2531 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesende064702009-02-06 21:50:26 +00002532 DebugLoc dl = Op.getDebugLoc();
Scott Michelb30e8f62008-12-02 19:53:53 +00002533
Scott Michel6e1d1472009-03-16 18:47:25 +00002534 // Type to truncate from
Scott Michelb30e8f62008-12-02 19:53:53 +00002535 SDValue Op0 = Op.getOperand(0);
2536 MVT Op0VT = Op0.getValueType();
Scott Michelb30e8f62008-12-02 19:53:53 +00002537
Scott Michelf0569be2008-12-27 04:51:36 +00002538 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel52d00012009-01-03 00:27:53 +00002539 // Create shuffle mask, least significant doubleword of quadword
Scott Michelf0569be2008-12-27 04:51:36 +00002540 unsigned maskHigh = 0x08090a0b;
2541 unsigned maskLow = 0x0c0d0e0f;
2542 // Use a shuffle to perform the truncation
Evan Chenga87008d2009-02-25 22:49:59 +00002543 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2544 DAG.getConstant(maskHigh, MVT::i32),
2545 DAG.getConstant(maskLow, MVT::i32),
2546 DAG.getConstant(maskHigh, MVT::i32),
2547 DAG.getConstant(maskLow, MVT::i32));
Scott Michelf0569be2008-12-27 04:51:36 +00002548
Scott Michel6e1d1472009-03-16 18:47:25 +00002549 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT,
2550 Op0, Op0, shufMask);
Scott Michelf0569be2008-12-27 04:51:36 +00002551
Scott Michel6e1d1472009-03-16 18:47:25 +00002552 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle);
Scott Michelb30e8f62008-12-02 19:53:53 +00002553 }
2554
Scott Michelf0569be2008-12-27 04:51:36 +00002555 return SDValue(); // Leave the truncate unmolested
Scott Michelb30e8f62008-12-02 19:53:53 +00002556}
2557
Scott Michel7a1c9e92008-11-22 23:50:42 +00002558//! Custom (target-specific) lowering entry point
2559/*!
2560 This is where LLVM's DAG selection process calls to do target-specific
2561 lowering of nodes.
2562 */
Dan Gohman475871a2008-07-27 21:46:04 +00002563SDValue
2564SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel266bc8f2007-12-04 22:23:35 +00002565{
Scott Michela59d4692008-02-23 18:41:37 +00002566 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002567 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002568
2569 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002570 default: {
2571 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002572 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greifba36cb52008-08-28 21:40:38 +00002573 cerr << "*Op.getNode():\n";
2574 Op.getNode()->dump();
Scott Michel266bc8f2007-12-04 22:23:35 +00002575 abort();
2576 }
2577 case ISD::LOAD:
Scott Michelb30e8f62008-12-02 19:53:53 +00002578 case ISD::EXTLOAD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002579 case ISD::SEXTLOAD:
2580 case ISD::ZEXTLOAD:
2581 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2582 case ISD::STORE:
2583 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2584 case ISD::ConstantPool:
2585 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2586 case ISD::GlobalAddress:
2587 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2588 case ISD::JumpTable:
2589 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002590 case ISD::ConstantFP:
2591 return LowerConstantFP(Op, DAG);
2592 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002593 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002594 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002595 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002596 case ISD::RET:
2597 return LowerRET(Op, DAG, getTargetMachine());
2598
Scott Michel02d711b2008-12-30 23:28:25 +00002599 // i8, i64 math ops:
Scott Michel8bf61e82008-06-02 22:18:03 +00002600 case ISD::ADD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002601 case ISD::SUB:
2602 case ISD::ROTR:
2603 case ISD::ROTL:
2604 case ISD::SRL:
2605 case ISD::SHL:
Scott Michel8bf61e82008-06-02 22:18:03 +00002606 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002607 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002608 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michela59d4692008-02-23 18:41:37 +00002609 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002610 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002611
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002612 case ISD::FP_TO_SINT:
2613 case ISD::FP_TO_UINT:
2614 return LowerFP_TO_INT(Op, DAG, *this);
2615
2616 case ISD::SINT_TO_FP:
2617 case ISD::UINT_TO_FP:
2618 return LowerINT_TO_FP(Op, DAG, *this);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002619
Scott Michel266bc8f2007-12-04 22:23:35 +00002620 // Vector-related lowering.
2621 case ISD::BUILD_VECTOR:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002622 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002623 case ISD::SCALAR_TO_VECTOR:
2624 return LowerSCALAR_TO_VECTOR(Op, DAG);
2625 case ISD::VECTOR_SHUFFLE:
2626 return LowerVECTOR_SHUFFLE(Op, DAG);
2627 case ISD::EXTRACT_VECTOR_ELT:
2628 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2629 case ISD::INSERT_VECTOR_ELT:
2630 return LowerINSERT_VECTOR_ELT(Op, DAG);
2631
2632 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2633 case ISD::AND:
2634 case ISD::OR:
2635 case ISD::XOR:
2636 return LowerByteImmed(Op, DAG);
2637
2638 // Vector and i8 multiply:
2639 case ISD::MUL:
Scott Michel02d711b2008-12-30 23:28:25 +00002640 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002641 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel266bc8f2007-12-04 22:23:35 +00002642
Scott Michel266bc8f2007-12-04 22:23:35 +00002643 case ISD::CTPOP:
2644 return LowerCTPOP(Op, DAG);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002645
2646 case ISD::SELECT_CC:
Scott Michelf0569be2008-12-27 04:51:36 +00002647 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelb30e8f62008-12-02 19:53:53 +00002648
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002649 case ISD::SETCC:
2650 return LowerSETCC(Op, DAG, *this);
2651
Scott Michelb30e8f62008-12-02 19:53:53 +00002652 case ISD::TRUNCATE:
2653 return LowerTRUNCATE(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002654 }
2655
Dan Gohman475871a2008-07-27 21:46:04 +00002656 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002657}
2658
Duncan Sands1607f052008-12-01 11:39:25 +00002659void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2660 SmallVectorImpl<SDValue>&Results,
2661 SelectionDAG &DAG)
Scott Michel73ce1c52008-11-10 23:43:06 +00002662{
2663#if 0
2664 unsigned Opc = (unsigned) N->getOpcode();
2665 MVT OpVT = N->getValueType(0);
2666
2667 switch (Opc) {
2668 default: {
2669 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2670 cerr << "Op.getOpcode() = " << Opc << "\n";
2671 cerr << "*Op.getNode():\n";
2672 N->dump();
2673 abort();
2674 /*NOTREACHED*/
2675 }
2676 }
2677#endif
2678
2679 /* Otherwise, return unchanged */
Scott Michel73ce1c52008-11-10 23:43:06 +00002680}
2681
Scott Michel266bc8f2007-12-04 22:23:35 +00002682//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002683// Target Optimization Hooks
2684//===----------------------------------------------------------------------===//
2685
Dan Gohman475871a2008-07-27 21:46:04 +00002686SDValue
Scott Michel266bc8f2007-12-04 22:23:35 +00002687SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2688{
2689#if 0
2690 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002691#endif
2692 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002693 SelectionDAG &DAG = DCI.DAG;
Scott Michel1a6cdb62008-12-01 17:56:02 +00002694 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2695 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michelf0569be2008-12-27 04:51:36 +00002696 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel1a6cdb62008-12-01 17:56:02 +00002697 SDValue Result; // Initially, empty result
Dale Johannesende064702009-02-06 21:50:26 +00002698 DebugLoc dl = N->getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002699
2700 switch (N->getOpcode()) {
2701 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002702 case ISD::ADD: {
Dan Gohman475871a2008-07-27 21:46:04 +00002703 SDValue Op1 = N->getOperand(1);
Scott Michel053c1da2008-01-29 02:16:57 +00002704
Scott Michelf0569be2008-12-27 04:51:36 +00002705 if (Op0.getOpcode() == SPUISD::IndirectAddr
2706 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2707 // Normalize the operands to reduce repeated code
2708 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michel1df30c42008-12-29 03:23:36 +00002709
Scott Michelf0569be2008-12-27 04:51:36 +00002710 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2711 IndirectArg = Op1;
2712 AddArg = Op0;
2713 }
2714
2715 if (isa<ConstantSDNode>(AddArg)) {
2716 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2717 SDValue IndOp1 = IndirectArg.getOperand(1);
2718
2719 if (CN0->isNullValue()) {
2720 // (add (SPUindirect <arg>, <arg>), 0) ->
2721 // (SPUindirect <arg>, <arg>)
Scott Michel053c1da2008-01-29 02:16:57 +00002722
Scott Michel23f2ff72008-12-04 17:16:59 +00002723#if !defined(NDEBUG)
Scott Michelf0569be2008-12-27 04:51:36 +00002724 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002725 cerr << "\n"
Scott Michelf0569be2008-12-27 04:51:36 +00002726 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2727 << "With: (SPUindirect <arg>, <arg>)\n";
2728 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002729#endif
2730
Scott Michelf0569be2008-12-27 04:51:36 +00002731 return IndirectArg;
2732 } else if (isa<ConstantSDNode>(IndOp1)) {
2733 // (add (SPUindirect <arg>, <const>), <const>) ->
2734 // (SPUindirect <arg>, <const + const>)
2735 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2736 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2737 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michel053c1da2008-01-29 02:16:57 +00002738
Scott Michelf0569be2008-12-27 04:51:36 +00002739#if !defined(NDEBUG)
2740 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2741 cerr << "\n"
2742 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2743 << "), " << CN0->getSExtValue() << ")\n"
2744 << "With: (SPUindirect <arg>, "
2745 << combinedConst << ")\n";
2746 }
2747#endif
Scott Michel053c1da2008-01-29 02:16:57 +00002748
Dale Johannesende064702009-02-06 21:50:26 +00002749 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michelf0569be2008-12-27 04:51:36 +00002750 IndirectArg, combinedValue);
2751 }
Scott Michel053c1da2008-01-29 02:16:57 +00002752 }
2753 }
Scott Michela59d4692008-02-23 18:41:37 +00002754 break;
2755 }
2756 case ISD::SIGN_EXTEND:
2757 case ISD::ZERO_EXTEND:
2758 case ISD::ANY_EXTEND: {
Scott Michel1a6cdb62008-12-01 17:56:02 +00002759 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michela59d4692008-02-23 18:41:37 +00002760 // (any_extend (SPUextract_elt0 <arg>)) ->
2761 // (SPUextract_elt0 <arg>)
2762 // Types must match, however...
Scott Michel23f2ff72008-12-04 17:16:59 +00002763#if !defined(NDEBUG)
2764 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002765 cerr << "\nReplace: ";
2766 N->dump(&DAG);
2767 cerr << "\nWith: ";
2768 Op0.getNode()->dump(&DAG);
2769 cerr << "\n";
Scott Michel23f2ff72008-12-04 17:16:59 +00002770 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002771#endif
Scott Michela59d4692008-02-23 18:41:37 +00002772
2773 return Op0;
2774 }
2775 break;
2776 }
2777 case SPUISD::IndirectAddr: {
2778 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002779 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2780 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michela59d4692008-02-23 18:41:37 +00002781 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2782 // (SPUaform <addr>, 0)
2783
2784 DEBUG(cerr << "Replace: ");
2785 DEBUG(N->dump(&DAG));
2786 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002787 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002788 DEBUG(cerr << "\n");
2789
2790 return Op0;
2791 }
Scott Michelf0569be2008-12-27 04:51:36 +00002792 } else if (Op0.getOpcode() == ISD::ADD) {
2793 SDValue Op1 = N->getOperand(1);
2794 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2795 // (SPUindirect (add <arg>, <arg>), 0) ->
2796 // (SPUindirect <arg>, <arg>)
2797 if (CN1->isNullValue()) {
2798
2799#if !defined(NDEBUG)
2800 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2801 cerr << "\n"
2802 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2803 << "With: (SPUindirect <arg>, <arg>)\n";
2804 }
2805#endif
2806
Dale Johannesende064702009-02-06 21:50:26 +00002807 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michelf0569be2008-12-27 04:51:36 +00002808 Op0.getOperand(0), Op0.getOperand(1));
2809 }
2810 }
Scott Michela59d4692008-02-23 18:41:37 +00002811 }
2812 break;
2813 }
2814 case SPUISD::SHLQUAD_L_BITS:
2815 case SPUISD::SHLQUAD_L_BYTES:
2816 case SPUISD::VEC_SHL:
2817 case SPUISD::VEC_SRL:
2818 case SPUISD::VEC_SRA:
Scott Michelf0569be2008-12-27 04:51:36 +00002819 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman475871a2008-07-27 21:46:04 +00002820 SDValue Op1 = N->getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00002821
Scott Michelf0569be2008-12-27 04:51:36 +00002822 // Kill degenerate vector shifts:
2823 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2824 if (CN->isNullValue()) {
Scott Michela59d4692008-02-23 18:41:37 +00002825 Result = Op0;
2826 }
2827 }
2828 break;
2829 }
Scott Michelf0569be2008-12-27 04:51:36 +00002830 case SPUISD::PREFSLOT2VEC: {
Scott Michela59d4692008-02-23 18:41:37 +00002831 switch (Op0.getOpcode()) {
2832 default:
2833 break;
2834 case ISD::ANY_EXTEND:
2835 case ISD::ZERO_EXTEND:
2836 case ISD::SIGN_EXTEND: {
Scott Michel1df30c42008-12-29 03:23:36 +00002837 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michela59d4692008-02-23 18:41:37 +00002838 // <arg>
Scott Michel1df30c42008-12-29 03:23:36 +00002839 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman475871a2008-07-27 21:46:04 +00002840 SDValue Op00 = Op0.getOperand(0);
Scott Michel104de432008-11-24 17:11:17 +00002841 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman475871a2008-07-27 21:46:04 +00002842 SDValue Op000 = Op00.getOperand(0);
Scott Michel1a6cdb62008-12-01 17:56:02 +00002843 if (Op000.getValueType() == NodeVT) {
Scott Michela59d4692008-02-23 18:41:37 +00002844 Result = Op000;
2845 }
2846 }
2847 break;
2848 }
Scott Michel104de432008-11-24 17:11:17 +00002849 case SPUISD::VEC2PREFSLOT: {
Scott Michel1df30c42008-12-29 03:23:36 +00002850 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michela59d4692008-02-23 18:41:37 +00002851 // <arg>
2852 Result = Op0.getOperand(0);
2853 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002854 }
Scott Michela59d4692008-02-23 18:41:37 +00002855 }
2856 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002857 }
2858 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002859
Scott Michel58c58182008-01-17 20:38:41 +00002860 // Otherwise, return unchanged.
Scott Michel1a6cdb62008-12-01 17:56:02 +00002861#ifndef NDEBUG
Gabor Greifba36cb52008-08-28 21:40:38 +00002862 if (Result.getNode()) {
Scott Michela59d4692008-02-23 18:41:37 +00002863 DEBUG(cerr << "\nReplace.SPU: ");
2864 DEBUG(N->dump(&DAG));
2865 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002866 DEBUG(Result.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002867 DEBUG(cerr << "\n");
2868 }
2869#endif
2870
2871 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002872}
2873
2874//===----------------------------------------------------------------------===//
2875// Inline Assembly Support
2876//===----------------------------------------------------------------------===//
2877
2878/// getConstraintType - Given a constraint letter, return the type of
2879/// constraint it is for this target.
Scott Michel5af8f0e2008-07-16 17:17:29 +00002880SPUTargetLowering::ConstraintType
Scott Michel266bc8f2007-12-04 22:23:35 +00002881SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2882 if (ConstraintLetter.size() == 1) {
2883 switch (ConstraintLetter[0]) {
2884 default: break;
2885 case 'b':
2886 case 'r':
2887 case 'f':
2888 case 'v':
2889 case 'y':
2890 return C_RegisterClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002891 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002892 }
2893 return TargetLowering::getConstraintType(ConstraintLetter);
2894}
2895
Scott Michel5af8f0e2008-07-16 17:17:29 +00002896std::pair<unsigned, const TargetRegisterClass*>
Scott Michel266bc8f2007-12-04 22:23:35 +00002897SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002898 MVT VT) const
Scott Michel266bc8f2007-12-04 22:23:35 +00002899{
2900 if (Constraint.size() == 1) {
2901 // GCC RS6000 Constraint Letters
2902 switch (Constraint[0]) {
2903 case 'b': // R1-R31
2904 case 'r': // R0-R31
2905 if (VT == MVT::i64)
2906 return std::make_pair(0U, SPU::R64CRegisterClass);
2907 return std::make_pair(0U, SPU::R32CRegisterClass);
2908 case 'f':
2909 if (VT == MVT::f32)
2910 return std::make_pair(0U, SPU::R32FPRegisterClass);
2911 else if (VT == MVT::f64)
2912 return std::make_pair(0U, SPU::R64FPRegisterClass);
2913 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002914 case 'v':
Scott Michel266bc8f2007-12-04 22:23:35 +00002915 return std::make_pair(0U, SPU::GPRCRegisterClass);
2916 }
2917 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00002918
Scott Michel266bc8f2007-12-04 22:23:35 +00002919 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2920}
2921
Scott Michela59d4692008-02-23 18:41:37 +00002922//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002923void
Dan Gohman475871a2008-07-27 21:46:04 +00002924SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002925 const APInt &Mask,
Scott Michel5af8f0e2008-07-16 17:17:29 +00002926 APInt &KnownZero,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002927 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002928 const SelectionDAG &DAG,
2929 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00002930#if 0
Dan Gohmande551f92009-04-01 18:45:54 +00002931 const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT;
Scott Michela59d4692008-02-23 18:41:37 +00002932
2933 switch (Op.getOpcode()) {
2934 default:
2935 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2936 break;
Scott Michela59d4692008-02-23 18:41:37 +00002937 case CALL:
2938 case SHUFB:
Scott Michel7a1c9e92008-11-22 23:50:42 +00002939 case SHUFFLE_MASK:
Scott Michela59d4692008-02-23 18:41:37 +00002940 case CNTB:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002941 case SPUISD::PREFSLOT2VEC:
Scott Michela59d4692008-02-23 18:41:37 +00002942 case SPUISD::LDRESULT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002943 case SPUISD::VEC2PREFSLOT:
Scott Michel203b2d62008-04-30 00:30:08 +00002944 case SPUISD::SHLQUAD_L_BITS:
2945 case SPUISD::SHLQUAD_L_BYTES:
2946 case SPUISD::VEC_SHL:
2947 case SPUISD::VEC_SRL:
2948 case SPUISD::VEC_SRA:
2949 case SPUISD::VEC_ROTL:
2950 case SPUISD::VEC_ROTR:
Scott Michel203b2d62008-04-30 00:30:08 +00002951 case SPUISD::ROTBYTES_LEFT:
Scott Michel8bf61e82008-06-02 22:18:03 +00002952 case SPUISD::SELECT_MASK:
2953 case SPUISD::SELB:
Scott Michela59d4692008-02-23 18:41:37 +00002954 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002955#endif
Scott Michel266bc8f2007-12-04 22:23:35 +00002956}
Scott Michel02d711b2008-12-30 23:28:25 +00002957
Scott Michelf0569be2008-12-27 04:51:36 +00002958unsigned
2959SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2960 unsigned Depth) const {
2961 switch (Op.getOpcode()) {
2962 default:
2963 return 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002964
Scott Michelf0569be2008-12-27 04:51:36 +00002965 case ISD::SETCC: {
2966 MVT VT = Op.getValueType();
2967
2968 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2969 VT = MVT::i32;
2970 }
2971 return VT.getSizeInBits();
2972 }
2973 }
2974}
Scott Michel1df30c42008-12-29 03:23:36 +00002975
Scott Michel203b2d62008-04-30 00:30:08 +00002976// LowerAsmOperandForConstraint
2977void
Dan Gohman475871a2008-07-27 21:46:04 +00002978SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michel203b2d62008-04-30 00:30:08 +00002979 char ConstraintLetter,
Evan Chengda43bcf2008-09-24 00:05:32 +00002980 bool hasMemory,
Dan Gohman475871a2008-07-27 21:46:04 +00002981 std::vector<SDValue> &Ops,
Scott Michel203b2d62008-04-30 00:30:08 +00002982 SelectionDAG &DAG) const {
2983 // Default, for the time being, to the base class handler
Evan Chengda43bcf2008-09-24 00:05:32 +00002984 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2985 Ops, DAG);
Scott Michel203b2d62008-04-30 00:30:08 +00002986}
2987
Scott Michel266bc8f2007-12-04 22:23:35 +00002988/// isLegalAddressImmediate - Return true if the integer value can be used
2989/// as the offset of the target addressing mode.
Gabor Greif93c53e52008-08-31 15:37:04 +00002990bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2991 const Type *Ty) const {
Scott Michel266bc8f2007-12-04 22:23:35 +00002992 // SPU's addresses are 256K:
2993 return (V > -(1 << 18) && V < (1 << 18) - 1);
2994}
2995
2996bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel5af8f0e2008-07-16 17:17:29 +00002997 return false;
Scott Michel266bc8f2007-12-04 22:23:35 +00002998}
Dan Gohman6520e202008-10-18 02:06:02 +00002999
3000bool
3001SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
3002 // The SPU target isn't yet aware of offsets.
3003 return false;
3004}