blob: b28644378bda8e12182ba0c7699ece1c608efea9 [file] [log] [blame]
Scott Michel8efdca42007-12-04 22:23:35 +00001//
Scott Michel0d5eae02009-03-17 01:15:45 +00002//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
Scott Michel8efdca42007-12-04 22:23:35 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel8efdca42007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michelbc5fbc12008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel06eabde2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel8efdca42007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
pingbak2f387e82009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel8efdca42007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000042 //! MVT mapping to useful data for Cell SPU
Scott Michel8efdca42007-12-04 22:23:35 +000043 struct valtype_map_s {
Scott Michel56a125e2008-11-22 23:50:42 +000044 const MVT valtype;
45 const int prefslot_byte;
Scott Michel8efdca42007-12-04 22:23:35 +000046 };
Scott Michel4ec722e2008-07-16 17:17:29 +000047
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000061 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +000066 retval = valtype_map + i;
67 break;
Scott Michel8efdca42007-12-04 22:23:35 +000068 }
69 }
70
71#ifndef NDEBUG
72 if (retval == 0) {
73 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands92c43912008-06-06 12:08:01 +000074 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +000075 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +000076 abort();
77 }
78#endif
79
80 return retval;
81 }
Scott Michel750b93f2009-01-15 04:41:47 +000082
pingbak2f387e82009-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,
Dale Johannesenca6237b2009-01-30 23:10:59 +0000116 CallingConv::C, false, Callee, Args, DAG,
Dale Johannesen2dbdb0e2009-02-07 19:59:05 +0000117 Op.getDebugLoc());
pingbak2f387e82009-01-26 03:31:40 +0000118
119 return CallInfo.first;
120 }
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000133
Scott Michel8c67fa42009-01-21 04:58:48 +0000134 // Set RTLIB libcall names as used by SPU:
135 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
136
Scott Michel8efdca42007-12-04 22:23:35 +0000137 // Set up the SPU's register classes:
Scott Michel438be252007-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 Michel8efdca42007-12-04 22:23:35 +0000144 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel4ec722e2008-07-16 17:17:29 +0000145
Scott Michel8efdca42007-12-04 22:23:35 +0000146 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng08c171a2008-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 Michel8efdca42007-12-04 22:23:35 +0000150
Scott Michel06eabde2008-12-27 04:51:36 +0000151 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
152 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelec8c82e2008-12-02 19:53:53 +0000153
Scott Michel8efdca42007-12-04 22:23:35 +0000154 // SPU constant load actions are custom lowered:
Nate Begeman78125042008-02-14 18:43:04 +0000155 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-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 Michel2ef773a2009-01-06 03:36:14 +0000159 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel8efdca42007-12-04 22:23:35 +0000160 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000161 MVT VT = (MVT::SimpleValueType)sctype;
162
Scott Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000173 }
174
Scott Michel06eabde2008-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 Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000191
192 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel4ec722e2008-07-16 17:17:29 +0000193 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel56a125e2008-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 Michel8efdca42007-12-04 22:23:35 +0000198
199 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000200 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
201
Scott Michel06eabde2008-12-27 04:51:36 +0000202 // SPU has no SREM/UREM instructions
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000207
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000215
pingbak2f387e82009-01-26 03:31:40 +0000216 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
217 // for f32!)
Scott Michel8efdca42007-12-04 22:23:35 +0000218 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
219 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000220
Scott Michel8efdca42007-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 Wendling965299c2008-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 Michel8efdca42007-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 Michelabb8ca12008-11-20 16:36:33 +0000236
Scott Michel8efdca42007-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 Michel33d73eb2008-11-21 02:56:16 +0000241
Scott Michel4d07fb72008-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 Michel8efdca42007-12-04 22:23:35 +0000246
Scott Michel4ec722e2008-07-16 17:17:29 +0000247 // Custom lower i8, i32 and i64 multiplications
248 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelae5cbf52008-12-29 03:23:36 +0000249 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel750b93f2009-01-15 04:41:47 +0000250 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel33d73eb2008-11-21 02:56:16 +0000251
Eli Friedman35be0012009-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 Michel67224b22008-06-02 22:18:03 +0000271 // Need to custom handle (some) common i8, i64 math ops
Scott Michel4d07fb72008-12-30 23:28:25 +0000272 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000273 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000274 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000275 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000276
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000291
Scott Michel67224b22008-06-02 22:18:03 +0000292 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel978b96f2008-03-10 23:49:09 +0000293 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000294 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000295 setOperationAction(ISD::SELECT, MVT::i16, Legal);
296 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel06eabde2008-12-27 04:51:36 +0000297 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000298
Scott Michel53ab7792008-03-10 16:58:52 +0000299 setOperationAction(ISD::SETCC, MVT::i8, Legal);
300 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000301 setOperationAction(ISD::SETCC, MVT::i32, Legal);
302 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel8c67fa42009-01-21 04:58:48 +0000303 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michel6baba072008-03-05 23:02:02 +0000304
Scott Michel06eabde2008-12-27 04:51:36 +0000305 // Custom lower i128 -> i64 truncates
Scott Michelec8c82e2008-12-02 19:53:53 +0000306 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
307
pingbak2f387e82009-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 Michel8efdca42007-12-04 22:23:35 +0000312
313 // FDIV on SPU requires custom lowering
pingbak2f387e82009-01-26 03:31:40 +0000314 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel8efdca42007-12-04 22:23:35 +0000315
Scott Michelc899a122009-01-26 22:33:37 +0000316 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
pingbak2f387e82009-01-26 03:31:40 +0000317 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000318 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000319 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
320 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000321 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000322 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel8efdca42007-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 Michel754d8662007-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 Michel8efdca42007-12-04 22:23:35 +0000330
331 // We cannot sextinreg(i1). Expand to shifts.
332 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000333
Scott Michel8efdca42007-12-04 22:23:35 +0000334 // Support label based line numbers.
Dan Gohman472d12c2008-06-30 20:59:49 +0000335 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000336 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000337
338 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel8efdca42007-12-04 22:23:35 +0000339 // appropriate instructions to materialize the address.
Scott Michel33d73eb2008-11-21 02:56:16 +0000340 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelf9f42e62008-01-29 02:16:57 +0000341 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000342 MVT VT = (MVT::SimpleValueType)sctype;
343
Scott Michelae5cbf52008-12-29 03:23:36 +0000344 setOperationAction(ISD::GlobalAddress, VT, Custom);
345 setOperationAction(ISD::ConstantPool, VT, Custom);
346 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelf9f42e62008-01-29 02:16:57 +0000347 }
Scott Michel8efdca42007-12-04 22:23:35 +0000348
349 // RET must be custom lowered, to meet ABI requirements
350 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000351
Scott Michel8efdca42007-12-04 22:23:35 +0000352 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
353 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000354
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000359 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000367
Scott Michel8efdca42007-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 Michel70741542009-01-06 23:10:38 +0000383 // "Odd size" vector classes that we're willing to support:
384 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
385
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000389
Duncan Sands92c43912008-06-06 12:08:01 +0000390 // add/sub are legal for all supported vector VT's.
pingbak2f387e82009-01-26 03:31:40 +0000391 setOperationAction(ISD::ADD, VT, Legal);
392 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000393 // mul has to be custom lowered.
pingbak2f387e82009-01-26 03:31:40 +0000394 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000395
pingbak2f387e82009-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 Michel4ec722e2008-07-16 17:17:29 +0000402
Scott Michel8efdca42007-12-04 22:23:35 +0000403 // These operations need to be expanded:
pingbak2f387e82009-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 Michel8efdca42007-12-04 22:23:35 +0000408
409 // Custom lower build_vector, constant pool spills, insert and
410 // extract vector elements:
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000417 }
418
Scott Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000423
Scott Michel4d07fb72008-12-30 23:28:25 +0000424 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000425
Scott Michel8efdca42007-12-04 22:23:35 +0000426 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000427 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000428
Scott Michel8efdca42007-12-04 22:23:35 +0000429 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000430
Scott Michel8efdca42007-12-04 22:23:35 +0000431 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000432 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000433 setTargetDAGCombine(ISD::ZERO_EXTEND);
434 setTargetDAGCombine(ISD::SIGN_EXTEND);
435 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000436
Scott Michel8efdca42007-12-04 22:23:35 +0000437 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000438
Scott Michel2c261072008-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 Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000453 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000454 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000458 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000459 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000460 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000461 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-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 Michel8efdca42007-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 Michel8c67fa42009-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 Michel67224b22008-06-02 22:18:03 +0000472 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000473 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel750b93f2009-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 Michel8efdca42007-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
Scott Michel06eabde2008-12-27 04:51:36 +0000484//===----------------------------------------------------------------------===//
485// Return the Cell SPU's SETCC result type
486//===----------------------------------------------------------------------===//
487
Duncan Sands4a361272009-01-01 15:52:00 +0000488MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-12-27 04:51:36 +0000489 // i16 and i32 are valid SETCC result types
490 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel53ab7792008-03-10 16:58:52 +0000491}
492
Scott Michel8efdca42007-12-04 22:23:35 +0000493//===----------------------------------------------------------------------===//
494// Calling convention code:
495//===----------------------------------------------------------------------===//
496
497#include "SPUGenCallingConv.inc"
498
499//===----------------------------------------------------------------------===//
500// LowerOperation implementation
501//===----------------------------------------------------------------------===//
502
503/// Custom lower loads for CellSPU
504/*!
505 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
506 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel6ccefab2008-12-04 03:02:42 +0000507
508 For extending loads, we also want to ensure that the following sequence is
509 emitted, e.g. for MVT::f32 extending load to MVT::f64:
510
511\verbatim
Scott Michelae5cbf52008-12-29 03:23:36 +0000512%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000513%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000514%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000515%4 f32 = vec2perfslot %3
516%5 f64 = fp_extend %4
517\endverbatim
518*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000519static SDValue
520LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000521 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000522 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000523 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000524 MVT InVT = LN->getMemoryVT();
525 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000526 ISD::LoadExtType ExtType = LN->getExtensionType();
527 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000528 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Dale Johannesenea996922009-02-04 20:06:27 +0000529 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000530
Scott Michel8efdca42007-12-04 22:23:35 +0000531 switch (LN->getAddressingMode()) {
532 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000533 SDValue result;
534 SDValue basePtr = LN->getBasePtr();
535 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000536
Scott Michel06eabde2008-12-27 04:51:36 +0000537 if (alignment == 16) {
538 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000539
Scott Michel06eabde2008-12-27 04:51:36 +0000540 // Special cases for a known aligned load to simplify the base pointer
541 // and the rotation amount:
542 if (basePtr.getOpcode() == ISD::ADD
543 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
544 // Known offset into basePtr
545 int64_t offset = CN->getSExtValue();
546 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000547
Scott Michel06eabde2008-12-27 04:51:36 +0000548 if (rotamt < 0)
549 rotamt += 16;
550
551 rotate = DAG.getConstant(rotamt, MVT::i16);
552
553 // Simplify the base pointer for this case:
554 basePtr = basePtr.getOperand(0);
555 if ((offset & ~0xf) > 0) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000556 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000557 basePtr,
558 DAG.getConstant((offset & ~0xf), PtrVT));
559 }
560 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
561 || (basePtr.getOpcode() == SPUISD::IndirectAddr
562 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
563 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
564 // Plain aligned a-form address: rotate into preferred slot
565 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
566 int64_t rotamt = -vtm->prefslot_byte;
567 if (rotamt < 0)
568 rotamt += 16;
569 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000570 } else {
Scott Michel06eabde2008-12-27 04:51:36 +0000571 // Offset the rotate amount by the basePtr and the preferred slot
572 // byte offset
573 int64_t rotamt = -vtm->prefslot_byte;
574 if (rotamt < 0)
575 rotamt += 16;
Dale Johannesenea996922009-02-04 20:06:27 +0000576 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000577 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000578 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000579 }
Scott Michel06eabde2008-12-27 04:51:36 +0000580 } else {
581 // Unaligned load: must be more pessimistic about addressing modes:
582 if (basePtr.getOpcode() == ISD::ADD) {
583 MachineFunction &MF = DAG.getMachineFunction();
584 MachineRegisterInfo &RegInfo = MF.getRegInfo();
585 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
586 SDValue Flag;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000587
Scott Michel06eabde2008-12-27 04:51:36 +0000588 SDValue Op0 = basePtr.getOperand(0);
589 SDValue Op1 = basePtr.getOperand(1);
590
591 if (isa<ConstantSDNode>(Op1)) {
592 // Convert the (add <ptr>, <const>) to an indirect address contained
593 // in a register. Note that this is done because we need to avoid
594 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000595 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesenea996922009-02-04 20:06:27 +0000596 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
597 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michel06eabde2008-12-27 04:51:36 +0000598 } else {
599 // Convert the (add <arg1>, <arg2>) to an indirect address, which
600 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000601 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel06eabde2008-12-27 04:51:36 +0000602 }
603 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000604 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000605 basePtr,
606 DAG.getConstant(0, PtrVT));
607 }
608
609 // Offset the rotate amount by the basePtr and the preferred slot
610 // byte offset
Dale Johannesenea996922009-02-04 20:06:27 +0000611 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000612 basePtr,
613 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +0000614 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000615
Scott Michel06eabde2008-12-27 04:51:36 +0000616 // Re-emit as a v16i8 vector load
Dale Johannesenea996922009-02-04 20:06:27 +0000617 result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel06eabde2008-12-27 04:51:36 +0000618 LN->getSrcValue(), LN->getSrcValueOffset(),
619 LN->isVolatile(), 16);
620
621 // Update the chain
622 the_chain = result.getValue(1);
623
624 // Rotate into the preferred slot:
Dale Johannesenea996922009-02-04 20:06:27 +0000625 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::v16i8,
Scott Michel06eabde2008-12-27 04:51:36 +0000626 result.getValue(0), rotate);
627
Scott Michel6ccefab2008-12-04 03:02:42 +0000628 // Convert the loaded v16i8 vector to the appropriate vector type
629 // specified by the operand:
630 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
Dale Johannesenea996922009-02-04 20:06:27 +0000631 result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT,
632 DAG.getNode(ISD::BIT_CONVERT, dl, vecVT, result));
Scott Michel4ec722e2008-07-16 17:17:29 +0000633
Scott Michel6ccefab2008-12-04 03:02:42 +0000634 // Handle extending loads by extending the scalar result:
635 if (ExtType == ISD::SEXTLOAD) {
Dale Johannesenea996922009-02-04 20:06:27 +0000636 result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result);
Scott Michel6ccefab2008-12-04 03:02:42 +0000637 } else if (ExtType == ISD::ZEXTLOAD) {
Dale Johannesenea996922009-02-04 20:06:27 +0000638 result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result);
Scott Michel6ccefab2008-12-04 03:02:42 +0000639 } else if (ExtType == ISD::EXTLOAD) {
640 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000641
Scott Michel6ccefab2008-12-04 03:02:42 +0000642 if (OutVT.isFloatingPoint())
pingbakb8913342009-01-26 03:37:41 +0000643 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000644
Dale Johannesenea996922009-02-04 20:06:27 +0000645 result = DAG.getNode(NewOpc, dl, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000646 }
647
Scott Michel6ccefab2008-12-04 03:02:42 +0000648 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000649 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000650 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000651 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000652 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000653
Dale Johannesenea996922009-02-04 20:06:27 +0000654 result = DAG.getNode(SPUISD::LDRESULT, dl, retvts,
Scott Michel394e26d2008-01-17 20:38:41 +0000655 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000656 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000657 }
658 case ISD::PRE_INC:
659 case ISD::PRE_DEC:
660 case ISD::POST_INC:
661 case ISD::POST_DEC:
662 case ISD::LAST_INDEXED_MODE:
663 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
664 "UNINDEXED\n";
665 cerr << (unsigned) LN->getAddressingMode() << "\n";
666 abort();
667 /*NOTREACHED*/
668 }
669
Dan Gohman8181bd12008-07-27 21:46:04 +0000670 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000671}
672
673/// Custom lower stores for CellSPU
674/*!
675 All CellSPU stores are aligned to 16-byte boundaries, so for elements
676 within a 16-byte block, we have to generate a shuffle to insert the
677 requested element into its place, then store the resulting block.
678 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000679static SDValue
680LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000681 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000682 SDValue Value = SN->getValue();
Duncan Sands92c43912008-06-06 12:08:01 +0000683 MVT VT = Value.getValueType();
684 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
685 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Dale Johannesenea996922009-02-04 20:06:27 +0000686 DebugLoc dl = Op.getDebugLoc();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000687 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000688
689 switch (SN->getAddressingMode()) {
690 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000691 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000692 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
693 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000694
Scott Michel06eabde2008-12-27 04:51:36 +0000695 SDValue alignLoadVec;
696 SDValue basePtr = SN->getBasePtr();
697 SDValue the_chain = SN->getChain();
698 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000699
Scott Michel06eabde2008-12-27 04:51:36 +0000700 if (alignment == 16) {
701 ConstantSDNode *CN;
702
703 // Special cases for a known aligned load to simplify the base pointer
704 // and insertion byte:
705 if (basePtr.getOpcode() == ISD::ADD
706 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
707 // Known offset into basePtr
708 int64_t offset = CN->getSExtValue();
709
710 // Simplify the base pointer for this case:
711 basePtr = basePtr.getOperand(0);
Dale Johannesen175fdef2009-02-06 21:50:26 +0000712 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000713 basePtr,
714 DAG.getConstant((offset & 0xf), PtrVT));
715
716 if ((offset & ~0xf) > 0) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000717 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000718 basePtr,
719 DAG.getConstant((offset & ~0xf), PtrVT));
720 }
721 } else {
722 // Otherwise, assume it's at byte 0 of basePtr
Dale Johannesen175fdef2009-02-06 21:50:26 +0000723 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000724 basePtr,
725 DAG.getConstant(0, PtrVT));
726 }
727 } else {
728 // Unaligned load: must be more pessimistic about addressing modes:
729 if (basePtr.getOpcode() == ISD::ADD) {
730 MachineFunction &MF = DAG.getMachineFunction();
731 MachineRegisterInfo &RegInfo = MF.getRegInfo();
732 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
733 SDValue Flag;
734
735 SDValue Op0 = basePtr.getOperand(0);
736 SDValue Op1 = basePtr.getOperand(1);
737
738 if (isa<ConstantSDNode>(Op1)) {
739 // Convert the (add <ptr>, <const>) to an indirect address contained
740 // in a register. Note that this is done because we need to avoid
741 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000742 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesenea996922009-02-04 20:06:27 +0000743 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
744 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michel06eabde2008-12-27 04:51:36 +0000745 } else {
746 // Convert the (add <arg1>, <arg2>) to an indirect address, which
747 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000748 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel06eabde2008-12-27 04:51:36 +0000749 }
750 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000751 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000752 basePtr,
753 DAG.getConstant(0, PtrVT));
754 }
755
756 // Insertion point is solely determined by basePtr's contents
Dale Johannesenea996922009-02-04 20:06:27 +0000757 insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000758 basePtr,
759 DAG.getConstant(0, PtrVT));
760 }
761
762 // Re-emit as a v16i8 vector load
Dale Johannesenea996922009-02-04 20:06:27 +0000763 alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel06eabde2008-12-27 04:51:36 +0000764 SN->getSrcValue(), SN->getSrcValueOffset(),
765 SN->isVolatile(), 16);
766
767 // Update the chain
768 the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000769
Scott Micheldbac4cf2008-01-11 02:53:15 +0000770 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000771 SDValue theValue = SN->getValue();
772 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000773
774 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000775 && (theValue.getOpcode() == ISD::AssertZext
776 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000777 // Drill down and get the value for zero- and sign-extended
778 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000779 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000780 }
781
Scott Micheldbac4cf2008-01-11 02:53:15 +0000782 // If the base pointer is already a D-form address, then just create
783 // a new D-form address with a slot offset and the orignal base pointer.
784 // Otherwise generate a D-form address with the slot offset relative
785 // to the stack pointer, which is always aligned.
Scott Michel06eabde2008-12-27 04:51:36 +0000786#if !defined(NDEBUG)
787 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
788 cerr << "CellSPU LowerSTORE: basePtr = ";
789 basePtr.getNode()->dump(&DAG);
790 cerr << "\n";
791 }
792#endif
Scott Micheldbac4cf2008-01-11 02:53:15 +0000793
Scott Michelf65c8f02008-11-19 15:24:16 +0000794 SDValue insertEltOp =
Dale Johannesenea996922009-02-04 20:06:27 +0000795 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000796 SDValue vectorizeOp =
Dale Johannesenea996922009-02-04 20:06:27 +0000797 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000798
Dale Johannesenea996922009-02-04 20:06:27 +0000799 result = DAG.getNode(SPUISD::SHUFB, dl, vecVT,
pingbakb8913342009-01-26 03:37:41 +0000800 vectorizeOp, alignLoadVec,
Scott Michel34712c32009-03-16 18:47:25 +0000801 DAG.getNode(ISD::BIT_CONVERT, dl,
Dale Johannesenea996922009-02-04 20:06:27 +0000802 MVT::v4i32, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000803
Dale Johannesenea996922009-02-04 20:06:27 +0000804 result = DAG.getStore(the_chain, dl, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000805 LN->getSrcValue(), LN->getSrcValueOffset(),
806 LN->isVolatile(), LN->getAlignment());
807
Scott Michel8c2746e2008-12-04 17:16:59 +0000808#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-11-19 15:24:16 +0000809 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
810 const SDValue &currentRoot = DAG.getRoot();
811
812 DAG.setRoot(result);
813 cerr << "------- CellSPU:LowerStore result:\n";
814 DAG.dump();
815 cerr << "-------\n";
816 DAG.setRoot(currentRoot);
817 }
818#endif
Scott Michelec8c82e2008-12-02 19:53:53 +0000819
Scott Michel8efdca42007-12-04 22:23:35 +0000820 return result;
821 /*UNREACHED*/
822 }
823 case ISD::PRE_INC:
824 case ISD::PRE_DEC:
825 case ISD::POST_INC:
826 case ISD::POST_DEC:
827 case ISD::LAST_INDEXED_MODE:
828 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
829 "UNINDEXED\n";
830 cerr << (unsigned) SN->getAddressingMode() << "\n";
831 abort();
832 /*NOTREACHED*/
833 }
834
Dan Gohman8181bd12008-07-27 21:46:04 +0000835 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000836}
837
Scott Michel750b93f2009-01-15 04:41:47 +0000838//! Generate the address of a constant pool entry.
839SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000840LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000841 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000842 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
843 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000844 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
845 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000846 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000847 // FIXME there is no actual debug info here
848 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000849
850 if (TM.getRelocationModel() == Reloc::Static) {
851 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000852 // Just return the SDValue with the constant pool address in it.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000853 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000854 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000855 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, CPI, Zero);
856 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, CPI, Zero);
857 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000858 }
859 }
860
861 assert(0 &&
Gabor Greife9f7f582008-08-31 15:37:04 +0000862 "LowerConstantPool: Relocation model other than static"
863 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000864 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000865}
866
Scott Michel750b93f2009-01-15 04:41:47 +0000867//! Alternate entry point for generating the address of a constant pool entry
868SDValue
869SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
870 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
871}
872
Dan Gohman8181bd12008-07-27 21:46:04 +0000873static SDValue
874LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000875 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000876 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000877 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
878 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000879 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000880 // FIXME there is no actual debug info here
881 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000882
883 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000884 if (!ST->usingLargeMem()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000885 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000886 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000887 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, JTI, Zero);
888 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, JTI, Zero);
889 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel97872d32008-02-23 18:41:37 +0000890 }
Scott Michel8efdca42007-12-04 22:23:35 +0000891 }
892
893 assert(0 &&
894 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000895 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000896}
897
Dan Gohman8181bd12008-07-27 21:46:04 +0000898static SDValue
899LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000900 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000901 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
902 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000903 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000904 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000905 SDValue Zero = DAG.getConstant(0, PtrVT);
Dale Johannesen175fdef2009-02-06 21:50:26 +0000906 // FIXME there is no actual debug info here
907 DebugLoc dl = Op.getDebugLoc();
Scott Michel4ec722e2008-07-16 17:17:29 +0000908
Scott Michel8efdca42007-12-04 22:23:35 +0000909 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000910 if (!ST->usingLargeMem()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000911 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero);
Scott Michelf9f42e62008-01-29 02:16:57 +0000912 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000913 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, GA, Zero);
914 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, GA, Zero);
915 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michelf9f42e62008-01-29 02:16:57 +0000916 }
Scott Michel8efdca42007-12-04 22:23:35 +0000917 } else {
918 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000919 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000920 abort();
921 /*NOTREACHED*/
922 }
923
Dan Gohman8181bd12008-07-27 21:46:04 +0000924 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000925}
926
Nate Begeman78125042008-02-14 18:43:04 +0000927//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000928static SDValue
929LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000930 MVT VT = Op.getValueType();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000931 // FIXME there is no actual debug info here
932 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000933
Nate Begeman78125042008-02-14 18:43:04 +0000934 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000935 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
936
937 assert((FP != 0) &&
938 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000939
Scott Michel11e88bb2007-12-19 20:15:47 +0000940 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-12-01 17:56:02 +0000941 SDValue T = DAG.getConstant(dbits, MVT::i64);
Evan Cheng907a2d22009-02-25 22:49:59 +0000942 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T);
Dale Johannesen175fdef2009-02-06 21:50:26 +0000943 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
Dale Johannesen24dd9a52009-02-07 00:55:49 +0000944 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Tvec));
Scott Michel8efdca42007-12-04 22:23:35 +0000945 }
946
Dan Gohman8181bd12008-07-27 21:46:04 +0000947 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000948}
949
Dan Gohman8181bd12008-07-27 21:46:04 +0000950static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000951LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000952{
953 MachineFunction &MF = DAG.getMachineFunction();
954 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000955 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000956 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000957 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000958 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Dale Johannesenea996922009-02-04 20:06:27 +0000959 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000960
961 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
962 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000963
Scott Michel8efdca42007-12-04 22:23:35 +0000964 unsigned ArgOffset = SPUFrameInfo::minStackSize();
965 unsigned ArgRegIdx = 0;
966 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000967
Duncan Sands92c43912008-06-06 12:08:01 +0000968 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000969
Scott Michel8efdca42007-12-04 22:23:35 +0000970 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000971 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
972 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000973 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
974 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000975 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000976
Scott Michela313fb02008-10-30 01:51:48 +0000977 if (ArgRegIdx < NumArgRegs) {
978 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000979
Scott Michela313fb02008-10-30 01:51:48 +0000980 switch (ObjectVT.getSimpleVT()) {
981 default: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000982 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
983 << ObjectVT.getMVTString()
984 << "\n";
985 abort();
Scott Michela313fb02008-10-30 01:51:48 +0000986 }
987 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000988 ArgRegClass = &SPU::R8CRegClass;
989 break;
Scott Michela313fb02008-10-30 01:51:48 +0000990 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +0000991 ArgRegClass = &SPU::R16CRegClass;
992 break;
Scott Michela313fb02008-10-30 01:51:48 +0000993 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000994 ArgRegClass = &SPU::R32CRegClass;
995 break;
Scott Michela313fb02008-10-30 01:51:48 +0000996 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000997 ArgRegClass = &SPU::R64CRegClass;
998 break;
Scott Michel2ef773a2009-01-06 03:36:14 +0000999 case MVT::i128:
1000 ArgRegClass = &SPU::GPRCRegClass;
1001 break;
Scott Michela313fb02008-10-30 01:51:48 +00001002 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +00001003 ArgRegClass = &SPU::R32FPRegClass;
1004 break;
Scott Michela313fb02008-10-30 01:51:48 +00001005 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +00001006 ArgRegClass = &SPU::R64FPRegClass;
1007 break;
Scott Michela313fb02008-10-30 01:51:48 +00001008 case MVT::v2f64:
1009 case MVT::v4f32:
1010 case MVT::v2i64:
1011 case MVT::v4i32:
1012 case MVT::v8i16:
1013 case MVT::v16i8:
Scott Michel33d73eb2008-11-21 02:56:16 +00001014 ArgRegClass = &SPU::VECREGRegClass;
1015 break;
Scott Michela313fb02008-10-30 01:51:48 +00001016 }
1017
1018 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
1019 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Dale Johannesenea996922009-02-04 20:06:27 +00001020 ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT);
Scott Michela313fb02008-10-30 01:51:48 +00001021 ++ArgRegIdx;
1022 } else {
1023 // We need to load the argument to a virtual register if we determined
1024 // above that we ran out of physical registers of the appropriate type
1025 // or we're forced to do vararg
Chris Lattner60069452008-02-13 07:35:30 +00001026 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +00001027 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Dale Johannesenea996922009-02-04 20:06:27 +00001028 ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +00001029 ArgOffset += StackSlotSize;
1030 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001031
Scott Michel8efdca42007-12-04 22:23:35 +00001032 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +00001033 // Update the chain
1034 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001035 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001036
Scott Michela313fb02008-10-30 01:51:48 +00001037 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +00001038 if (isVarArg) {
Scott Michela313fb02008-10-30 01:51:48 +00001039 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
1040 // We will spill (79-3)+1 registers to the stack
1041 SmallVector<SDValue, 79-3+1> MemOps;
1042
1043 // Create the frame slot
1044
Scott Michel8efdca42007-12-04 22:23:35 +00001045 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-10-30 01:51:48 +00001046 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1047 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1048 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
Dale Johannesenea996922009-02-04 20:06:27 +00001049 SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0);
Scott Michela313fb02008-10-30 01:51:48 +00001050 Root = Store.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001051 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001052
1053 // Increment address by stack slot size for the next stored argument
1054 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001055 }
1056 if (!MemOps.empty())
Scott Michel34712c32009-03-16 18:47:25 +00001057 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Dale Johannesenea996922009-02-04 20:06:27 +00001058 &MemOps[0], MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001059 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001060
Scott Michel8efdca42007-12-04 22:23:35 +00001061 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001062
Scott Michel8efdca42007-12-04 22:23:35 +00001063 // Return the new list of results.
Dale Johannesenea996922009-02-04 20:06:27 +00001064 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
Duncan Sands42d7bb82008-12-01 11:41:29 +00001065 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001066}
1067
1068/// isLSAAddress - Return the immediate to use if the specified
1069/// value is representable as a LSA address.
Dan Gohman8181bd12008-07-27 21:46:04 +00001070static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001071 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001072 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001073
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001074 int Addr = C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001075 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1076 (Addr << 14 >> 14) != Addr)
1077 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel4ec722e2008-07-16 17:17:29 +00001078
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001079 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001080}
1081
Scott Michel70741542009-01-06 23:10:38 +00001082static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +00001083LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001084 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1085 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001086 SDValue Callee = TheCall->getCallee();
1087 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-12-04 22:23:35 +00001088 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1089 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1090 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Dale Johannesenea996922009-02-04 20:06:27 +00001091 DebugLoc dl = TheCall->getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00001092
1093 // Handy pointer type
Duncan Sands92c43912008-06-06 12:08:01 +00001094 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001095
Scott Michel8efdca42007-12-04 22:23:35 +00001096 // Accumulate how many bytes are to be pushed on the stack, including the
1097 // linkage area, and parameter passing area. According to the SPU ABI,
1098 // we minimally need space for [LR] and [SP]
1099 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel4ec722e2008-07-16 17:17:29 +00001100
Scott Michel8efdca42007-12-04 22:23:35 +00001101 // Set up a copy of the stack pointer for use loading and storing any
1102 // arguments that may not fit in the registers available for argument
1103 // passing.
Dan Gohman8181bd12008-07-27 21:46:04 +00001104 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001105
Scott Michel8efdca42007-12-04 22:23:35 +00001106 // Figure out which arguments are going to go in registers, and which in
1107 // memory.
1108 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1109 unsigned ArgRegIdx = 0;
1110
1111 // Keep track of registers passing arguments
Dan Gohman8181bd12008-07-27 21:46:04 +00001112 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001113 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001114 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001115
1116 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001117 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001118
Scott Michel8efdca42007-12-04 22:23:35 +00001119 // PtrOff will be used to store the current argument to the stack if a
1120 // register cannot be found for it.
Dan Gohman8181bd12008-07-27 21:46:04 +00001121 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Dale Johannesenea996922009-02-04 20:06:27 +00001122 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
Scott Michel8efdca42007-12-04 22:23:35 +00001123
Duncan Sands92c43912008-06-06 12:08:01 +00001124 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001125 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001126 case MVT::i8:
1127 case MVT::i16:
Scott Michel8efdca42007-12-04 22:23:35 +00001128 case MVT::i32:
1129 case MVT::i64:
1130 case MVT::i128:
1131 if (ArgRegIdx != NumArgRegs) {
1132 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1133 } else {
Dale Johannesenea996922009-02-04 20:06:27 +00001134 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001135 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001136 }
1137 break;
1138 case MVT::f32:
1139 case MVT::f64:
1140 if (ArgRegIdx != NumArgRegs) {
1141 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1142 } else {
Dale Johannesenea996922009-02-04 20:06:27 +00001143 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001144 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001145 }
1146 break;
Scott Michele2641a12008-12-04 21:01:44 +00001147 case MVT::v2i64:
1148 case MVT::v2f64:
Scott Michel8efdca42007-12-04 22:23:35 +00001149 case MVT::v4f32:
1150 case MVT::v4i32:
1151 case MVT::v8i16:
1152 case MVT::v16i8:
1153 if (ArgRegIdx != NumArgRegs) {
1154 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1155 } else {
Dale Johannesenea996922009-02-04 20:06:27 +00001156 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001157 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001158 }
1159 break;
1160 }
1161 }
1162
1163 // Update number of stack bytes actually used, insert a call sequence start
1164 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001165 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1166 true));
Scott Michel8efdca42007-12-04 22:23:35 +00001167
1168 if (!MemOpChains.empty()) {
1169 // Adjust the stack pointer for the stack arguments.
Dale Johannesenea996922009-02-04 20:06:27 +00001170 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Scott Michel8efdca42007-12-04 22:23:35 +00001171 &MemOpChains[0], MemOpChains.size());
1172 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001173
Scott Michel8efdca42007-12-04 22:23:35 +00001174 // Build a sequence of copy-to-reg nodes chained together with token chain
1175 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman8181bd12008-07-27 21:46:04 +00001176 SDValue InFlag;
Scott Michel8efdca42007-12-04 22:23:35 +00001177 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
Scott Michel34712c32009-03-16 18:47:25 +00001178 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
Dale Johannesenea996922009-02-04 20:06:27 +00001179 RegsToPass[i].second, InFlag);
Scott Michel8efdca42007-12-04 22:23:35 +00001180 InFlag = Chain.getValue(1);
1181 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001182
Dan Gohman8181bd12008-07-27 21:46:04 +00001183 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001184 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001185
Bill Wendlingfef06052008-09-16 21:48:12 +00001186 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1187 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1188 // node so that legalize doesn't hack it.
Scott Michel5974f432008-11-11 03:06:06 +00001189 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001190 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001191 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001192 SDValue Zero = DAG.getConstant(0, PtrVT);
1193 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001194
Scott Micheldbac4cf2008-01-11 02:53:15 +00001195 if (!ST->usingLargeMem()) {
1196 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1197 // style calls, otherwise, external symbols are BRASL calls. This assumes
1198 // that declared/defined symbols are in the same compilation unit and can
1199 // be reached through PC-relative jumps.
1200 //
1201 // NOTE:
1202 // This may be an unsafe assumption for JIT and really large compilation
1203 // units.
1204 if (GV->isDeclaration()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001205 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001206 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001207 Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001208 }
Scott Michel8efdca42007-12-04 22:23:35 +00001209 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001210 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1211 // address pairs:
Dale Johannesen175fdef2009-02-06 21:50:26 +00001212 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001213 }
Scott Michelae5cbf52008-12-29 03:23:36 +00001214 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1215 MVT CalleeVT = Callee.getValueType();
1216 SDValue Zero = DAG.getConstant(0, PtrVT);
1217 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1218 Callee.getValueType());
1219
1220 if (!ST->usingLargeMem()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001221 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero);
Scott Michelae5cbf52008-12-29 03:23:36 +00001222 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001223 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero);
Scott Michelae5cbf52008-12-29 03:23:36 +00001224 }
1225 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001226 // If this is an absolute destination address that appears to be a legal
1227 // local store address, use the munged value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001228 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001229 }
Scott Michel8efdca42007-12-04 22:23:35 +00001230
1231 Ops.push_back(Chain);
1232 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001233
Scott Michel8efdca42007-12-04 22:23:35 +00001234 // Add argument registers to the end of the list so that they are known live
1235 // into the call.
1236 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel4ec722e2008-07-16 17:17:29 +00001237 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001238 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001239
Gabor Greif1c80d112008-08-28 21:40:38 +00001240 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001241 Ops.push_back(InFlag);
Duncan Sands698842f2008-07-02 17:40:58 +00001242 // Returns a chain and a flag for retval copy to use.
Dale Johannesenea996922009-02-04 20:06:27 +00001243 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag),
Duncan Sands698842f2008-07-02 17:40:58 +00001244 &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001245 InFlag = Chain.getValue(1);
1246
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001247 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1248 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001249 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001250 InFlag = Chain.getValue(1);
1251
Dan Gohman8181bd12008-07-27 21:46:04 +00001252 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001253 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001254
Scott Michel8efdca42007-12-04 22:23:35 +00001255 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001256 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001257 default: assert(0 && "Unexpected ret value!");
1258 case MVT::Other: break;
1259 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001260 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel34712c32009-03-16 18:47:25 +00001261 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4,
Dale Johannesenea996922009-02-04 20:06:27 +00001262 MVT::i32, InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001263 ResultVals[0] = Chain.getValue(0);
Dale Johannesenea996922009-02-04 20:06:27 +00001264 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Scott Michel8efdca42007-12-04 22:23:35 +00001265 Chain.getValue(2)).getValue(1);
1266 ResultVals[1] = Chain.getValue(0);
1267 NumResults = 2;
Scott Michel8efdca42007-12-04 22:23:35 +00001268 } else {
Scott Michel34712c32009-03-16 18:47:25 +00001269 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Dale Johannesenea996922009-02-04 20:06:27 +00001270 InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001271 ResultVals[0] = Chain.getValue(0);
1272 NumResults = 1;
1273 }
Scott Michel8efdca42007-12-04 22:23:35 +00001274 break;
1275 case MVT::i64:
Scott Michel34712c32009-03-16 18:47:25 +00001276 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64,
Dale Johannesenea996922009-02-04 20:06:27 +00001277 InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001278 ResultVals[0] = Chain.getValue(0);
1279 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001280 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001281 case MVT::i128:
Scott Michel34712c32009-03-16 18:47:25 +00001282 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128,
Dale Johannesenea996922009-02-04 20:06:27 +00001283 InFlag).getValue(1);
Scott Michel2ef773a2009-01-06 03:36:14 +00001284 ResultVals[0] = Chain.getValue(0);
1285 NumResults = 1;
1286 break;
Scott Michel8efdca42007-12-04 22:23:35 +00001287 case MVT::f32:
1288 case MVT::f64:
Dale Johannesenea996922009-02-04 20:06:27 +00001289 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001290 InFlag).getValue(1);
1291 ResultVals[0] = Chain.getValue(0);
1292 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001293 break;
1294 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001295 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001296 case MVT::v4f32:
1297 case MVT::v4i32:
1298 case MVT::v8i16:
1299 case MVT::v16i8:
Dale Johannesenea996922009-02-04 20:06:27 +00001300 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001301 InFlag).getValue(1);
1302 ResultVals[0] = Chain.getValue(0);
1303 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001304 break;
1305 }
Duncan Sands698842f2008-07-02 17:40:58 +00001306
Scott Michel8efdca42007-12-04 22:23:35 +00001307 // If the function returns void, just return the chain.
1308 if (NumResults == 0)
1309 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001310
Scott Michel8efdca42007-12-04 22:23:35 +00001311 // Otherwise, merge everything together with a MERGE_VALUES node.
1312 ResultVals[NumResults++] = Chain;
Dale Johannesenea996922009-02-04 20:06:27 +00001313 SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl);
Gabor Greif46bf5472008-08-26 22:36:50 +00001314 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001315}
1316
Dan Gohman8181bd12008-07-27 21:46:04 +00001317static SDValue
1318LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-12-04 22:23:35 +00001319 SmallVector<CCValAssign, 16> RVLocs;
1320 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1321 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001322 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00001323 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greif1c80d112008-08-28 21:40:38 +00001324 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001325
Scott Michel8efdca42007-12-04 22:23:35 +00001326 // If this is the first return lowered for this function, add the regs to the
1327 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001328 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001329 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001330 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001331 }
1332
Dan Gohman8181bd12008-07-27 21:46:04 +00001333 SDValue Chain = Op.getOperand(0);
1334 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001335
Scott Michel8efdca42007-12-04 22:23:35 +00001336 // Copy the result values into the output registers.
1337 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1338 CCValAssign &VA = RVLocs[i];
1339 assert(VA.isRegLoc() && "Can only return in registers!");
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001340 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
1341 Op.getOperand(i*2+1), Flag);
Scott Michel8efdca42007-12-04 22:23:35 +00001342 Flag = Chain.getValue(1);
1343 }
1344
Gabor Greif1c80d112008-08-28 21:40:38 +00001345 if (Flag.getNode())
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001346 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
Scott Michel8efdca42007-12-04 22:23:35 +00001347 else
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001348 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain);
Scott Michel8efdca42007-12-04 22:23:35 +00001349}
1350
1351
1352//===----------------------------------------------------------------------===//
1353// Vector related lowering:
1354//===----------------------------------------------------------------------===//
1355
1356static ConstantSDNode *
1357getVecImm(SDNode *N) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001358 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001359
Scott Michel8efdca42007-12-04 22:23:35 +00001360 // Check to see if this buildvec has a single non-undef value in its elements.
1361 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1362 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greif1c80d112008-08-28 21:40:38 +00001363 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001364 OpVal = N->getOperand(i);
1365 else if (OpVal != N->getOperand(i))
1366 return 0;
1367 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001368
Gabor Greif1c80d112008-08-28 21:40:38 +00001369 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001370 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001371 return CN;
1372 }
1373 }
1374
Scott Michel0d5eae02009-03-17 01:15:45 +00001375 return 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001376}
1377
1378/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1379/// and the value fits into an unsigned 18-bit constant, and if so, return the
1380/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001381SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001382 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001383 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001384 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001385 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001386 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001387 uint32_t upper = uint32_t(UValue >> 32);
1388 uint32_t lower = uint32_t(UValue);
1389 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001390 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001391 Value = Value >> 32;
1392 }
Scott Michel8efdca42007-12-04 22:23:35 +00001393 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001394 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001395 }
1396
Dan Gohman8181bd12008-07-27 21:46:04 +00001397 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001398}
1399
1400/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1401/// and the value fits into a signed 16-bit constant, and if so, return the
1402/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001403SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001404 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001405 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001406 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001407 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001408 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001409 uint32_t upper = uint32_t(UValue >> 32);
1410 uint32_t lower = uint32_t(UValue);
1411 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001412 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001413 Value = Value >> 32;
1414 }
Scott Michel6baba072008-03-05 23:02:02 +00001415 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001416 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001417 }
1418 }
1419
Dan Gohman8181bd12008-07-27 21:46:04 +00001420 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001421}
1422
1423/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1424/// and the value fits into a signed 10-bit constant, and if so, return the
1425/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001426SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001427 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001428 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001429 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001430 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001431 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001432 uint32_t upper = uint32_t(UValue >> 32);
1433 uint32_t lower = uint32_t(UValue);
1434 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001435 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001436 Value = Value >> 32;
1437 }
Scott Michel6baba072008-03-05 23:02:02 +00001438 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001439 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001440 }
1441
Dan Gohman8181bd12008-07-27 21:46:04 +00001442 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001443}
1444
1445/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1446/// and the value fits into a signed 8-bit constant, and if so, return the
1447/// constant.
1448///
1449/// @note: The incoming vector is v16i8 because that's the only way we can load
1450/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1451/// same value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001452SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001453 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001454 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001455 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001456 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001457 && Value <= 0xffff /* truncated from uint64_t */
1458 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001459 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001460 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001461 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001462 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001463 }
1464
Dan Gohman8181bd12008-07-27 21:46:04 +00001465 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001466}
1467
1468/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1469/// and the value fits into a signed 16-bit constant, and if so, return the
1470/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001471SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001472 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001473 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001474 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001475 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001476 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1477 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001478 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001479 }
1480
Dan Gohman8181bd12008-07-27 21:46:04 +00001481 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001482}
1483
1484/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001485SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001486 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001487 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001488 }
1489
Dan Gohman8181bd12008-07-27 21:46:04 +00001490 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001491}
1492
1493/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001494SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001495 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001496 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001497 }
1498
Dan Gohman8181bd12008-07-27 21:46:04 +00001499 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001500}
1501
Scott Michel8c67fa42009-01-21 04:58:48 +00001502//! Lower a BUILD_VECTOR instruction creatively:
1503SDValue
pingbak2f387e82009-01-26 03:31:40 +00001504LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001505 MVT VT = Op.getValueType();
Scott Michel0d5eae02009-03-17 01:15:45 +00001506 MVT EltVT = VT.getVectorElementType();
Dale Johannesen913ba762009-02-06 01:31:28 +00001507 DebugLoc dl = Op.getDebugLoc();
Scott Michel0d5eae02009-03-17 01:15:45 +00001508 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(Op.getNode());
1509 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerBUILD_VECTOR");
1510 unsigned minSplatBits = EltVT.getSizeInBits();
1511
1512 if (minSplatBits < 16)
1513 minSplatBits = 16;
1514
1515 APInt APSplatBits, APSplatUndef;
1516 unsigned SplatBitSize;
1517 bool HasAnyUndefs;
1518
1519 if (!BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
1520 HasAnyUndefs, minSplatBits)
1521 || minSplatBits < SplatBitSize)
1522 return SDValue(); // Wasn't a constant vector or splat exceeded min
1523
1524 uint64_t SplatBits = APSplatBits.getZExtValue();
Scott Michel4ec722e2008-07-16 17:17:29 +00001525
Duncan Sands92c43912008-06-06 12:08:01 +00001526 switch (VT.getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001527 default:
Scott Michel8c67fa42009-01-21 04:58:48 +00001528 cerr << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
1529 << VT.getMVTString()
1530 << "\n";
1531 abort();
1532 /*NOTREACHED*/
Scott Michel8efdca42007-12-04 22:23:35 +00001533 case MVT::v4f32: {
pingbak2f387e82009-01-26 03:31:40 +00001534 uint32_t Value32 = uint32_t(SplatBits);
Chris Lattner8579bab2009-03-26 05:29:34 +00001535 assert(SplatBitSize == 32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001536 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001537 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001538 SDValue T = DAG.getConstant(Value32, MVT::i32);
Dale Johannesen913ba762009-02-06 01:31:28 +00001539 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4f32,
Chris Lattner8579bab2009-03-26 05:29:34 +00001540 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T));
Scott Michel8efdca42007-12-04 22:23:35 +00001541 break;
1542 }
1543 case MVT::v2f64: {
pingbak2f387e82009-01-26 03:31:40 +00001544 uint64_t f64val = uint64_t(SplatBits);
Chris Lattner8579bab2009-03-26 05:29:34 +00001545 assert(SplatBitSize == 64
Scott Michelc630c412008-11-24 17:11:17 +00001546 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001547 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001548 SDValue T = DAG.getConstant(f64val, MVT::i64);
Dale Johannesen913ba762009-02-06 01:31:28 +00001549 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64,
Evan Cheng907a2d22009-02-25 22:49:59 +00001550 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001551 break;
1552 }
1553 case MVT::v16i8: {
1554 // 8-bit constants have to be expanded to 16-bits
Scott Michel0d5eae02009-03-17 01:15:45 +00001555 unsigned short Value16 = SplatBits /* | (SplatBits << 8) */;
1556 SmallVector<SDValue, 8> Ops;
1557
1558 Ops.assign(8, DAG.getConstant(Value16, MVT::i16));
Dale Johannesen913ba762009-02-06 01:31:28 +00001559 return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
Scott Michel0d5eae02009-03-17 01:15:45 +00001560 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001561 }
1562 case MVT::v8i16: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001563 unsigned short Value16 = SplatBits;
1564 SDValue T = DAG.getConstant(Value16, EltVT);
1565 SmallVector<SDValue, 8> Ops;
1566
1567 Ops.assign(8, T);
1568 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001569 }
1570 case MVT::v4i32: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001571 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Cheng907a2d22009-02-25 22:49:59 +00001572 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
Scott Michel8efdca42007-12-04 22:23:35 +00001573 }
Scott Michel70741542009-01-06 23:10:38 +00001574 case MVT::v2i32: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001575 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Cheng907a2d22009-02-25 22:49:59 +00001576 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T);
Scott Michel70741542009-01-06 23:10:38 +00001577 }
Scott Michel8efdca42007-12-04 22:23:35 +00001578 case MVT::v2i64: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001579 return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
Scott Michel8efdca42007-12-04 22:23:35 +00001580 }
1581 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001582
Dan Gohman8181bd12008-07-27 21:46:04 +00001583 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001584}
1585
Scott Michel0d5eae02009-03-17 01:15:45 +00001586/*!
1587 */
pingbak2f387e82009-01-26 03:31:40 +00001588SDValue
Scott Michel0d5eae02009-03-17 01:15:45 +00001589SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal,
1590 DebugLoc dl) {
pingbak2f387e82009-01-26 03:31:40 +00001591 uint32_t upper = uint32_t(SplatVal >> 32);
1592 uint32_t lower = uint32_t(SplatVal);
1593
1594 if (upper == lower) {
1595 // Magic constant that can be matched by IL, ILA, et. al.
1596 SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
Dale Johannesen913ba762009-02-06 01:31:28 +00001597 return DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001598 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1599 Val, Val, Val, Val));
pingbak2f387e82009-01-26 03:31:40 +00001600 } else {
pingbak2f387e82009-01-26 03:31:40 +00001601 bool upper_special, lower_special;
1602
1603 // NOTE: This code creates common-case shuffle masks that can be easily
1604 // detected as common expressions. It is not attempting to create highly
1605 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1606
1607 // Detect if the upper or lower half is a special shuffle mask pattern:
1608 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1609 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1610
Scott Michel0d5eae02009-03-17 01:15:45 +00001611 // Both upper and lower are special, lower to a constant pool load:
1612 if (lower_special && upper_special) {
1613 SDValue SplatValCN = DAG.getConstant(SplatVal, MVT::i64);
1614 return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
1615 SplatValCN, SplatValCN);
1616 }
1617
1618 SDValue LO32;
1619 SDValue HI32;
1620 SmallVector<SDValue, 16> ShufBytes;
1621 SDValue Result;
1622
pingbak2f387e82009-01-26 03:31:40 +00001623 // Create lower vector if not a special pattern
1624 if (!lower_special) {
1625 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Dale Johannesen913ba762009-02-06 01:31:28 +00001626 LO32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001627 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1628 LO32C, LO32C, LO32C, LO32C));
pingbak2f387e82009-01-26 03:31:40 +00001629 }
1630
1631 // Create upper vector if not a special pattern
1632 if (!upper_special) {
1633 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Dale Johannesen913ba762009-02-06 01:31:28 +00001634 HI32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001635 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1636 HI32C, HI32C, HI32C, HI32C));
pingbak2f387e82009-01-26 03:31:40 +00001637 }
1638
1639 // If either upper or lower are special, then the two input operands are
1640 // the same (basically, one of them is a "don't care")
1641 if (lower_special)
1642 LO32 = HI32;
1643 if (upper_special)
1644 HI32 = LO32;
pingbak2f387e82009-01-26 03:31:40 +00001645
1646 for (int i = 0; i < 4; ++i) {
1647 uint64_t val = 0;
1648 for (int j = 0; j < 4; ++j) {
1649 SDValue V;
1650 bool process_upper, process_lower;
1651 val <<= 8;
1652 process_upper = (upper_special && (i & 1) == 0);
1653 process_lower = (lower_special && (i & 1) == 1);
1654
1655 if (process_upper || process_lower) {
1656 if ((process_upper && upper == 0)
1657 || (process_lower && lower == 0))
1658 val |= 0x80;
1659 else if ((process_upper && upper == 0xffffffff)
1660 || (process_lower && lower == 0xffffffff))
1661 val |= 0xc0;
1662 else if ((process_upper && upper == 0x80000000)
1663 || (process_lower && lower == 0x80000000))
1664 val |= (j == 0 ? 0xe0 : 0x80);
1665 } else
1666 val |= i * 4 + j + ((i & 1) * 16);
1667 }
1668
1669 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
1670 }
1671
Dale Johannesen913ba762009-02-06 01:31:28 +00001672 return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32,
Evan Cheng907a2d22009-02-25 22:49:59 +00001673 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1674 &ShufBytes[0], ShufBytes.size()));
pingbak2f387e82009-01-26 03:31:40 +00001675 }
1676}
1677
Scott Michel8efdca42007-12-04 22:23:35 +00001678/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1679/// which the Cell can operate. The code inspects V3 to ascertain whether the
1680/// permutation vector, V3, is monotonically increasing with one "exception"
1681/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel56a125e2008-11-22 23:50:42 +00001682/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-12-04 22:23:35 +00001683/// In either case, the net result is going to eventually invoke SHUFB to
1684/// permute/shuffle the bytes from V1 and V2.
1685/// \note
Scott Michel56a125e2008-11-22 23:50:42 +00001686/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-12-04 22:23:35 +00001687/// control word for byte/halfword/word insertion. This takes care of a single
1688/// element move from V2 into V1.
1689/// \note
1690/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman8181bd12008-07-27 21:46:04 +00001691static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
Nate Begeman543d2142009-04-27 18:41:29 +00001692 const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +00001693 SDValue V1 = Op.getOperand(0);
1694 SDValue V2 = Op.getOperand(1);
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001695 DebugLoc dl = Op.getDebugLoc();
Scott Michel4ec722e2008-07-16 17:17:29 +00001696
Scott Michel8efdca42007-12-04 22:23:35 +00001697 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001698
Scott Michel8efdca42007-12-04 22:23:35 +00001699 // If we have a single element being moved from V1 to V2, this can be handled
1700 // using the C*[DX] compute mask instructions, but the vector elements have
1701 // to be monotonically increasing with one exception element.
Scott Michele2641a12008-12-04 21:01:44 +00001702 MVT VecVT = V1.getValueType();
1703 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001704 unsigned EltsFromV2 = 0;
1705 unsigned V2Elt = 0;
1706 unsigned V2EltIdx0 = 0;
1707 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001708 unsigned MaxElts = VecVT.getVectorNumElements();
1709 unsigned PrevElt = 0;
1710 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001711 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001712 bool rotate = true;
1713
1714 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001715 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001716 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001717 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001718 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001719 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001720 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1721 V2EltIdx0 = 2;
1722 } else
Scott Michel8efdca42007-12-04 22:23:35 +00001723 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1724
Nate Begeman543d2142009-04-27 18:41:29 +00001725 for (unsigned i = 0; i != MaxElts; ++i) {
1726 if (SVN->getMaskElt(i) < 0)
1727 continue;
1728
1729 unsigned SrcElt = SVN->getMaskElt(i);
Scott Michel8efdca42007-12-04 22:23:35 +00001730
Nate Begeman543d2142009-04-27 18:41:29 +00001731 if (monotonic) {
1732 if (SrcElt >= V2EltIdx0) {
1733 if (1 >= (++EltsFromV2)) {
1734 V2Elt = (V2EltIdx0 - SrcElt) << 2;
Scott Michele2641a12008-12-04 21:01:44 +00001735 }
Nate Begeman543d2142009-04-27 18:41:29 +00001736 } else if (CurrElt != SrcElt) {
1737 monotonic = false;
Scott Michele2641a12008-12-04 21:01:44 +00001738 }
1739
Nate Begeman543d2142009-04-27 18:41:29 +00001740 ++CurrElt;
1741 }
1742
1743 if (rotate) {
1744 if (PrevElt > 0 && SrcElt < MaxElts) {
1745 if ((PrevElt == SrcElt - 1)
1746 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
Scott Michele2641a12008-12-04 21:01:44 +00001747 PrevElt = SrcElt;
Nate Begeman543d2142009-04-27 18:41:29 +00001748 if (SrcElt == 0)
1749 V0Elt = i;
Scott Michele2641a12008-12-04 21:01:44 +00001750 } else {
Scott Michele2641a12008-12-04 21:01:44 +00001751 rotate = false;
1752 }
Nate Begeman543d2142009-04-27 18:41:29 +00001753 } else if (PrevElt == 0) {
1754 // First time through, need to keep track of previous element
1755 PrevElt = SrcElt;
1756 } else {
1757 // This isn't a rotation, takes elements from vector 2
1758 rotate = false;
Scott Michele2641a12008-12-04 21:01:44 +00001759 }
Scott Michel8efdca42007-12-04 22:23:35 +00001760 }
Scott Michel8efdca42007-12-04 22:23:35 +00001761 }
1762
1763 if (EltsFromV2 == 1 && monotonic) {
1764 // Compute mask and shuffle
1765 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001766 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1767 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001768 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001769 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001770 SDValue InitTempReg =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001771 DAG.getCopyToReg(DAG.getEntryNode(), dl, VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001772 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001773 SDValue ShufMaskOp =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001774 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001775 DAG.getTargetConstant(V2Elt, MVT::i32),
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001776 DAG.getCopyFromReg(InitTempReg, dl, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001777 // Use shuffle mask in SHUFB synthetic instruction:
Scott Michel34712c32009-03-16 18:47:25 +00001778 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1,
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001779 ShufMaskOp);
Scott Michele2641a12008-12-04 21:01:44 +00001780 } else if (rotate) {
1781 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001782
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001783 return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(),
Scott Michele2641a12008-12-04 21:01:44 +00001784 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001785 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001786 // Convert the SHUFFLE_VECTOR mask's input element units to the
1787 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001788 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001789
Dan Gohman8181bd12008-07-27 21:46:04 +00001790 SmallVector<SDValue, 16> ResultMask;
Nate Begeman543d2142009-04-27 18:41:29 +00001791 for (unsigned i = 0, e = MaxElts; i != e; ++i) {
1792 unsigned SrcElt = SVN->getMaskElt(i) < 0 ? 0 : SVN->getMaskElt(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001793
Nate Begeman543d2142009-04-27 18:41:29 +00001794 for (unsigned j = 0; j < BytesPerElement; ++j)
1795 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001796 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001797
Evan Cheng907a2d22009-02-25 22:49:59 +00001798 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
1799 &ResultMask[0], ResultMask.size());
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001800 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
Scott Michel8efdca42007-12-04 22:23:35 +00001801 }
1802}
1803
Dan Gohman8181bd12008-07-27 21:46:04 +00001804static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1805 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Dale Johannesen913ba762009-02-06 01:31:28 +00001806 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00001807
Gabor Greif1c80d112008-08-28 21:40:38 +00001808 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-12-04 22:23:35 +00001809 // For a constant, build the appropriate constant vector, which will
1810 // eventually simplify to a vector register load.
1811
Gabor Greif1c80d112008-08-28 21:40:38 +00001812 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001813 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001814 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001815 size_t n_copies;
1816
1817 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001818 switch (Op.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001819 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001820 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001821 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1822 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1823 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1824 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1825 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1826 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1827 }
1828
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001829 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-12-04 22:23:35 +00001830 for (size_t j = 0; j < n_copies; ++j)
1831 ConstVecValues.push_back(CValue);
1832
Evan Cheng907a2d22009-02-25 22:49:59 +00001833 return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(),
1834 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001835 } else {
1836 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001837 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001838 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1839 case MVT::i8:
1840 case MVT::i16:
1841 case MVT::i32:
1842 case MVT::i64:
1843 case MVT::f32:
1844 case MVT::f64:
Dale Johannesen913ba762009-02-06 01:31:28 +00001845 return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001846 }
1847 }
1848
Dan Gohman8181bd12008-07-27 21:46:04 +00001849 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001850}
1851
Dan Gohman8181bd12008-07-27 21:46:04 +00001852static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001853 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001854 SDValue N = Op.getOperand(0);
1855 SDValue Elt = Op.getOperand(1);
Dale Johannesen913ba762009-02-06 01:31:28 +00001856 DebugLoc dl = Op.getDebugLoc();
Scott Michel56a125e2008-11-22 23:50:42 +00001857 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001858
Scott Michel56a125e2008-11-22 23:50:42 +00001859 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1860 // Constant argument:
1861 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001862
Scott Michel56a125e2008-11-22 23:50:42 +00001863 // sanity checks:
1864 if (VT == MVT::i8 && EltNo >= 16)
1865 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1866 else if (VT == MVT::i16 && EltNo >= 8)
1867 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1868 else if (VT == MVT::i32 && EltNo >= 4)
1869 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1870 else if (VT == MVT::i64 && EltNo >= 2)
1871 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel8efdca42007-12-04 22:23:35 +00001872
Scott Michel56a125e2008-11-22 23:50:42 +00001873 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1874 // i32 and i64: Element 0 is the preferred slot
Dale Johannesen913ba762009-02-06 01:31:28 +00001875 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001876 }
Scott Michel8efdca42007-12-04 22:23:35 +00001877
Scott Michel56a125e2008-11-22 23:50:42 +00001878 // Need to generate shuffle mask and extract:
1879 int prefslot_begin = -1, prefslot_end = -1;
1880 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1881
1882 switch (VT.getSimpleVT()) {
1883 default:
1884 assert(false && "Invalid value type!");
1885 case MVT::i8: {
1886 prefslot_begin = prefslot_end = 3;
1887 break;
1888 }
1889 case MVT::i16: {
1890 prefslot_begin = 2; prefslot_end = 3;
1891 break;
1892 }
1893 case MVT::i32:
1894 case MVT::f32: {
1895 prefslot_begin = 0; prefslot_end = 3;
1896 break;
1897 }
1898 case MVT::i64:
1899 case MVT::f64: {
1900 prefslot_begin = 0; prefslot_end = 7;
1901 break;
1902 }
1903 }
1904
1905 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1906 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1907
1908 unsigned int ShufBytes[16];
1909 for (int i = 0; i < 16; ++i) {
1910 // zero fill uppper part of preferred slot, don't care about the
1911 // other slots:
1912 unsigned int mask_val;
1913 if (i <= prefslot_end) {
1914 mask_val =
1915 ((i < prefslot_begin)
1916 ? 0x80
1917 : elt_byte + (i - prefslot_begin));
1918
1919 ShufBytes[i] = mask_val;
1920 } else
1921 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1922 }
1923
1924 SDValue ShufMask[4];
1925 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michele2641a12008-12-04 21:01:44 +00001926 unsigned bidx = i * 4;
Scott Michel56a125e2008-11-22 23:50:42 +00001927 unsigned int bits = ((ShufBytes[bidx] << 24) |
1928 (ShufBytes[bidx+1] << 16) |
1929 (ShufBytes[bidx+2] << 8) |
1930 ShufBytes[bidx+3]);
1931 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1932 }
1933
Scott Michel0d5eae02009-03-17 01:15:45 +00001934 SDValue ShufMaskVec =
1935 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1936 &ShufMask[0], sizeof(ShufMask)/sizeof(ShufMask[0]));
Scott Michel56a125e2008-11-22 23:50:42 +00001937
Dale Johannesen913ba762009-02-06 01:31:28 +00001938 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
1939 DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(),
Scott Michel56a125e2008-11-22 23:50:42 +00001940 N, N, ShufMaskVec));
1941 } else {
1942 // Variable index: Rotate the requested element into slot 0, then replicate
1943 // slot 0 across the vector
1944 MVT VecVT = N.getValueType();
1945 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
1946 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
1947 abort();
1948 }
1949
1950 // Make life easier by making sure the index is zero-extended to i32
1951 if (Elt.getValueType() != MVT::i32)
Dale Johannesen913ba762009-02-06 01:31:28 +00001952 Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt);
Scott Michel56a125e2008-11-22 23:50:42 +00001953
1954 // Scale the index to a bit/byte shift quantity
1955 APInt scaleFactor =
Scott Michelc630c412008-11-24 17:11:17 +00001956 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1957 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00001958 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00001959
Scott Michelc630c412008-11-24 17:11:17 +00001960 if (scaleShift > 0) {
1961 // Scale the shift factor:
Dale Johannesen913ba762009-02-06 01:31:28 +00001962 Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00001963 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00001964 }
1965
Dale Johannesen913ba762009-02-06 01:31:28 +00001966 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, dl, VecVT, N, Elt);
Scott Michelc630c412008-11-24 17:11:17 +00001967
1968 // Replicate the bytes starting at byte 0 across the entire vector (for
1969 // consistency with the notion of a unified register set)
Scott Michel56a125e2008-11-22 23:50:42 +00001970 SDValue replicate;
1971
1972 switch (VT.getSimpleVT()) {
1973 default:
1974 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
1975 abort();
1976 /*NOTREACHED*/
1977 case MVT::i8: {
Scott Michelc630c412008-11-24 17:11:17 +00001978 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00001979 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1980 factor, factor, factor, factor);
Scott Michel56a125e2008-11-22 23:50:42 +00001981 break;
1982 }
1983 case MVT::i16: {
Scott Michelc630c412008-11-24 17:11:17 +00001984 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00001985 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1986 factor, factor, factor, factor);
Scott Michel56a125e2008-11-22 23:50:42 +00001987 break;
1988 }
1989 case MVT::i32:
1990 case MVT::f32: {
1991 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00001992 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1993 factor, factor, factor, factor);
Scott Michel56a125e2008-11-22 23:50:42 +00001994 break;
1995 }
1996 case MVT::i64:
1997 case MVT::f64: {
1998 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
1999 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00002000 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
Evan Cheng907a2d22009-02-25 22:49:59 +00002001 loFactor, hiFactor, loFactor, hiFactor);
Scott Michel56a125e2008-11-22 23:50:42 +00002002 break;
2003 }
2004 }
2005
Dale Johannesen913ba762009-02-06 01:31:28 +00002006 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
2007 DAG.getNode(SPUISD::SHUFB, dl, VecVT,
Scott Michel0718cd82008-12-01 17:56:02 +00002008 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002009 }
2010
Scott Michel56a125e2008-11-22 23:50:42 +00002011 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002012}
2013
Dan Gohman8181bd12008-07-27 21:46:04 +00002014static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2015 SDValue VecOp = Op.getOperand(0);
2016 SDValue ValOp = Op.getOperand(1);
2017 SDValue IdxOp = Op.getOperand(2);
Dale Johannesen913ba762009-02-06 01:31:28 +00002018 DebugLoc dl = Op.getDebugLoc();
Duncan Sands92c43912008-06-06 12:08:01 +00002019 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002020
2021 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2022 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2023
Duncan Sands92c43912008-06-06 12:08:01 +00002024 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-12-01 17:56:02 +00002025 // Use $sp ($1) because it's always 16-byte aligned and it's available:
Dale Johannesen913ba762009-02-06 01:31:28 +00002026 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel0718cd82008-12-01 17:56:02 +00002027 DAG.getRegister(SPU::R1, PtrVT),
2028 DAG.getConstant(CN->getSExtValue(), PtrVT));
Dale Johannesen913ba762009-02-06 01:31:28 +00002029 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, VT, Pointer);
Scott Michel8efdca42007-12-04 22:23:35 +00002030
Dan Gohman8181bd12008-07-27 21:46:04 +00002031 SDValue result =
Dale Johannesen913ba762009-02-06 01:31:28 +00002032 DAG.getNode(SPUISD::SHUFB, dl, VT,
2033 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002034 VecOp,
Dale Johannesen913ba762009-02-06 01:31:28 +00002035 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002036
2037 return result;
2038}
2039
Scott Michel06eabde2008-12-27 04:51:36 +00002040static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2041 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002042{
Dan Gohman8181bd12008-07-27 21:46:04 +00002043 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Dale Johannesen913ba762009-02-06 01:31:28 +00002044 DebugLoc dl = Op.getDebugLoc();
Scott Michel06eabde2008-12-27 04:51:36 +00002045 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-12-04 22:23:35 +00002046
2047 assert(Op.getValueType() == MVT::i8);
2048 switch (Opc) {
2049 default:
2050 assert(0 && "Unhandled i8 math operator");
2051 /*NOTREACHED*/
2052 break;
Scott Michel4d07fb72008-12-30 23:28:25 +00002053 case ISD::ADD: {
2054 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2055 // the result:
2056 SDValue N1 = Op.getOperand(1);
Dale Johannesen913ba762009-02-06 01:31:28 +00002057 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2058 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2059 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2060 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel4d07fb72008-12-30 23:28:25 +00002061
2062 }
2063
Scott Michel8efdca42007-12-04 22:23:35 +00002064 case ISD::SUB: {
2065 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2066 // the result:
Dan Gohman8181bd12008-07-27 21:46:04 +00002067 SDValue N1 = Op.getOperand(1);
Dale Johannesen913ba762009-02-06 01:31:28 +00002068 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2069 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2070 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2071 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel4ec722e2008-07-16 17:17:29 +00002072 }
Scott Michel8efdca42007-12-04 22:23:35 +00002073 case ISD::ROTR:
2074 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002075 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-03-17 01:15:45 +00002076 MVT N1VT = N1.getValueType();
2077
2078 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2079 if (!N1VT.bitsEq(ShiftVT)) {
2080 unsigned N1Opc = N1.getValueType().bitsLT(ShiftVT)
2081 ? ISD::ZERO_EXTEND
2082 : ISD::TRUNCATE;
2083 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2084 }
2085
2086 // Replicate lower 8-bits into upper 8:
Dan Gohman8181bd12008-07-27 21:46:04 +00002087 SDValue ExpandArg =
Dale Johannesen913ba762009-02-06 01:31:28 +00002088 DAG.getNode(ISD::OR, dl, MVT::i16, N0,
2089 DAG.getNode(ISD::SHL, dl, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002090 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel0d5eae02009-03-17 01:15:45 +00002091
2092 // Truncate back down to i8
Dale Johannesen913ba762009-02-06 01:31:28 +00002093 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2094 DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002095 }
2096 case ISD::SRL:
2097 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002098 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-03-17 01:15:45 +00002099 MVT N1VT = N1.getValueType();
2100
2101 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2102 if (!N1VT.bitsEq(ShiftVT)) {
2103 unsigned N1Opc = ISD::ZERO_EXTEND;
2104
2105 if (N1.getValueType().bitsGT(ShiftVT))
2106 N1Opc = ISD::TRUNCATE;
2107
2108 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2109 }
2110
Dale Johannesen913ba762009-02-06 01:31:28 +00002111 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2112 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002113 }
2114 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002115 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-03-17 01:15:45 +00002116 MVT N1VT = N1.getValueType();
2117
2118 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2119 if (!N1VT.bitsEq(ShiftVT)) {
2120 unsigned N1Opc = ISD::SIGN_EXTEND;
2121
2122 if (N1VT.bitsGT(ShiftVT))
2123 N1Opc = ISD::TRUNCATE;
2124 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2125 }
2126
Dale Johannesen913ba762009-02-06 01:31:28 +00002127 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2128 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002129 }
2130 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002131 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-03-17 01:15:45 +00002132
2133 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2134 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
Dale Johannesen913ba762009-02-06 01:31:28 +00002135 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2136 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002137 break;
2138 }
2139 }
2140
Dan Gohman8181bd12008-07-27 21:46:04 +00002141 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002142}
2143
2144//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002145static SDValue
2146LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2147 SDValue ConstVec;
2148 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002149 MVT VT = Op.getValueType();
Dale Johannesen913ba762009-02-06 01:31:28 +00002150 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002151
2152 ConstVec = Op.getOperand(0);
2153 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002154 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2155 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002156 ConstVec = ConstVec.getOperand(0);
2157 } else {
2158 ConstVec = Op.getOperand(1);
2159 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002160 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002161 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002162 }
2163 }
2164 }
2165
Gabor Greif1c80d112008-08-28 21:40:38 +00002166 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel0d5eae02009-03-17 01:15:45 +00002167 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode());
2168 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed");
Scott Michel8efdca42007-12-04 22:23:35 +00002169
Scott Michel0d5eae02009-03-17 01:15:45 +00002170 APInt APSplatBits, APSplatUndef;
2171 unsigned SplatBitSize;
2172 bool HasAnyUndefs;
2173 unsigned minSplatBits = VT.getVectorElementType().getSizeInBits();
2174
2175 if (BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
2176 HasAnyUndefs, minSplatBits)
2177 && minSplatBits <= SplatBitSize) {
2178 uint64_t SplatBits = APSplatBits.getZExtValue();
Dan Gohman8181bd12008-07-27 21:46:04 +00002179 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002180
Scott Michel0d5eae02009-03-17 01:15:45 +00002181 SmallVector<SDValue, 16> tcVec;
2182 tcVec.assign(16, tc);
Dale Johannesen913ba762009-02-06 01:31:28 +00002183 return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg,
Scott Michel0d5eae02009-03-17 01:15:45 +00002184 DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00002185 }
2186 }
Scott Michelc899a122009-01-26 22:33:37 +00002187
Nate Begeman7569e762008-07-29 19:07:27 +00002188 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2189 // lowered. Return the operation, rather than a null SDValue.
2190 return Op;
Scott Michel8efdca42007-12-04 22:23:35 +00002191}
2192
Scott Michel8efdca42007-12-04 22:23:35 +00002193//! Custom lowering for CTPOP (count population)
2194/*!
2195 Custom lowering code that counts the number ones in the input
2196 operand. SPU has such an instruction, but it counts the number of
2197 ones per byte, which then have to be accumulated.
2198*/
Dan Gohman8181bd12008-07-27 21:46:04 +00002199static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002200 MVT VT = Op.getValueType();
2201 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002202 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002203
Duncan Sands92c43912008-06-06 12:08:01 +00002204 switch (VT.getSimpleVT()) {
2205 default:
2206 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002207 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002208 SDValue N = Op.getOperand(0);
2209 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002210
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002211 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2212 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002213
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002214 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0);
Scott Michel8efdca42007-12-04 22:23:35 +00002215 }
2216
2217 case MVT::i16: {
2218 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002219 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002220
Chris Lattner1b989192007-12-31 04:13:23 +00002221 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002222
Dan Gohman8181bd12008-07-27 21:46:04 +00002223 SDValue N = Op.getOperand(0);
2224 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2225 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sands7aef60d2008-10-30 19:24:28 +00002226 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002227
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002228 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2229 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002230
2231 // CNTB_result becomes the chain to which all of the virtual registers
2232 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002233 SDValue CNTB_result =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002234 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002235
Dan Gohman8181bd12008-07-27 21:46:04 +00002236 SDValue CNTB_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002237 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel8efdca42007-12-04 22:23:35 +00002238
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002239 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002240
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002241 return DAG.getNode(ISD::AND, dl, MVT::i16,
2242 DAG.getNode(ISD::ADD, dl, MVT::i16,
2243 DAG.getNode(ISD::SRL, dl, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002244 Tmp1, Shift1),
2245 Tmp1),
2246 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002247 }
2248
2249 case MVT::i32: {
2250 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002251 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002252
Chris Lattner1b989192007-12-31 04:13:23 +00002253 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2254 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002255
Dan Gohman8181bd12008-07-27 21:46:04 +00002256 SDValue N = Op.getOperand(0);
2257 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2258 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2259 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2260 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002261
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002262 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2263 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002264
2265 // CNTB_result becomes the chain to which all of the virtual registers
2266 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002267 SDValue CNTB_result =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002268 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002269
Dan Gohman8181bd12008-07-27 21:46:04 +00002270 SDValue CNTB_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002271 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel8efdca42007-12-04 22:23:35 +00002272
Dan Gohman8181bd12008-07-27 21:46:04 +00002273 SDValue Comp1 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002274 DAG.getNode(ISD::SRL, dl, MVT::i32,
Scott Michel34712c32009-03-16 18:47:25 +00002275 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32),
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002276 Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002277
Dan Gohman8181bd12008-07-27 21:46:04 +00002278 SDValue Sum1 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002279 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp1,
2280 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002281
Dan Gohman8181bd12008-07-27 21:46:04 +00002282 SDValue Sum1_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002283 DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1);
Scott Michel8efdca42007-12-04 22:23:35 +00002284
Dan Gohman8181bd12008-07-27 21:46:04 +00002285 SDValue Comp2 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002286 DAG.getNode(ISD::SRL, dl, MVT::i32,
2287 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002288 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002289 SDValue Sum2 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002290 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp2,
2291 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002292
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002293 return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002294 }
2295
2296 case MVT::i64:
2297 break;
2298 }
2299
Dan Gohman8181bd12008-07-27 21:46:04 +00002300 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002301}
2302
pingbak2f387e82009-01-26 03:31:40 +00002303//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Michel8c67fa42009-01-21 04:58:48 +00002304/*!
pingbak2f387e82009-01-26 03:31:40 +00002305 f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
2306 All conversions to i64 are expanded to a libcall.
Scott Michel8c67fa42009-01-21 04:58:48 +00002307 */
pingbak2f387e82009-01-26 03:31:40 +00002308static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2309 SPUTargetLowering &TLI) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002310 MVT OpVT = Op.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002311 SDValue Op0 = Op.getOperand(0);
pingbak2f387e82009-01-26 03:31:40 +00002312 MVT Op0VT = Op0.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002313
pingbak2f387e82009-01-26 03:31:40 +00002314 if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
2315 || OpVT == MVT::i64) {
2316 // Convert f32 / f64 to i32 / i64 via libcall.
2317 RTLIB::Libcall LC =
2318 (Op.getOpcode() == ISD::FP_TO_SINT)
2319 ? RTLIB::getFPTOSINT(Op0VT, OpVT)
2320 : RTLIB::getFPTOUINT(Op0VT, OpVT);
2321 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
2322 SDValue Dummy;
2323 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2324 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002325
Eli Friedman9d77ac32009-05-27 00:47:34 +00002326 return Op;
pingbak2f387e82009-01-26 03:31:40 +00002327}
Scott Michel8c67fa42009-01-21 04:58:48 +00002328
pingbak2f387e82009-01-26 03:31:40 +00002329//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
2330/*!
2331 i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
2332 All conversions from i64 are expanded to a libcall.
2333 */
2334static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
2335 SPUTargetLowering &TLI) {
2336 MVT OpVT = Op.getValueType();
2337 SDValue Op0 = Op.getOperand(0);
2338 MVT Op0VT = Op0.getValueType();
2339
2340 if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
2341 || Op0VT == MVT::i64) {
2342 // Convert i32, i64 to f64 via libcall:
2343 RTLIB::Libcall LC =
2344 (Op.getOpcode() == ISD::SINT_TO_FP)
2345 ? RTLIB::getSINTTOFP(Op0VT, OpVT)
2346 : RTLIB::getUINTTOFP(Op0VT, OpVT);
2347 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
2348 SDValue Dummy;
2349 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2350 }
2351
Eli Friedman9d77ac32009-05-27 00:47:34 +00002352 return Op;
Scott Michel8c67fa42009-01-21 04:58:48 +00002353}
2354
2355//! Lower ISD::SETCC
2356/*!
2357 This handles MVT::f64 (double floating point) condition lowering
2358 */
Scott Michel8c67fa42009-01-21 04:58:48 +00002359static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2360 const TargetLowering &TLI) {
pingbak2f387e82009-01-26 03:31:40 +00002361 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen2dbdb0e2009-02-07 19:59:05 +00002362 DebugLoc dl = Op.getDebugLoc();
pingbak2f387e82009-01-26 03:31:40 +00002363 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2364
Scott Michel8c67fa42009-01-21 04:58:48 +00002365 SDValue lhs = Op.getOperand(0);
2366 SDValue rhs = Op.getOperand(1);
Scott Michel8c67fa42009-01-21 04:58:48 +00002367 MVT lhsVT = lhs.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002368 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2369
pingbak2f387e82009-01-26 03:31:40 +00002370 MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
2371 APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2372 MVT IntVT(MVT::i64);
2373
2374 // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
2375 // selected to a NOP:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002376 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
pingbak2f387e82009-01-26 03:31:40 +00002377 SDValue lhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002378 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2379 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002380 i64lhs, DAG.getConstant(32, MVT::i32)));
2381 SDValue lhsHi32abs =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002382 DAG.getNode(ISD::AND, dl, MVT::i32,
pingbak2f387e82009-01-26 03:31:40 +00002383 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2384 SDValue lhsLo32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002385 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
pingbak2f387e82009-01-26 03:31:40 +00002386
2387 // SETO and SETUO only use the lhs operand:
2388 if (CC->get() == ISD::SETO) {
2389 // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
2390 // SETUO
2391 APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
Dale Johannesen85fc0932009-02-04 01:48:28 +00002392 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2393 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002394 lhs, DAG.getConstantFP(0.0, lhsVT),
2395 ISD::SETUO),
2396 DAG.getConstant(ccResultAllOnes, ccResultVT));
2397 } else if (CC->get() == ISD::SETUO) {
2398 // Evaluates to true if Op0 is [SQ]NaN
Dale Johannesen85fc0932009-02-04 01:48:28 +00002399 return DAG.getNode(ISD::AND, dl, ccResultVT,
2400 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002401 lhsHi32abs,
2402 DAG.getConstant(0x7ff00000, MVT::i32),
2403 ISD::SETGE),
Dale Johannesen85fc0932009-02-04 01:48:28 +00002404 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002405 lhsLo32,
2406 DAG.getConstant(0, MVT::i32),
2407 ISD::SETGT));
2408 }
2409
Dale Johannesen24dd9a52009-02-07 00:55:49 +00002410 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, rhs);
pingbak2f387e82009-01-26 03:31:40 +00002411 SDValue rhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002412 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2413 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002414 i64rhs, DAG.getConstant(32, MVT::i32)));
2415
2416 // If a value is negative, subtract from the sign magnitude constant:
2417 SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
2418
2419 // Convert the sign-magnitude representation into 2's complement:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002420 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002421 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002422 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
pingbak2f387e82009-01-26 03:31:40 +00002423 SDValue lhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002424 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002425 lhsSelectMask, lhsSignMag2TC, i64lhs);
2426
Dale Johannesen85fc0932009-02-04 01:48:28 +00002427 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002428 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002429 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
pingbak2f387e82009-01-26 03:31:40 +00002430 SDValue rhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002431 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002432 rhsSelectMask, rhsSignMag2TC, i64rhs);
2433
2434 unsigned compareOp;
2435
Scott Michel8c67fa42009-01-21 04:58:48 +00002436 switch (CC->get()) {
2437 case ISD::SETOEQ:
Scott Michel8c67fa42009-01-21 04:58:48 +00002438 case ISD::SETUEQ:
pingbak2f387e82009-01-26 03:31:40 +00002439 compareOp = ISD::SETEQ; break;
2440 case ISD::SETOGT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002441 case ISD::SETUGT:
pingbak2f387e82009-01-26 03:31:40 +00002442 compareOp = ISD::SETGT; break;
2443 case ISD::SETOGE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002444 case ISD::SETUGE:
pingbak2f387e82009-01-26 03:31:40 +00002445 compareOp = ISD::SETGE; break;
2446 case ISD::SETOLT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002447 case ISD::SETULT:
pingbak2f387e82009-01-26 03:31:40 +00002448 compareOp = ISD::SETLT; break;
2449 case ISD::SETOLE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002450 case ISD::SETULE:
pingbak2f387e82009-01-26 03:31:40 +00002451 compareOp = ISD::SETLE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002452 case ISD::SETUNE:
pingbak2f387e82009-01-26 03:31:40 +00002453 case ISD::SETONE:
2454 compareOp = ISD::SETNE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002455 default:
2456 cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
2457 abort();
2458 break;
2459 }
2460
pingbak2f387e82009-01-26 03:31:40 +00002461 SDValue result =
Scott Michel34712c32009-03-16 18:47:25 +00002462 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
Dale Johannesen85fc0932009-02-04 01:48:28 +00002463 (ISD::CondCode) compareOp);
pingbak2f387e82009-01-26 03:31:40 +00002464
2465 if ((CC->get() & 0x8) == 0) {
2466 // Ordered comparison:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002467 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002468 lhs, DAG.getConstantFP(0.0, MVT::f64),
2469 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002470 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002471 rhs, DAG.getConstantFP(0.0, MVT::f64),
2472 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002473 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
pingbak2f387e82009-01-26 03:31:40 +00002474
Dale Johannesen85fc0932009-02-04 01:48:28 +00002475 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
pingbak2f387e82009-01-26 03:31:40 +00002476 }
2477
2478 return result;
Scott Michel8c67fa42009-01-21 04:58:48 +00002479}
2480
Scott Michel56a125e2008-11-22 23:50:42 +00002481//! Lower ISD::SELECT_CC
2482/*!
2483 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2484 SELB instruction.
2485
2486 \note Need to revisit this in the future: if the code path through the true
2487 and false value computations is longer than the latency of a branch (6
2488 cycles), then it would be more advantageous to branch and insert a new basic
2489 block and branch on the condition. However, this code does not make that
2490 assumption, given the simplisitc uses so far.
2491 */
2492
Scott Michel06eabde2008-12-27 04:51:36 +00002493static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2494 const TargetLowering &TLI) {
Scott Michel56a125e2008-11-22 23:50:42 +00002495 MVT VT = Op.getValueType();
2496 SDValue lhs = Op.getOperand(0);
2497 SDValue rhs = Op.getOperand(1);
2498 SDValue trueval = Op.getOperand(2);
2499 SDValue falseval = Op.getOperand(3);
2500 SDValue condition = Op.getOperand(4);
Dale Johannesen175fdef2009-02-06 21:50:26 +00002501 DebugLoc dl = Op.getDebugLoc();
Scott Michel56a125e2008-11-22 23:50:42 +00002502
Scott Michel06eabde2008-12-27 04:51:36 +00002503 // NOTE: SELB's arguments: $rA, $rB, $mask
2504 //
2505 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2506 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2507 // condition was true and 0s where the condition was false. Hence, the
2508 // arguments to SELB get reversed.
2509
Scott Michel56a125e2008-11-22 23:50:42 +00002510 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2511 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2512 // with another "cannot select select_cc" assert:
2513
Dale Johannesen175fdef2009-02-06 21:50:26 +00002514 SDValue compare = DAG.getNode(ISD::SETCC, dl,
Duncan Sands4a361272009-01-01 15:52:00 +00002515 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002516 lhs, rhs, condition);
Dale Johannesen175fdef2009-02-06 21:50:26 +00002517 return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002518}
2519
Scott Michelec8c82e2008-12-02 19:53:53 +00002520//! Custom lower ISD::TRUNCATE
2521static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2522{
Scott Michel34712c32009-03-16 18:47:25 +00002523 // Type to truncate to
Scott Michelec8c82e2008-12-02 19:53:53 +00002524 MVT VT = Op.getValueType();
2525 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2526 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesen175fdef2009-02-06 21:50:26 +00002527 DebugLoc dl = Op.getDebugLoc();
Scott Michelec8c82e2008-12-02 19:53:53 +00002528
Scott Michel34712c32009-03-16 18:47:25 +00002529 // Type to truncate from
Scott Michelec8c82e2008-12-02 19:53:53 +00002530 SDValue Op0 = Op.getOperand(0);
2531 MVT Op0VT = Op0.getValueType();
Scott Michelec8c82e2008-12-02 19:53:53 +00002532
Scott Michel06eabde2008-12-27 04:51:36 +00002533 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002534 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-12-27 04:51:36 +00002535 unsigned maskHigh = 0x08090a0b;
2536 unsigned maskLow = 0x0c0d0e0f;
2537 // Use a shuffle to perform the truncation
Evan Cheng907a2d22009-02-25 22:49:59 +00002538 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2539 DAG.getConstant(maskHigh, MVT::i32),
2540 DAG.getConstant(maskLow, MVT::i32),
2541 DAG.getConstant(maskHigh, MVT::i32),
2542 DAG.getConstant(maskLow, MVT::i32));
Scott Michel06eabde2008-12-27 04:51:36 +00002543
Scott Michel34712c32009-03-16 18:47:25 +00002544 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT,
2545 Op0, Op0, shufMask);
Scott Michel06eabde2008-12-27 04:51:36 +00002546
Scott Michel34712c32009-03-16 18:47:25 +00002547 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle);
Scott Michelec8c82e2008-12-02 19:53:53 +00002548 }
2549
Scott Michel06eabde2008-12-27 04:51:36 +00002550 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002551}
2552
Scott Michel56a125e2008-11-22 23:50:42 +00002553//! Custom (target-specific) lowering entry point
2554/*!
2555 This is where LLVM's DAG selection process calls to do target-specific
2556 lowering of nodes.
2557 */
Dan Gohman8181bd12008-07-27 21:46:04 +00002558SDValue
2559SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002560{
Scott Michel97872d32008-02-23 18:41:37 +00002561 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002562 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002563
2564 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002565 default: {
2566 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002567 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002568 cerr << "*Op.getNode():\n";
2569 Op.getNode()->dump();
Scott Michel8efdca42007-12-04 22:23:35 +00002570 abort();
2571 }
2572 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002573 case ISD::EXTLOAD:
Scott Michel8efdca42007-12-04 22:23:35 +00002574 case ISD::SEXTLOAD:
2575 case ISD::ZEXTLOAD:
2576 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2577 case ISD::STORE:
2578 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2579 case ISD::ConstantPool:
2580 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2581 case ISD::GlobalAddress:
2582 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2583 case ISD::JumpTable:
2584 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002585 case ISD::ConstantFP:
2586 return LowerConstantFP(Op, DAG);
2587 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002588 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002589 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002590 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002591 case ISD::RET:
2592 return LowerRET(Op, DAG, getTargetMachine());
2593
Scott Michel4d07fb72008-12-30 23:28:25 +00002594 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002595 case ISD::ADD:
Scott Michel8efdca42007-12-04 22:23:35 +00002596 case ISD::SUB:
2597 case ISD::ROTR:
2598 case ISD::ROTL:
2599 case ISD::SRL:
2600 case ISD::SHL:
Scott Michel67224b22008-06-02 22:18:03 +00002601 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002602 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002603 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002604 break;
Scott Michel67224b22008-06-02 22:18:03 +00002605 }
Scott Michel8efdca42007-12-04 22:23:35 +00002606
pingbak2f387e82009-01-26 03:31:40 +00002607 case ISD::FP_TO_SINT:
2608 case ISD::FP_TO_UINT:
2609 return LowerFP_TO_INT(Op, DAG, *this);
2610
2611 case ISD::SINT_TO_FP:
2612 case ISD::UINT_TO_FP:
2613 return LowerINT_TO_FP(Op, DAG, *this);
Scott Michel8c67fa42009-01-21 04:58:48 +00002614
Scott Michel8efdca42007-12-04 22:23:35 +00002615 // Vector-related lowering.
2616 case ISD::BUILD_VECTOR:
pingbak2f387e82009-01-26 03:31:40 +00002617 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002618 case ISD::SCALAR_TO_VECTOR:
2619 return LowerSCALAR_TO_VECTOR(Op, DAG);
2620 case ISD::VECTOR_SHUFFLE:
2621 return LowerVECTOR_SHUFFLE(Op, DAG);
2622 case ISD::EXTRACT_VECTOR_ELT:
2623 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2624 case ISD::INSERT_VECTOR_ELT:
2625 return LowerINSERT_VECTOR_ELT(Op, DAG);
2626
2627 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2628 case ISD::AND:
2629 case ISD::OR:
2630 case ISD::XOR:
2631 return LowerByteImmed(Op, DAG);
2632
2633 // Vector and i8 multiply:
2634 case ISD::MUL:
Scott Michel4d07fb72008-12-30 23:28:25 +00002635 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002636 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002637
Scott Michel8efdca42007-12-04 22:23:35 +00002638 case ISD::CTPOP:
2639 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002640
2641 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002642 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002643
Scott Michel8c67fa42009-01-21 04:58:48 +00002644 case ISD::SETCC:
2645 return LowerSETCC(Op, DAG, *this);
2646
Scott Michelec8c82e2008-12-02 19:53:53 +00002647 case ISD::TRUNCATE:
2648 return LowerTRUNCATE(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002649 }
2650
Dan Gohman8181bd12008-07-27 21:46:04 +00002651 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002652}
2653
Duncan Sands7d9834b2008-12-01 11:39:25 +00002654void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2655 SmallVectorImpl<SDValue>&Results,
2656 SelectionDAG &DAG)
Scott Michel6e2d68b2008-11-10 23:43:06 +00002657{
2658#if 0
2659 unsigned Opc = (unsigned) N->getOpcode();
2660 MVT OpVT = N->getValueType(0);
2661
2662 switch (Opc) {
2663 default: {
2664 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2665 cerr << "Op.getOpcode() = " << Opc << "\n";
2666 cerr << "*Op.getNode():\n";
2667 N->dump();
2668 abort();
2669 /*NOTREACHED*/
2670 }
2671 }
2672#endif
2673
2674 /* Otherwise, return unchanged */
Scott Michel6e2d68b2008-11-10 23:43:06 +00002675}
2676
Scott Michel8efdca42007-12-04 22:23:35 +00002677//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002678// Target Optimization Hooks
2679//===----------------------------------------------------------------------===//
2680
Dan Gohman8181bd12008-07-27 21:46:04 +00002681SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002682SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2683{
2684#if 0
2685 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002686#endif
2687 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002688 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-12-01 17:56:02 +00002689 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2690 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michel06eabde2008-12-27 04:51:36 +00002691 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002692 SDValue Result; // Initially, empty result
Dale Johannesen175fdef2009-02-06 21:50:26 +00002693 DebugLoc dl = N->getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002694
2695 switch (N->getOpcode()) {
2696 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002697 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002698 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002699
Scott Michel06eabde2008-12-27 04:51:36 +00002700 if (Op0.getOpcode() == SPUISD::IndirectAddr
2701 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2702 // Normalize the operands to reduce repeated code
2703 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michelae5cbf52008-12-29 03:23:36 +00002704
Scott Michel06eabde2008-12-27 04:51:36 +00002705 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2706 IndirectArg = Op1;
2707 AddArg = Op0;
2708 }
2709
2710 if (isa<ConstantSDNode>(AddArg)) {
2711 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2712 SDValue IndOp1 = IndirectArg.getOperand(1);
2713
2714 if (CN0->isNullValue()) {
2715 // (add (SPUindirect <arg>, <arg>), 0) ->
2716 // (SPUindirect <arg>, <arg>)
Scott Michelf9f42e62008-01-29 02:16:57 +00002717
Scott Michel8c2746e2008-12-04 17:16:59 +00002718#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002719 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002720 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002721 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2722 << "With: (SPUindirect <arg>, <arg>)\n";
2723 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002724#endif
2725
Scott Michel06eabde2008-12-27 04:51:36 +00002726 return IndirectArg;
2727 } else if (isa<ConstantSDNode>(IndOp1)) {
2728 // (add (SPUindirect <arg>, <const>), <const>) ->
2729 // (SPUindirect <arg>, <const + const>)
2730 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2731 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2732 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michelf9f42e62008-01-29 02:16:57 +00002733
Scott Michel06eabde2008-12-27 04:51:36 +00002734#if !defined(NDEBUG)
2735 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2736 cerr << "\n"
2737 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2738 << "), " << CN0->getSExtValue() << ")\n"
2739 << "With: (SPUindirect <arg>, "
2740 << combinedConst << ")\n";
2741 }
2742#endif
Scott Michelf9f42e62008-01-29 02:16:57 +00002743
Dale Johannesen175fdef2009-02-06 21:50:26 +00002744 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel06eabde2008-12-27 04:51:36 +00002745 IndirectArg, combinedValue);
2746 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002747 }
2748 }
Scott Michel97872d32008-02-23 18:41:37 +00002749 break;
2750 }
2751 case ISD::SIGN_EXTEND:
2752 case ISD::ZERO_EXTEND:
2753 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002754 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002755 // (any_extend (SPUextract_elt0 <arg>)) ->
2756 // (SPUextract_elt0 <arg>)
2757 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002758#if !defined(NDEBUG)
2759 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002760 cerr << "\nReplace: ";
2761 N->dump(&DAG);
2762 cerr << "\nWith: ";
2763 Op0.getNode()->dump(&DAG);
2764 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002765 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002766#endif
Scott Michel97872d32008-02-23 18:41:37 +00002767
2768 return Op0;
2769 }
2770 break;
2771 }
2772 case SPUISD::IndirectAddr: {
2773 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002774 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2775 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michel97872d32008-02-23 18:41:37 +00002776 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2777 // (SPUaform <addr>, 0)
2778
2779 DEBUG(cerr << "Replace: ");
2780 DEBUG(N->dump(&DAG));
2781 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002782 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002783 DEBUG(cerr << "\n");
2784
2785 return Op0;
2786 }
Scott Michel06eabde2008-12-27 04:51:36 +00002787 } else if (Op0.getOpcode() == ISD::ADD) {
2788 SDValue Op1 = N->getOperand(1);
2789 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2790 // (SPUindirect (add <arg>, <arg>), 0) ->
2791 // (SPUindirect <arg>, <arg>)
2792 if (CN1->isNullValue()) {
2793
2794#if !defined(NDEBUG)
2795 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2796 cerr << "\n"
2797 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2798 << "With: (SPUindirect <arg>, <arg>)\n";
2799 }
2800#endif
2801
Dale Johannesen175fdef2009-02-06 21:50:26 +00002802 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel06eabde2008-12-27 04:51:36 +00002803 Op0.getOperand(0), Op0.getOperand(1));
2804 }
2805 }
Scott Michel97872d32008-02-23 18:41:37 +00002806 }
2807 break;
2808 }
2809 case SPUISD::SHLQUAD_L_BITS:
2810 case SPUISD::SHLQUAD_L_BYTES:
2811 case SPUISD::VEC_SHL:
2812 case SPUISD::VEC_SRL:
2813 case SPUISD::VEC_SRA:
Scott Michel06eabde2008-12-27 04:51:36 +00002814 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002815 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002816
Scott Michel06eabde2008-12-27 04:51:36 +00002817 // Kill degenerate vector shifts:
2818 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2819 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002820 Result = Op0;
2821 }
2822 }
2823 break;
2824 }
Scott Michel06eabde2008-12-27 04:51:36 +00002825 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-02-23 18:41:37 +00002826 switch (Op0.getOpcode()) {
2827 default:
2828 break;
2829 case ISD::ANY_EXTEND:
2830 case ISD::ZERO_EXTEND:
2831 case ISD::SIGN_EXTEND: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002832 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002833 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002834 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002835 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002836 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002837 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002838 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002839 Result = Op000;
2840 }
2841 }
2842 break;
2843 }
Scott Michelc630c412008-11-24 17:11:17 +00002844 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002845 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002846 // <arg>
2847 Result = Op0.getOperand(0);
2848 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002849 }
Scott Michel97872d32008-02-23 18:41:37 +00002850 }
2851 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002852 }
2853 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002854
Scott Michel394e26d2008-01-17 20:38:41 +00002855 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002856#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002857 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002858 DEBUG(cerr << "\nReplace.SPU: ");
2859 DEBUG(N->dump(&DAG));
2860 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002861 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002862 DEBUG(cerr << "\n");
2863 }
2864#endif
2865
2866 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002867}
2868
2869//===----------------------------------------------------------------------===//
2870// Inline Assembly Support
2871//===----------------------------------------------------------------------===//
2872
2873/// getConstraintType - Given a constraint letter, return the type of
2874/// constraint it is for this target.
Scott Michel4ec722e2008-07-16 17:17:29 +00002875SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-12-04 22:23:35 +00002876SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2877 if (ConstraintLetter.size() == 1) {
2878 switch (ConstraintLetter[0]) {
2879 default: break;
2880 case 'b':
2881 case 'r':
2882 case 'f':
2883 case 'v':
2884 case 'y':
2885 return C_RegisterClass;
Scott Michel4ec722e2008-07-16 17:17:29 +00002886 }
Scott Michel8efdca42007-12-04 22:23:35 +00002887 }
2888 return TargetLowering::getConstraintType(ConstraintLetter);
2889}
2890
Scott Michel4ec722e2008-07-16 17:17:29 +00002891std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002892SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002893 MVT VT) const
Scott Michel8efdca42007-12-04 22:23:35 +00002894{
2895 if (Constraint.size() == 1) {
2896 // GCC RS6000 Constraint Letters
2897 switch (Constraint[0]) {
2898 case 'b': // R1-R31
2899 case 'r': // R0-R31
2900 if (VT == MVT::i64)
2901 return std::make_pair(0U, SPU::R64CRegisterClass);
2902 return std::make_pair(0U, SPU::R32CRegisterClass);
2903 case 'f':
2904 if (VT == MVT::f32)
2905 return std::make_pair(0U, SPU::R32FPRegisterClass);
2906 else if (VT == MVT::f64)
2907 return std::make_pair(0U, SPU::R64FPRegisterClass);
2908 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002909 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00002910 return std::make_pair(0U, SPU::GPRCRegisterClass);
2911 }
2912 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002913
Scott Michel8efdca42007-12-04 22:23:35 +00002914 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2915}
2916
Scott Michel97872d32008-02-23 18:41:37 +00002917//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002918void
Dan Gohman8181bd12008-07-27 21:46:04 +00002919SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002920 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00002921 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00002922 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002923 const SelectionDAG &DAG,
2924 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00002925#if 0
Dan Gohmand06cad62009-04-01 18:45:54 +00002926 const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT;
Scott Michel97872d32008-02-23 18:41:37 +00002927
2928 switch (Op.getOpcode()) {
2929 default:
2930 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2931 break;
Scott Michel97872d32008-02-23 18:41:37 +00002932 case CALL:
2933 case SHUFB:
Scott Michel56a125e2008-11-22 23:50:42 +00002934 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00002935 case CNTB:
Scott Michel8c67fa42009-01-21 04:58:48 +00002936 case SPUISD::PREFSLOT2VEC:
Scott Michel97872d32008-02-23 18:41:37 +00002937 case SPUISD::LDRESULT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002938 case SPUISD::VEC2PREFSLOT:
Scott Michelbc5fbc12008-04-30 00:30:08 +00002939 case SPUISD::SHLQUAD_L_BITS:
2940 case SPUISD::SHLQUAD_L_BYTES:
2941 case SPUISD::VEC_SHL:
2942 case SPUISD::VEC_SRL:
2943 case SPUISD::VEC_SRA:
2944 case SPUISD::VEC_ROTL:
2945 case SPUISD::VEC_ROTR:
Scott Michelbc5fbc12008-04-30 00:30:08 +00002946 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00002947 case SPUISD::SELECT_MASK:
2948 case SPUISD::SELB:
Scott Michel97872d32008-02-23 18:41:37 +00002949 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002950#endif
Scott Michel8efdca42007-12-04 22:23:35 +00002951}
Scott Michel4d07fb72008-12-30 23:28:25 +00002952
Scott Michel06eabde2008-12-27 04:51:36 +00002953unsigned
2954SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2955 unsigned Depth) const {
2956 switch (Op.getOpcode()) {
2957 default:
2958 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00002959
Scott Michel06eabde2008-12-27 04:51:36 +00002960 case ISD::SETCC: {
2961 MVT VT = Op.getValueType();
2962
2963 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2964 VT = MVT::i32;
2965 }
2966 return VT.getSizeInBits();
2967 }
2968 }
2969}
Scott Michelae5cbf52008-12-29 03:23:36 +00002970
Scott Michelbc5fbc12008-04-30 00:30:08 +00002971// LowerAsmOperandForConstraint
2972void
Dan Gohman8181bd12008-07-27 21:46:04 +00002973SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002974 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00002975 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00002976 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002977 SelectionDAG &DAG) const {
2978 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00002979 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2980 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00002981}
2982
Scott Michel8efdca42007-12-04 22:23:35 +00002983/// isLegalAddressImmediate - Return true if the integer value can be used
2984/// as the offset of the target addressing mode.
Gabor Greife9f7f582008-08-31 15:37:04 +00002985bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
2986 const Type *Ty) const {
Scott Michel8efdca42007-12-04 22:23:35 +00002987 // SPU's addresses are 256K:
2988 return (V > -(1 << 18) && V < (1 << 18) - 1);
2989}
2990
2991bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel4ec722e2008-07-16 17:17:29 +00002992 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00002993}
Dan Gohman36322c72008-10-18 02:06:02 +00002994
2995bool
2996SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
2997 // The SPU target isn't yet aware of offsets.
2998 return false;
2999}