blob: 7879007319876101c60c14dd12a914d79ad1349e [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//
Scott Michel7ea02ff2009-03-17 01:15:45 +00002//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michel203b2d62008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michelf0569be2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michelc9c8b2a2009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000021#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000027#include "llvm/Constants.h"
28#include "llvm/Function.h"
29#include "llvm/Intrinsics.h"
30#include "llvm/Support/Debug.h"
Torok Edwindac237e2009-07-08 20:53:28 +000031#include "llvm/Support/ErrorHandling.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000032#include "llvm/Support/MathExtras.h"
Torok Edwindac237e2009-07-08 20:53:28 +000033#include "llvm/Support/raw_ostream.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000034#include "llvm/Target/TargetOptions.h"
35
36#include <map>
37
38using namespace llvm;
39
40// Used in getTargetNodeName() below
41namespace {
42 std::map<unsigned, const char *> node_names;
43
Duncan Sands83ec4b62008-06-06 12:08:01 +000044 //! MVT mapping to useful data for Cell SPU
Scott Michel266bc8f2007-12-04 22:23:35 +000045 struct valtype_map_s {
Scott Michel7a1c9e92008-11-22 23:50:42 +000046 const MVT valtype;
47 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000048 };
Scott Michel5af8f0e2008-07-16 17:17:29 +000049
Scott Michel266bc8f2007-12-04 22:23:35 +000050 const valtype_map_s valtype_map[] = {
51 { MVT::i1, 3 },
52 { MVT::i8, 3 },
53 { MVT::i16, 2 },
54 { MVT::i32, 0 },
55 { MVT::f32, 0 },
56 { MVT::i64, 0 },
57 { MVT::f64, 0 },
58 { MVT::i128, 0 }
59 };
60
61 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
62
Duncan Sands83ec4b62008-06-06 12:08:01 +000063 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel266bc8f2007-12-04 22:23:35 +000064 const valtype_map_s *retval = 0;
65
66 for (size_t i = 0; i < n_valtype_map; ++i) {
67 if (valtype_map[i].valtype == VT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +000068 retval = valtype_map + i;
69 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000070 }
71 }
72
73#ifndef NDEBUG
74 if (retval == 0) {
Torok Edwindac237e2009-07-08 20:53:28 +000075 std::string msg;
76 raw_string_ostream Msg(msg);
77 Msg << "getValueTypeMapEntry returns NULL for "
78 << VT.getMVTString();
79 llvm_report_error(Msg.str());
Scott Michel266bc8f2007-12-04 22:23:35 +000080 }
81#endif
82
83 return retval;
84 }
Scott Michel94bd57e2009-01-15 04:41:47 +000085
Scott Michelc9c8b2a2009-01-26 03:31:40 +000086 //! Expand a library call into an actual call DAG node
87 /*!
88 \note
89 This code is taken from SelectionDAGLegalize, since it is not exposed as
90 part of the LLVM SelectionDAG API.
91 */
92
93 SDValue
94 ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG,
95 bool isSigned, SDValue &Hi, SPUTargetLowering &TLI) {
96 // The input chain to this libcall is the entry node of the function.
97 // Legalizing the call will automatically add the previous call to the
98 // dependence.
99 SDValue InChain = DAG.getEntryNode();
100
101 TargetLowering::ArgListTy Args;
102 TargetLowering::ArgListEntry Entry;
103 for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
104 MVT ArgVT = Op.getOperand(i).getValueType();
105 const Type *ArgTy = ArgVT.getTypeForMVT();
106 Entry.Node = Op.getOperand(i);
107 Entry.Ty = ArgTy;
108 Entry.isSExt = isSigned;
109 Entry.isZExt = !isSigned;
110 Args.push_back(Entry);
111 }
112 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
113 TLI.getPointerTy());
114
115 // Splice the libcall in wherever FindInputOutputChains tells us to.
116 const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
117 std::pair<SDValue, SDValue> CallInfo =
118 TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
Tilmann Scheller6b61cd12009-07-03 06:44:53 +0000119 0, CallingConv::C, false, Callee, Args, DAG,
Dale Johannesen6f38cb62009-02-07 19:59:05 +0000120 Op.getDebugLoc());
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000121
122 return CallInfo.first;
123 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000124}
125
126SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
127 : TargetLowering(TM),
128 SPUTM(TM)
129{
130 // Fold away setcc operations if possible.
131 setPow2DivIsCheap();
132
133 // Use _setjmp/_longjmp instead of setjmp/longjmp.
134 setUseUnderscoreSetJmp(true);
135 setUseUnderscoreLongJmp(true);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000136
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000137 // Set RTLIB libcall names as used by SPU:
138 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
139
Scott Michel266bc8f2007-12-04 22:23:35 +0000140 // Set up the SPU's register classes:
Scott Michel504c3692007-12-17 22:32:34 +0000141 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
142 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
143 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
144 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
145 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
146 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000147 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000148
Scott Michel266bc8f2007-12-04 22:23:35 +0000149 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng03294662008-10-14 21:26:46 +0000150 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
151 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
152 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000153
Scott Michelf0569be2008-12-27 04:51:36 +0000154 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
155 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelb30e8f62008-12-02 19:53:53 +0000156
Scott Michel266bc8f2007-12-04 22:23:35 +0000157 // SPU constant load actions are custom lowered:
Nate Begemanccef5802008-02-14 18:43:04 +0000158 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000159 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
160
161 // SPU's loads and stores have to be custom lowered:
Scott Micheldd950092009-01-06 03:36:14 +0000162 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel266bc8f2007-12-04 22:23:35 +0000163 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000164 MVT VT = (MVT::SimpleValueType)sctype;
165
Scott Michelf0569be2008-12-27 04:51:36 +0000166 setOperationAction(ISD::LOAD, VT, Custom);
167 setOperationAction(ISD::STORE, VT, Custom);
168 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
169 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
170 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
171
172 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
173 MVT StoreVT = (MVT::SimpleValueType) stype;
174 setTruncStoreAction(VT, StoreVT, Expand);
175 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000176 }
177
Scott Michelf0569be2008-12-27 04:51:36 +0000178 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
179 ++sctype) {
180 MVT VT = (MVT::SimpleValueType) sctype;
181
182 setOperationAction(ISD::LOAD, VT, Custom);
183 setOperationAction(ISD::STORE, VT, Custom);
184
185 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
186 MVT StoreVT = (MVT::SimpleValueType) stype;
187 setTruncStoreAction(VT, StoreVT, Expand);
188 }
189 }
190
Scott Michel266bc8f2007-12-04 22:23:35 +0000191 // Expand the jumptable branches
192 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
193 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000194
195 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel5af8f0e2008-07-16 17:17:29 +0000196 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000197 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
198 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
199 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
200 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000201
202 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000203 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
204
Scott Michelf0569be2008-12-27 04:51:36 +0000205 // SPU has no SREM/UREM instructions
Scott Michel266bc8f2007-12-04 22:23:35 +0000206 setOperationAction(ISD::SREM, MVT::i32, Expand);
207 setOperationAction(ISD::UREM, MVT::i32, Expand);
208 setOperationAction(ISD::SREM, MVT::i64, Expand);
209 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000210
Scott Michel266bc8f2007-12-04 22:23:35 +0000211 // We don't support sin/cos/sqrt/fmod
212 setOperationAction(ISD::FSIN , MVT::f64, Expand);
213 setOperationAction(ISD::FCOS , MVT::f64, Expand);
214 setOperationAction(ISD::FREM , MVT::f64, Expand);
215 setOperationAction(ISD::FSIN , MVT::f32, Expand);
216 setOperationAction(ISD::FCOS , MVT::f32, Expand);
217 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000218
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000219 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
220 // for f32!)
Scott Michel266bc8f2007-12-04 22:23:35 +0000221 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
222 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000223
Scott Michel266bc8f2007-12-04 22:23:35 +0000224 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
225 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
226
227 // SPU can do rotate right and left, so legalize it... but customize for i8
228 // because instructions don't exist.
Bill Wendling9440e352008-08-31 02:59:23 +0000229
230 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
231 // .td files.
232 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
233 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
234 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
235
Scott Michel266bc8f2007-12-04 22:23:35 +0000236 setOperationAction(ISD::ROTL, MVT::i32, Legal);
237 setOperationAction(ISD::ROTL, MVT::i16, Legal);
238 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Micheldc91bea2008-11-20 16:36:33 +0000239
Scott Michel266bc8f2007-12-04 22:23:35 +0000240 // SPU has no native version of shift left/right for i8
241 setOperationAction(ISD::SHL, MVT::i8, Custom);
242 setOperationAction(ISD::SRL, MVT::i8, Custom);
243 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000244
Scott Michel02d711b2008-12-30 23:28:25 +0000245 // Make these operations legal and handle them during instruction selection:
246 setOperationAction(ISD::SHL, MVT::i64, Legal);
247 setOperationAction(ISD::SRL, MVT::i64, Legal);
248 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000249
Scott Michel5af8f0e2008-07-16 17:17:29 +0000250 // Custom lower i8, i32 and i64 multiplications
251 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michel1df30c42008-12-29 03:23:36 +0000252 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel94bd57e2009-01-15 04:41:47 +0000253 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000254
Eli Friedman6314ac22009-06-16 06:40:59 +0000255 // Expand double-width multiplication
256 // FIXME: It would probably be reasonable to support some of these operations
257 setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand);
258 setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand);
259 setOperationAction(ISD::MULHU, MVT::i8, Expand);
260 setOperationAction(ISD::MULHS, MVT::i8, Expand);
261 setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand);
262 setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand);
263 setOperationAction(ISD::MULHU, MVT::i16, Expand);
264 setOperationAction(ISD::MULHS, MVT::i16, Expand);
265 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
266 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
267 setOperationAction(ISD::MULHU, MVT::i32, Expand);
268 setOperationAction(ISD::MULHS, MVT::i32, Expand);
269 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
270 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
271 setOperationAction(ISD::MULHU, MVT::i64, Expand);
272 setOperationAction(ISD::MULHS, MVT::i64, Expand);
273
Scott Michel8bf61e82008-06-02 22:18:03 +0000274 // Need to custom handle (some) common i8, i64 math ops
Scott Michel02d711b2008-12-30 23:28:25 +0000275 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000276 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000277 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000278 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000279
Scott Michel266bc8f2007-12-04 22:23:35 +0000280 // SPU does not have BSWAP. It does have i32 support CTLZ.
281 // CTPOP has to be custom lowered.
282 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
283 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
284
285 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
286 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
287 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
288 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
289
290 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
291 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
292
293 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000294
Scott Michel8bf61e82008-06-02 22:18:03 +0000295 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000296 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000297 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000298 setOperationAction(ISD::SELECT, MVT::i16, Legal);
299 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michelf0569be2008-12-27 04:51:36 +0000300 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000301
Scott Michel78c47fa2008-03-10 16:58:52 +0000302 setOperationAction(ISD::SETCC, MVT::i8, Legal);
303 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000304 setOperationAction(ISD::SETCC, MVT::i32, Legal);
305 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000306 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michelad2715e2008-03-05 23:02:02 +0000307
Scott Michelf0569be2008-12-27 04:51:36 +0000308 // Custom lower i128 -> i64 truncates
Scott Michelb30e8f62008-12-02 19:53:53 +0000309 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
310
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000311 // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
312 // to expand to a libcall, hence the custom lowering:
313 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
314 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000315
316 // FDIV on SPU requires custom lowering
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000317 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel266bc8f2007-12-04 22:23:35 +0000318
Scott Michel9de57a92009-01-26 22:33:37 +0000319 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000320 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000321 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000322 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
323 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000324 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000325 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000326 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
327 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
328
Scott Michel86c041f2007-12-20 00:44:13 +0000329 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
330 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
331 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
332 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000333
334 // We cannot sextinreg(i1). Expand to shifts.
335 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000336
Scott Michel266bc8f2007-12-04 22:23:35 +0000337 // Support label based line numbers.
Dan Gohman7f460202008-06-30 20:59:49 +0000338 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000339 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000340
341 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel266bc8f2007-12-04 22:23:35 +0000342 // appropriate instructions to materialize the address.
Scott Michel9c0c6b22008-11-21 02:56:16 +0000343 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michel053c1da2008-01-29 02:16:57 +0000344 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000345 MVT VT = (MVT::SimpleValueType)sctype;
346
Scott Michel1df30c42008-12-29 03:23:36 +0000347 setOperationAction(ISD::GlobalAddress, VT, Custom);
348 setOperationAction(ISD::ConstantPool, VT, Custom);
349 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michel053c1da2008-01-29 02:16:57 +0000350 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000351
352 // RET must be custom lowered, to meet ABI requirements
353 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000354
Scott Michel266bc8f2007-12-04 22:23:35 +0000355 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
356 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000357
Scott Michel266bc8f2007-12-04 22:23:35 +0000358 // Use the default implementation.
359 setOperationAction(ISD::VAARG , MVT::Other, Expand);
360 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
361 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000362 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000363 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
364 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
365 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
366
367 // Cell SPU has instructions for converting between i64 and fp.
368 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
369 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000370
Scott Michel266bc8f2007-12-04 22:23:35 +0000371 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
372 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
373
374 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
375 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
376
377 // First set operation action for all vector types to expand. Then we
378 // will selectively turn on ones that can be effectively codegen'd.
379 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
380 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
381 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
382 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
383 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
384 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
385
Scott Michel21213e72009-01-06 23:10:38 +0000386 // "Odd size" vector classes that we're willing to support:
387 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
388
Duncan Sands83ec4b62008-06-06 12:08:01 +0000389 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
390 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
391 MVT VT = (MVT::SimpleValueType)i;
Scott Michel266bc8f2007-12-04 22:23:35 +0000392
Duncan Sands83ec4b62008-06-06 12:08:01 +0000393 // add/sub are legal for all supported vector VT's.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000394 setOperationAction(ISD::ADD, VT, Legal);
395 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000396 // mul has to be custom lowered.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000397 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000398
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000399 setOperationAction(ISD::AND, VT, Legal);
400 setOperationAction(ISD::OR, VT, Legal);
401 setOperationAction(ISD::XOR, VT, Legal);
402 setOperationAction(ISD::LOAD, VT, Legal);
403 setOperationAction(ISD::SELECT, VT, Legal);
404 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000405
Scott Michel266bc8f2007-12-04 22:23:35 +0000406 // These operations need to be expanded:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000407 setOperationAction(ISD::SDIV, VT, Expand);
408 setOperationAction(ISD::SREM, VT, Expand);
409 setOperationAction(ISD::UDIV, VT, Expand);
410 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000411
412 // Custom lower build_vector, constant pool spills, insert and
413 // extract vector elements:
Duncan Sands83ec4b62008-06-06 12:08:01 +0000414 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
415 setOperationAction(ISD::ConstantPool, VT, Custom);
416 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
417 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
418 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
419 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000420 }
421
Scott Michel266bc8f2007-12-04 22:23:35 +0000422 setOperationAction(ISD::AND, MVT::v16i8, Custom);
423 setOperationAction(ISD::OR, MVT::v16i8, Custom);
424 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
425 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000426
Scott Michel02d711b2008-12-30 23:28:25 +0000427 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000428
Scott Michel266bc8f2007-12-04 22:23:35 +0000429 setShiftAmountType(MVT::i32);
Scott Michelf0569be2008-12-27 04:51:36 +0000430 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000431
Scott Michel266bc8f2007-12-04 22:23:35 +0000432 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000433
Scott Michel266bc8f2007-12-04 22:23:35 +0000434 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000435 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000436 setTargetDAGCombine(ISD::ZERO_EXTEND);
437 setTargetDAGCombine(ISD::SIGN_EXTEND);
438 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000439
Scott Michel266bc8f2007-12-04 22:23:35 +0000440 computeRegisterProperties();
Scott Michel7a1c9e92008-11-22 23:50:42 +0000441
Scott Michele07d3de2008-12-09 03:37:19 +0000442 // Set pre-RA register scheduler default to BURR, which produces slightly
443 // better code than the default (could also be TDRR, but TargetLowering.h
444 // needs a mod to support that model):
445 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel266bc8f2007-12-04 22:23:35 +0000446}
447
448const char *
449SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
450{
451 if (node_names.empty()) {
452 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
453 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
454 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
455 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000456 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000457 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000458 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
459 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
460 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel7a1c9e92008-11-22 23:50:42 +0000461 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000462 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michel1df30c42008-12-29 03:23:36 +0000463 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michel104de432008-11-24 17:11:17 +0000464 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michela59d4692008-02-23 18:41:37 +0000465 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
466 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000467 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
468 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
469 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
470 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
471 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000472 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
473 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
474 "SPUISD::ROTBYTES_LEFT_BITS";
Scott Michel8bf61e82008-06-02 22:18:03 +0000475 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000476 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel94bd57e2009-01-15 04:41:47 +0000477 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
478 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
479 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel266bc8f2007-12-04 22:23:35 +0000480 }
481
482 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
483
484 return ((i != node_names.end()) ? i->second : 0);
485}
486
Bill Wendlingb4202b82009-07-01 18:50:55 +0000487/// getFunctionAlignment - Return the Log2 alignment of this function.
Bill Wendling20c568f2009-06-30 22:38:32 +0000488unsigned SPUTargetLowering::getFunctionAlignment(const Function *) const {
489 return 3;
490}
491
Scott Michelf0569be2008-12-27 04:51:36 +0000492//===----------------------------------------------------------------------===//
493// Return the Cell SPU's SETCC result type
494//===----------------------------------------------------------------------===//
495
Duncan Sands5480c042009-01-01 15:52:00 +0000496MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michelf0569be2008-12-27 04:51:36 +0000497 // i16 and i32 are valid SETCC result types
498 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel78c47fa2008-03-10 16:58:52 +0000499}
500
Scott Michel266bc8f2007-12-04 22:23:35 +0000501//===----------------------------------------------------------------------===//
502// Calling convention code:
503//===----------------------------------------------------------------------===//
504
505#include "SPUGenCallingConv.inc"
506
507//===----------------------------------------------------------------------===//
508// LowerOperation implementation
509//===----------------------------------------------------------------------===//
510
511/// Custom lower loads for CellSPU
512/*!
513 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
514 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel30ee7df2008-12-04 03:02:42 +0000515
516 For extending loads, we also want to ensure that the following sequence is
517 emitted, e.g. for MVT::f32 extending load to MVT::f64:
518
519\verbatim
Scott Michel1df30c42008-12-29 03:23:36 +0000520%1 v16i8,ch = load
Scott Michel30ee7df2008-12-04 03:02:42 +0000521%2 v16i8,ch = rotate %1
Scott Michel1df30c42008-12-29 03:23:36 +0000522%3 v4f8, ch = bitconvert %2
Scott Michel30ee7df2008-12-04 03:02:42 +0000523%4 f32 = vec2perfslot %3
524%5 f64 = fp_extend %4
525\endverbatim
526*/
Dan Gohman475871a2008-07-27 21:46:04 +0000527static SDValue
528LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000529 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000530 SDValue the_chain = LN->getChain();
Scott Michelf0569be2008-12-27 04:51:36 +0000531 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel30ee7df2008-12-04 03:02:42 +0000532 MVT InVT = LN->getMemoryVT();
533 MVT OutVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000534 ISD::LoadExtType ExtType = LN->getExtensionType();
535 unsigned alignment = LN->getAlignment();
Scott Michelf0569be2008-12-27 04:51:36 +0000536 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000537 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000538
Scott Michel266bc8f2007-12-04 22:23:35 +0000539 switch (LN->getAddressingMode()) {
540 case ISD::UNINDEXED: {
Scott Michelf0569be2008-12-27 04:51:36 +0000541 SDValue result;
542 SDValue basePtr = LN->getBasePtr();
543 SDValue rotate;
Scott Michel266bc8f2007-12-04 22:23:35 +0000544
Scott Michelf0569be2008-12-27 04:51:36 +0000545 if (alignment == 16) {
546 ConstantSDNode *CN;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000547
Scott Michelf0569be2008-12-27 04:51:36 +0000548 // Special cases for a known aligned load to simplify the base pointer
549 // and the rotation amount:
550 if (basePtr.getOpcode() == ISD::ADD
551 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
552 // Known offset into basePtr
553 int64_t offset = CN->getSExtValue();
554 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000555
Scott Michelf0569be2008-12-27 04:51:36 +0000556 if (rotamt < 0)
557 rotamt += 16;
558
559 rotate = DAG.getConstant(rotamt, MVT::i16);
560
561 // Simplify the base pointer for this case:
562 basePtr = basePtr.getOperand(0);
563 if ((offset & ~0xf) > 0) {
Dale Johannesende064702009-02-06 21:50:26 +0000564 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000565 basePtr,
566 DAG.getConstant((offset & ~0xf), PtrVT));
567 }
568 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
569 || (basePtr.getOpcode() == SPUISD::IndirectAddr
570 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
571 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
572 // Plain aligned a-form address: rotate into preferred slot
573 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
574 int64_t rotamt = -vtm->prefslot_byte;
575 if (rotamt < 0)
576 rotamt += 16;
577 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000578 } else {
Scott Michelf0569be2008-12-27 04:51:36 +0000579 // Offset the rotate amount by the basePtr and the preferred slot
580 // byte offset
581 int64_t rotamt = -vtm->prefslot_byte;
582 if (rotamt < 0)
583 rotamt += 16;
Dale Johannesen33c960f2009-02-04 20:06:27 +0000584 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000585 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000586 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000587 }
Scott Michelf0569be2008-12-27 04:51:36 +0000588 } else {
589 // Unaligned load: must be more pessimistic about addressing modes:
590 if (basePtr.getOpcode() == ISD::ADD) {
591 MachineFunction &MF = DAG.getMachineFunction();
592 MachineRegisterInfo &RegInfo = MF.getRegInfo();
593 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
594 SDValue Flag;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000595
Scott Michelf0569be2008-12-27 04:51:36 +0000596 SDValue Op0 = basePtr.getOperand(0);
597 SDValue Op1 = basePtr.getOperand(1);
598
599 if (isa<ConstantSDNode>(Op1)) {
600 // Convert the (add <ptr>, <const>) to an indirect address contained
601 // in a register. Note that this is done because we need to avoid
602 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesende064702009-02-06 21:50:26 +0000603 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000604 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
605 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michelf0569be2008-12-27 04:51:36 +0000606 } else {
607 // Convert the (add <arg1>, <arg2>) to an indirect address, which
608 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesende064702009-02-06 21:50:26 +0000609 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michelf0569be2008-12-27 04:51:36 +0000610 }
611 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000612 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000613 basePtr,
614 DAG.getConstant(0, PtrVT));
615 }
616
617 // Offset the rotate amount by the basePtr and the preferred slot
618 // byte offset
Dale Johannesen33c960f2009-02-04 20:06:27 +0000619 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000620 basePtr,
621 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +0000622 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000623
Scott Michelf0569be2008-12-27 04:51:36 +0000624 // Re-emit as a v16i8 vector load
Dale Johannesen33c960f2009-02-04 20:06:27 +0000625 result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michelf0569be2008-12-27 04:51:36 +0000626 LN->getSrcValue(), LN->getSrcValueOffset(),
627 LN->isVolatile(), 16);
628
629 // Update the chain
630 the_chain = result.getValue(1);
631
632 // Rotate into the preferred slot:
Dale Johannesen33c960f2009-02-04 20:06:27 +0000633 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::v16i8,
Scott Michelf0569be2008-12-27 04:51:36 +0000634 result.getValue(0), rotate);
635
Scott Michel30ee7df2008-12-04 03:02:42 +0000636 // Convert the loaded v16i8 vector to the appropriate vector type
637 // specified by the operand:
638 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
Dale Johannesen33c960f2009-02-04 20:06:27 +0000639 result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT,
640 DAG.getNode(ISD::BIT_CONVERT, dl, vecVT, result));
Scott Michel5af8f0e2008-07-16 17:17:29 +0000641
Scott Michel30ee7df2008-12-04 03:02:42 +0000642 // Handle extending loads by extending the scalar result:
643 if (ExtType == ISD::SEXTLOAD) {
Dale Johannesen33c960f2009-02-04 20:06:27 +0000644 result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result);
Scott Michel30ee7df2008-12-04 03:02:42 +0000645 } else if (ExtType == ISD::ZEXTLOAD) {
Dale Johannesen33c960f2009-02-04 20:06:27 +0000646 result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result);
Scott Michel30ee7df2008-12-04 03:02:42 +0000647 } else if (ExtType == ISD::EXTLOAD) {
648 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000649
Scott Michel30ee7df2008-12-04 03:02:42 +0000650 if (OutVT.isFloatingPoint())
Scott Michel19c10e62009-01-26 03:37:41 +0000651 NewOpc = ISD::FP_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000652
Dale Johannesen33c960f2009-02-04 20:06:27 +0000653 result = DAG.getNode(NewOpc, dl, OutVT, result);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000654 }
655
Scott Michel30ee7df2008-12-04 03:02:42 +0000656 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman475871a2008-07-27 21:46:04 +0000657 SDValue retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000658 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000659 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000660 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000661
Dale Johannesen33c960f2009-02-04 20:06:27 +0000662 result = DAG.getNode(SPUISD::LDRESULT, dl, retvts,
Scott Michel58c58182008-01-17 20:38:41 +0000663 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000664 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000665 }
666 case ISD::PRE_INC:
667 case ISD::PRE_DEC:
668 case ISD::POST_INC:
669 case ISD::POST_DEC:
670 case ISD::LAST_INDEXED_MODE:
Torok Edwindac237e2009-07-08 20:53:28 +0000671 {
672 std::string msg;
673 raw_string_ostream Msg(msg);
674 Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
Scott Michel266bc8f2007-12-04 22:23:35 +0000675 "UNINDEXED\n";
Torok Edwindac237e2009-07-08 20:53:28 +0000676 Msg << (unsigned) LN->getAddressingMode();
677 llvm_report_error(Msg.str());
678 /*NOTREACHED*/
679 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000680 }
681
Dan Gohman475871a2008-07-27 21:46:04 +0000682 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000683}
684
685/// Custom lower stores for CellSPU
686/*!
687 All CellSPU stores are aligned to 16-byte boundaries, so for elements
688 within a 16-byte block, we have to generate a shuffle to insert the
689 requested element into its place, then store the resulting block.
690 */
Dan Gohman475871a2008-07-27 21:46:04 +0000691static SDValue
692LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000693 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000694 SDValue Value = SN->getValue();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000695 MVT VT = Value.getValueType();
696 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
697 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Dale Johannesen33c960f2009-02-04 20:06:27 +0000698 DebugLoc dl = Op.getDebugLoc();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000699 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000700
701 switch (SN->getAddressingMode()) {
702 case ISD::UNINDEXED: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000703 // The vector type we really want to load from the 16-byte chunk.
Scott Michel719b0e12008-11-19 17:45:08 +0000704 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
705 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +0000706
Scott Michelf0569be2008-12-27 04:51:36 +0000707 SDValue alignLoadVec;
708 SDValue basePtr = SN->getBasePtr();
709 SDValue the_chain = SN->getChain();
710 SDValue insertEltOffs;
Scott Michel266bc8f2007-12-04 22:23:35 +0000711
Scott Michelf0569be2008-12-27 04:51:36 +0000712 if (alignment == 16) {
713 ConstantSDNode *CN;
714
715 // Special cases for a known aligned load to simplify the base pointer
716 // and insertion byte:
717 if (basePtr.getOpcode() == ISD::ADD
718 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
719 // Known offset into basePtr
720 int64_t offset = CN->getSExtValue();
721
722 // Simplify the base pointer for this case:
723 basePtr = basePtr.getOperand(0);
Dale Johannesende064702009-02-06 21:50:26 +0000724 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000725 basePtr,
726 DAG.getConstant((offset & 0xf), PtrVT));
727
728 if ((offset & ~0xf) > 0) {
Dale Johannesende064702009-02-06 21:50:26 +0000729 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000730 basePtr,
731 DAG.getConstant((offset & ~0xf), PtrVT));
732 }
733 } else {
734 // Otherwise, assume it's at byte 0 of basePtr
Dale Johannesende064702009-02-06 21:50:26 +0000735 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000736 basePtr,
737 DAG.getConstant(0, PtrVT));
738 }
739 } else {
740 // Unaligned load: must be more pessimistic about addressing modes:
741 if (basePtr.getOpcode() == ISD::ADD) {
742 MachineFunction &MF = DAG.getMachineFunction();
743 MachineRegisterInfo &RegInfo = MF.getRegInfo();
744 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
745 SDValue Flag;
746
747 SDValue Op0 = basePtr.getOperand(0);
748 SDValue Op1 = basePtr.getOperand(1);
749
750 if (isa<ConstantSDNode>(Op1)) {
751 // Convert the (add <ptr>, <const>) to an indirect address contained
752 // in a register. Note that this is done because we need to avoid
753 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesende064702009-02-06 21:50:26 +0000754 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen33c960f2009-02-04 20:06:27 +0000755 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
756 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michelf0569be2008-12-27 04:51:36 +0000757 } else {
758 // Convert the (add <arg1>, <arg2>) to an indirect address, which
759 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesende064702009-02-06 21:50:26 +0000760 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michelf0569be2008-12-27 04:51:36 +0000761 }
762 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000763 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000764 basePtr,
765 DAG.getConstant(0, PtrVT));
766 }
767
768 // Insertion point is solely determined by basePtr's contents
Dale Johannesen33c960f2009-02-04 20:06:27 +0000769 insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michelf0569be2008-12-27 04:51:36 +0000770 basePtr,
771 DAG.getConstant(0, PtrVT));
772 }
773
774 // Re-emit as a v16i8 vector load
Dale Johannesen33c960f2009-02-04 20:06:27 +0000775 alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michelf0569be2008-12-27 04:51:36 +0000776 SN->getSrcValue(), SN->getSrcValueOffset(),
777 SN->isVolatile(), 16);
778
779 // Update the chain
780 the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000781
Scott Michel9de5d0d2008-01-11 02:53:15 +0000782 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman475871a2008-07-27 21:46:04 +0000783 SDValue theValue = SN->getValue();
784 SDValue result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000785
786 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000787 && (theValue.getOpcode() == ISD::AssertZext
788 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000789 // Drill down and get the value for zero- and sign-extended
790 // quantities
Scott Michel5af8f0e2008-07-16 17:17:29 +0000791 theValue = theValue.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000792 }
793
Scott Michel9de5d0d2008-01-11 02:53:15 +0000794 // If the base pointer is already a D-form address, then just create
795 // a new D-form address with a slot offset and the orignal base pointer.
796 // Otherwise generate a D-form address with the slot offset relative
797 // to the stack pointer, which is always aligned.
Scott Michelf0569be2008-12-27 04:51:36 +0000798#if !defined(NDEBUG)
799 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
800 cerr << "CellSPU LowerSTORE: basePtr = ";
801 basePtr.getNode()->dump(&DAG);
802 cerr << "\n";
803 }
804#endif
Scott Michel9de5d0d2008-01-11 02:53:15 +0000805
Scott Michel430a5552008-11-19 15:24:16 +0000806 SDValue insertEltOp =
Dale Johannesen33c960f2009-02-04 20:06:27 +0000807 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, insertEltOffs);
Scott Michel719b0e12008-11-19 17:45:08 +0000808 SDValue vectorizeOp =
Dale Johannesen33c960f2009-02-04 20:06:27 +0000809 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, theValue);
Scott Michel430a5552008-11-19 15:24:16 +0000810
Dale Johannesen33c960f2009-02-04 20:06:27 +0000811 result = DAG.getNode(SPUISD::SHUFB, dl, vecVT,
Scott Michel19c10e62009-01-26 03:37:41 +0000812 vectorizeOp, alignLoadVec,
Scott Michel6e1d1472009-03-16 18:47:25 +0000813 DAG.getNode(ISD::BIT_CONVERT, dl,
Dale Johannesen33c960f2009-02-04 20:06:27 +0000814 MVT::v4i32, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000815
Dale Johannesen33c960f2009-02-04 20:06:27 +0000816 result = DAG.getStore(the_chain, dl, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000817 LN->getSrcValue(), LN->getSrcValueOffset(),
818 LN->isVolatile(), LN->getAlignment());
819
Scott Michel23f2ff72008-12-04 17:16:59 +0000820#if 0 && !defined(NDEBUG)
Scott Michel430a5552008-11-19 15:24:16 +0000821 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
822 const SDValue &currentRoot = DAG.getRoot();
823
824 DAG.setRoot(result);
825 cerr << "------- CellSPU:LowerStore result:\n";
826 DAG.dump();
827 cerr << "-------\n";
828 DAG.setRoot(currentRoot);
829 }
830#endif
Scott Michelb30e8f62008-12-02 19:53:53 +0000831
Scott Michel266bc8f2007-12-04 22:23:35 +0000832 return result;
833 /*UNREACHED*/
834 }
835 case ISD::PRE_INC:
836 case ISD::PRE_DEC:
837 case ISD::POST_INC:
838 case ISD::POST_DEC:
839 case ISD::LAST_INDEXED_MODE:
Torok Edwindac237e2009-07-08 20:53:28 +0000840 {
841 std::string msg;
842 raw_string_ostream Msg(msg);
843 Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
Scott Michel266bc8f2007-12-04 22:23:35 +0000844 "UNINDEXED\n";
Torok Edwindac237e2009-07-08 20:53:28 +0000845 Msg << (unsigned) SN->getAddressingMode();
846 llvm_report_error(Msg.str());
847 /*NOTREACHED*/
848 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000849 }
850
Dan Gohman475871a2008-07-27 21:46:04 +0000851 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000852}
853
Scott Michel94bd57e2009-01-15 04:41:47 +0000854//! Generate the address of a constant pool entry.
855SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000856LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000857 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000858 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
859 Constant *C = CP->getConstVal();
Dan Gohman475871a2008-07-27 21:46:04 +0000860 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
861 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000862 const TargetMachine &TM = DAG.getTarget();
Dale Johannesende064702009-02-06 21:50:26 +0000863 // FIXME there is no actual debug info here
864 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000865
866 if (TM.getRelocationModel() == Reloc::Static) {
867 if (!ST->usingLargeMem()) {
Dan Gohman475871a2008-07-27 21:46:04 +0000868 // Just return the SDValue with the constant pool address in it.
Dale Johannesende064702009-02-06 21:50:26 +0000869 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000870 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000871 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, CPI, Zero);
872 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, CPI, Zero);
873 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000874 }
875 }
876
877 assert(0 &&
Gabor Greif93c53e52008-08-31 15:37:04 +0000878 "LowerConstantPool: Relocation model other than static"
879 " not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000880 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000881}
882
Scott Michel94bd57e2009-01-15 04:41:47 +0000883//! Alternate entry point for generating the address of a constant pool entry
884SDValue
885SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
886 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
887}
888
Dan Gohman475871a2008-07-27 21:46:04 +0000889static SDValue
890LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000891 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000892 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000893 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
894 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000895 const TargetMachine &TM = DAG.getTarget();
Dale Johannesende064702009-02-06 21:50:26 +0000896 // FIXME there is no actual debug info here
897 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000898
899 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000900 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +0000901 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000902 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000903 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, JTI, Zero);
904 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, JTI, Zero);
905 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michela59d4692008-02-23 18:41:37 +0000906 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000907 }
908
909 assert(0 &&
910 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000911 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000912}
913
Dan Gohman475871a2008-07-27 21:46:04 +0000914static SDValue
915LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000916 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000917 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
918 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman475871a2008-07-27 21:46:04 +0000919 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000920 const TargetMachine &TM = DAG.getTarget();
Dan Gohman475871a2008-07-27 21:46:04 +0000921 SDValue Zero = DAG.getConstant(0, PtrVT);
Dale Johannesende064702009-02-06 21:50:26 +0000922 // FIXME there is no actual debug info here
923 DebugLoc dl = Op.getDebugLoc();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000924
Scott Michel266bc8f2007-12-04 22:23:35 +0000925 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000926 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +0000927 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero);
Scott Michel053c1da2008-01-29 02:16:57 +0000928 } else {
Dale Johannesende064702009-02-06 21:50:26 +0000929 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, GA, Zero);
930 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, GA, Zero);
931 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel053c1da2008-01-29 02:16:57 +0000932 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000933 } else {
Torok Edwindac237e2009-07-08 20:53:28 +0000934 llvm_report_error("LowerGlobalAddress: Relocation model other than static"
935 "not supported.");
Scott Michel266bc8f2007-12-04 22:23:35 +0000936 /*NOTREACHED*/
937 }
938
Dan Gohman475871a2008-07-27 21:46:04 +0000939 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000940}
941
Nate Begemanccef5802008-02-14 18:43:04 +0000942//! Custom lower double precision floating point constants
Dan Gohman475871a2008-07-27 21:46:04 +0000943static SDValue
944LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000945 MVT VT = Op.getValueType();
Dale Johannesende064702009-02-06 21:50:26 +0000946 // FIXME there is no actual debug info here
947 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000948
Nate Begemanccef5802008-02-14 18:43:04 +0000949 if (VT == MVT::f64) {
Scott Michel1a6cdb62008-12-01 17:56:02 +0000950 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
951
952 assert((FP != 0) &&
953 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel1df30c42008-12-29 03:23:36 +0000954
Scott Michel170783a2007-12-19 20:15:47 +0000955 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel1a6cdb62008-12-01 17:56:02 +0000956 SDValue T = DAG.getConstant(dbits, MVT::i64);
Evan Chenga87008d2009-02-25 22:49:59 +0000957 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T);
Dale Johannesende064702009-02-06 21:50:26 +0000958 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
Dale Johannesenb300d2a2009-02-07 00:55:49 +0000959 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Tvec));
Scott Michel266bc8f2007-12-04 22:23:35 +0000960 }
961
Dan Gohman475871a2008-07-27 21:46:04 +0000962 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000963}
964
Dan Gohman475871a2008-07-27 21:46:04 +0000965static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000966LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel266bc8f2007-12-04 22:23:35 +0000967{
968 MachineFunction &MF = DAG.getMachineFunction();
969 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000970 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Micheld976c212008-10-30 01:51:48 +0000971 SmallVector<SDValue, 48> ArgValues;
Dan Gohman475871a2008-07-27 21:46:04 +0000972 SDValue Root = Op.getOperand(0);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000973 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Dale Johannesen33c960f2009-02-04 20:06:27 +0000974 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +0000975
976 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
977 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000978
Scott Michel266bc8f2007-12-04 22:23:35 +0000979 unsigned ArgOffset = SPUFrameInfo::minStackSize();
980 unsigned ArgRegIdx = 0;
981 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000982
Duncan Sands83ec4b62008-06-06 12:08:01 +0000983 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000984
Scott Michel266bc8f2007-12-04 22:23:35 +0000985 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif93c53e52008-08-31 15:37:04 +0000986 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
987 ArgNo != e; ++ArgNo) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000988 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
989 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Micheld976c212008-10-30 01:51:48 +0000990 SDValue ArgVal;
Scott Michel266bc8f2007-12-04 22:23:35 +0000991
Scott Micheld976c212008-10-30 01:51:48 +0000992 if (ArgRegIdx < NumArgRegs) {
993 const TargetRegisterClass *ArgRegClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +0000994
Scott Micheld976c212008-10-30 01:51:48 +0000995 switch (ObjectVT.getSimpleVT()) {
996 default: {
Torok Edwindac237e2009-07-08 20:53:28 +0000997 std::string msg;
998 raw_string_ostream Msg(msg);
999 Msg << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
1000 << ObjectVT.getMVTString();
1001 llvm_report_error(Msg.str());
Scott Micheld976c212008-10-30 01:51:48 +00001002 }
1003 case MVT::i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001004 ArgRegClass = &SPU::R8CRegClass;
1005 break;
Scott Micheld976c212008-10-30 01:51:48 +00001006 case MVT::i16:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001007 ArgRegClass = &SPU::R16CRegClass;
1008 break;
Scott Micheld976c212008-10-30 01:51:48 +00001009 case MVT::i32:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001010 ArgRegClass = &SPU::R32CRegClass;
1011 break;
Scott Micheld976c212008-10-30 01:51:48 +00001012 case MVT::i64:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001013 ArgRegClass = &SPU::R64CRegClass;
1014 break;
Scott Micheldd950092009-01-06 03:36:14 +00001015 case MVT::i128:
1016 ArgRegClass = &SPU::GPRCRegClass;
1017 break;
Scott Micheld976c212008-10-30 01:51:48 +00001018 case MVT::f32:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001019 ArgRegClass = &SPU::R32FPRegClass;
1020 break;
Scott Micheld976c212008-10-30 01:51:48 +00001021 case MVT::f64:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001022 ArgRegClass = &SPU::R64FPRegClass;
1023 break;
Scott Micheld976c212008-10-30 01:51:48 +00001024 case MVT::v2f64:
1025 case MVT::v4f32:
1026 case MVT::v2i64:
1027 case MVT::v4i32:
1028 case MVT::v8i16:
1029 case MVT::v16i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +00001030 ArgRegClass = &SPU::VECREGRegClass;
1031 break;
Scott Micheld976c212008-10-30 01:51:48 +00001032 }
1033
1034 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
1035 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001036 ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT);
Scott Micheld976c212008-10-30 01:51:48 +00001037 ++ArgRegIdx;
1038 } else {
1039 // We need to load the argument to a virtual register if we determined
1040 // above that we ran out of physical registers of the appropriate type
1041 // or we're forced to do vararg
Chris Lattner9f72d1a2008-02-13 07:35:30 +00001042 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +00001043 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001044 ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001045 ArgOffset += StackSlotSize;
1046 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001047
Scott Michel266bc8f2007-12-04 22:23:35 +00001048 ArgValues.push_back(ArgVal);
Scott Micheld976c212008-10-30 01:51:48 +00001049 // Update the chain
1050 Root = ArgVal.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001051 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001052
Scott Micheld976c212008-10-30 01:51:48 +00001053 // vararg handling:
Scott Michel266bc8f2007-12-04 22:23:35 +00001054 if (isVarArg) {
Scott Micheld976c212008-10-30 01:51:48 +00001055 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
1056 // We will spill (79-3)+1 registers to the stack
1057 SmallVector<SDValue, 79-3+1> MemOps;
1058
1059 // Create the frame slot
1060
Scott Michel266bc8f2007-12-04 22:23:35 +00001061 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Micheld976c212008-10-30 01:51:48 +00001062 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1063 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1064 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001065 SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0);
Scott Micheld976c212008-10-30 01:51:48 +00001066 Root = Store.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001067 MemOps.push_back(Store);
Scott Micheld976c212008-10-30 01:51:48 +00001068
1069 // Increment address by stack slot size for the next stored argument
1070 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001071 }
1072 if (!MemOps.empty())
Scott Michel6e1d1472009-03-16 18:47:25 +00001073 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001074 &MemOps[0], MemOps.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001075 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001076
Scott Michel266bc8f2007-12-04 22:23:35 +00001077 ArgValues.push_back(Root);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001078
Scott Michel266bc8f2007-12-04 22:23:35 +00001079 // Return the new list of results.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001080 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
Duncan Sandsaaffa052008-12-01 11:41:29 +00001081 &ArgValues[0], ArgValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001082}
1083
1084/// isLSAAddress - Return the immediate to use if the specified
1085/// value is representable as a LSA address.
Dan Gohman475871a2008-07-27 21:46:04 +00001086static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001087 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +00001088 if (!C) return 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001089
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001090 int Addr = C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001091 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1092 (Addr << 14 >> 14) != Addr)
1093 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001094
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001095 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel266bc8f2007-12-04 22:23:35 +00001096}
1097
Scott Michel21213e72009-01-06 23:10:38 +00001098static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +00001099LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman095cc292008-09-13 01:54:27 +00001100 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1101 SDValue Chain = TheCall->getChain();
Dan Gohman095cc292008-09-13 01:54:27 +00001102 SDValue Callee = TheCall->getCallee();
1103 unsigned NumOps = TheCall->getNumArgs();
Scott Michel266bc8f2007-12-04 22:23:35 +00001104 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1105 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1106 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Dale Johannesen33c960f2009-02-04 20:06:27 +00001107 DebugLoc dl = TheCall->getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001108
1109 // Handy pointer type
Duncan Sands83ec4b62008-06-06 12:08:01 +00001110 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001111
Scott Michel266bc8f2007-12-04 22:23:35 +00001112 // Accumulate how many bytes are to be pushed on the stack, including the
1113 // linkage area, and parameter passing area. According to the SPU ABI,
1114 // we minimally need space for [LR] and [SP]
1115 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001116
Scott Michel266bc8f2007-12-04 22:23:35 +00001117 // Set up a copy of the stack pointer for use loading and storing any
1118 // arguments that may not fit in the registers available for argument
1119 // passing.
Dan Gohman475871a2008-07-27 21:46:04 +00001120 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001121
Scott Michel266bc8f2007-12-04 22:23:35 +00001122 // Figure out which arguments are going to go in registers, and which in
1123 // memory.
1124 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1125 unsigned ArgRegIdx = 0;
1126
1127 // Keep track of registers passing arguments
Dan Gohman475871a2008-07-27 21:46:04 +00001128 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel266bc8f2007-12-04 22:23:35 +00001129 // And the arguments passed on the stack
Dan Gohman475871a2008-07-27 21:46:04 +00001130 SmallVector<SDValue, 8> MemOpChains;
Scott Michel266bc8f2007-12-04 22:23:35 +00001131
1132 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman095cc292008-09-13 01:54:27 +00001133 SDValue Arg = TheCall->getArg(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001134
Scott Michel266bc8f2007-12-04 22:23:35 +00001135 // PtrOff will be used to store the current argument to the stack if a
1136 // register cannot be found for it.
Dan Gohman475871a2008-07-27 21:46:04 +00001137 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Dale Johannesen33c960f2009-02-04 20:06:27 +00001138 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
Scott Michel266bc8f2007-12-04 22:23:35 +00001139
Duncan Sands83ec4b62008-06-06 12:08:01 +00001140 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001141 default: assert(0 && "Unexpected ValueType for argument!");
Scott Micheldd950092009-01-06 03:36:14 +00001142 case MVT::i8:
1143 case MVT::i16:
Scott Michel266bc8f2007-12-04 22:23:35 +00001144 case MVT::i32:
1145 case MVT::i64:
1146 case MVT::i128:
1147 if (ArgRegIdx != NumArgRegs) {
1148 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1149 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001150 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001151 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001152 }
1153 break;
1154 case MVT::f32:
1155 case MVT::f64:
1156 if (ArgRegIdx != NumArgRegs) {
1157 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1158 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001159 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001160 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001161 }
1162 break;
Scott Michelcc188272008-12-04 21:01:44 +00001163 case MVT::v2i64:
1164 case MVT::v2f64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001165 case MVT::v4f32:
1166 case MVT::v4i32:
1167 case MVT::v8i16:
1168 case MVT::v16i8:
1169 if (ArgRegIdx != NumArgRegs) {
1170 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1171 } else {
Dale Johannesen33c960f2009-02-04 20:06:27 +00001172 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001173 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001174 }
1175 break;
1176 }
1177 }
1178
1179 // Update number of stack bytes actually used, insert a call sequence start
1180 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnere563bbc2008-10-11 22:08:30 +00001181 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1182 true));
Scott Michel266bc8f2007-12-04 22:23:35 +00001183
1184 if (!MemOpChains.empty()) {
1185 // Adjust the stack pointer for the stack arguments.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001186 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Scott Michel266bc8f2007-12-04 22:23:35 +00001187 &MemOpChains[0], MemOpChains.size());
1188 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001189
Scott Michel266bc8f2007-12-04 22:23:35 +00001190 // Build a sequence of copy-to-reg nodes chained together with token chain
1191 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman475871a2008-07-27 21:46:04 +00001192 SDValue InFlag;
Scott Michel266bc8f2007-12-04 22:23:35 +00001193 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
Scott Michel6e1d1472009-03-16 18:47:25 +00001194 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001195 RegsToPass[i].second, InFlag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001196 InFlag = Chain.getValue(1);
1197 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001198
Dan Gohman475871a2008-07-27 21:46:04 +00001199 SmallVector<SDValue, 8> Ops;
Scott Michel266bc8f2007-12-04 22:23:35 +00001200 unsigned CallOpc = SPUISD::CALL;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001201
Bill Wendling056292f2008-09-16 21:48:12 +00001202 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1203 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1204 // node so that legalize doesn't hack it.
Scott Michel19fd42a2008-11-11 03:06:06 +00001205 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001206 GlobalValue *GV = G->getGlobal();
Duncan Sands83ec4b62008-06-06 12:08:01 +00001207 MVT CalleeVT = Callee.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001208 SDValue Zero = DAG.getConstant(0, PtrVT);
1209 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001210
Scott Michel9de5d0d2008-01-11 02:53:15 +00001211 if (!ST->usingLargeMem()) {
1212 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1213 // style calls, otherwise, external symbols are BRASL calls. This assumes
1214 // that declared/defined symbols are in the same compilation unit and can
1215 // be reached through PC-relative jumps.
1216 //
1217 // NOTE:
1218 // This may be an unsafe assumption for JIT and really large compilation
1219 // units.
1220 if (GV->isDeclaration()) {
Dale Johannesende064702009-02-06 21:50:26 +00001221 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001222 } else {
Dale Johannesende064702009-02-06 21:50:26 +00001223 Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001224 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001225 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001226 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1227 // address pairs:
Dale Johannesende064702009-02-06 21:50:26 +00001228 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001229 }
Scott Michel1df30c42008-12-29 03:23:36 +00001230 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1231 MVT CalleeVT = Callee.getValueType();
1232 SDValue Zero = DAG.getConstant(0, PtrVT);
1233 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1234 Callee.getValueType());
1235
1236 if (!ST->usingLargeMem()) {
Dale Johannesende064702009-02-06 21:50:26 +00001237 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero);
Scott Michel1df30c42008-12-29 03:23:36 +00001238 } else {
Dale Johannesende064702009-02-06 21:50:26 +00001239 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero);
Scott Michel1df30c42008-12-29 03:23:36 +00001240 }
1241 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001242 // If this is an absolute destination address that appears to be a legal
1243 // local store address, use the munged value.
Dan Gohman475871a2008-07-27 21:46:04 +00001244 Callee = SDValue(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001245 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001246
1247 Ops.push_back(Chain);
1248 Ops.push_back(Callee);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001249
Scott Michel266bc8f2007-12-04 22:23:35 +00001250 // Add argument registers to the end of the list so that they are known live
1251 // into the call.
1252 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel5af8f0e2008-07-16 17:17:29 +00001253 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel266bc8f2007-12-04 22:23:35 +00001254 RegsToPass[i].second.getValueType()));
Scott Michel5af8f0e2008-07-16 17:17:29 +00001255
Gabor Greifba36cb52008-08-28 21:40:38 +00001256 if (InFlag.getNode())
Scott Michel266bc8f2007-12-04 22:23:35 +00001257 Ops.push_back(InFlag);
Duncan Sands4bdcb612008-07-02 17:40:58 +00001258 // Returns a chain and a flag for retval copy to use.
Dale Johannesen33c960f2009-02-04 20:06:27 +00001259 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag),
Duncan Sands4bdcb612008-07-02 17:40:58 +00001260 &Ops[0], Ops.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001261 InFlag = Chain.getValue(1);
1262
Chris Lattnere563bbc2008-10-11 22:08:30 +00001263 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1264 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman095cc292008-09-13 01:54:27 +00001265 if (TheCall->getValueType(0) != MVT::Other)
Evan Chengebaaa912008-02-05 22:44:06 +00001266 InFlag = Chain.getValue(1);
1267
Dan Gohman475871a2008-07-27 21:46:04 +00001268 SDValue ResultVals[3];
Scott Michel266bc8f2007-12-04 22:23:35 +00001269 unsigned NumResults = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001270
Scott Michel266bc8f2007-12-04 22:23:35 +00001271 // If the call has results, copy the values out of the ret val registers.
Dan Gohman095cc292008-09-13 01:54:27 +00001272 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001273 default: assert(0 && "Unexpected ret value!");
1274 case MVT::Other: break;
1275 case MVT::i32:
Dan Gohman095cc292008-09-13 01:54:27 +00001276 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel6e1d1472009-03-16 18:47:25 +00001277 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001278 MVT::i32, InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001279 ResultVals[0] = Chain.getValue(0);
Dale Johannesen33c960f2009-02-04 20:06:27 +00001280 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Scott Michel266bc8f2007-12-04 22:23:35 +00001281 Chain.getValue(2)).getValue(1);
1282 ResultVals[1] = Chain.getValue(0);
1283 NumResults = 2;
Scott Michel266bc8f2007-12-04 22:23:35 +00001284 } else {
Scott Michel6e1d1472009-03-16 18:47:25 +00001285 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001286 InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001287 ResultVals[0] = Chain.getValue(0);
1288 NumResults = 1;
1289 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001290 break;
1291 case MVT::i64:
Scott Michel6e1d1472009-03-16 18:47:25 +00001292 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001293 InFlag).getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00001294 ResultVals[0] = Chain.getValue(0);
1295 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001296 break;
Scott Micheldd950092009-01-06 03:36:14 +00001297 case MVT::i128:
Scott Michel6e1d1472009-03-16 18:47:25 +00001298 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128,
Dale Johannesen33c960f2009-02-04 20:06:27 +00001299 InFlag).getValue(1);
Scott Micheldd950092009-01-06 03:36:14 +00001300 ResultVals[0] = Chain.getValue(0);
1301 NumResults = 1;
1302 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00001303 case MVT::f32:
1304 case MVT::f64:
Dale Johannesen33c960f2009-02-04 20:06:27 +00001305 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001306 InFlag).getValue(1);
1307 ResultVals[0] = Chain.getValue(0);
1308 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001309 break;
1310 case MVT::v2f64:
Scott Michelcc188272008-12-04 21:01:44 +00001311 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001312 case MVT::v4f32:
1313 case MVT::v4i32:
1314 case MVT::v8i16:
1315 case MVT::v16i8:
Dale Johannesen33c960f2009-02-04 20:06:27 +00001316 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001317 InFlag).getValue(1);
1318 ResultVals[0] = Chain.getValue(0);
1319 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001320 break;
1321 }
Duncan Sands4bdcb612008-07-02 17:40:58 +00001322
Scott Michel266bc8f2007-12-04 22:23:35 +00001323 // If the function returns void, just return the chain.
1324 if (NumResults == 0)
1325 return Chain;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001326
Scott Michel266bc8f2007-12-04 22:23:35 +00001327 // Otherwise, merge everything together with a MERGE_VALUES node.
1328 ResultVals[NumResults++] = Chain;
Dale Johannesen33c960f2009-02-04 20:06:27 +00001329 SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl);
Gabor Greif99a6cb92008-08-26 22:36:50 +00001330 return Res.getValue(Op.getResNo());
Scott Michel266bc8f2007-12-04 22:23:35 +00001331}
1332
Dan Gohman475871a2008-07-27 21:46:04 +00001333static SDValue
1334LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001335 SmallVector<CCValAssign, 16> RVLocs;
1336 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1337 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
Dale Johannesena05dca42009-02-04 23:02:30 +00001338 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001339 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greifba36cb52008-08-28 21:40:38 +00001340 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001341
Scott Michel266bc8f2007-12-04 22:23:35 +00001342 // If this is the first return lowered for this function, add the regs to the
1343 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001344 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001345 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001346 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001347 }
1348
Dan Gohman475871a2008-07-27 21:46:04 +00001349 SDValue Chain = Op.getOperand(0);
1350 SDValue Flag;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001351
Scott Michel266bc8f2007-12-04 22:23:35 +00001352 // Copy the result values into the output registers.
1353 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1354 CCValAssign &VA = RVLocs[i];
1355 assert(VA.isRegLoc() && "Can only return in registers!");
Dale Johannesena05dca42009-02-04 23:02:30 +00001356 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
1357 Op.getOperand(i*2+1), Flag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001358 Flag = Chain.getValue(1);
1359 }
1360
Gabor Greifba36cb52008-08-28 21:40:38 +00001361 if (Flag.getNode())
Dale Johannesena05dca42009-02-04 23:02:30 +00001362 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
Scott Michel266bc8f2007-12-04 22:23:35 +00001363 else
Dale Johannesena05dca42009-02-04 23:02:30 +00001364 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain);
Scott Michel266bc8f2007-12-04 22:23:35 +00001365}
1366
1367
1368//===----------------------------------------------------------------------===//
1369// Vector related lowering:
1370//===----------------------------------------------------------------------===//
1371
1372static ConstantSDNode *
1373getVecImm(SDNode *N) {
Dan Gohman475871a2008-07-27 21:46:04 +00001374 SDValue OpVal(0, 0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001375
Scott Michel266bc8f2007-12-04 22:23:35 +00001376 // Check to see if this buildvec has a single non-undef value in its elements.
1377 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1378 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greifba36cb52008-08-28 21:40:38 +00001379 if (OpVal.getNode() == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +00001380 OpVal = N->getOperand(i);
1381 else if (OpVal != N->getOperand(i))
1382 return 0;
1383 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001384
Gabor Greifba36cb52008-08-28 21:40:38 +00001385 if (OpVal.getNode() != 0) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001386 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001387 return CN;
1388 }
1389 }
1390
Scott Michel7ea02ff2009-03-17 01:15:45 +00001391 return 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001392}
1393
1394/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1395/// and the value fits into an unsigned 18-bit constant, and if so, return the
1396/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001397SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001398 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001399 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001400 uint64_t Value = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001401 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001402 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001403 uint32_t upper = uint32_t(UValue >> 32);
1404 uint32_t lower = uint32_t(UValue);
1405 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001406 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001407 Value = Value >> 32;
1408 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001409 if (Value <= 0x3ffff)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001410 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001411 }
1412
Dan Gohman475871a2008-07-27 21:46:04 +00001413 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001414}
1415
1416/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1417/// and the value fits into a signed 16-bit constant, and if so, return the
1418/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001419SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001420 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001421 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001422 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001423 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001424 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001425 uint32_t upper = uint32_t(UValue >> 32);
1426 uint32_t lower = uint32_t(UValue);
1427 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001428 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001429 Value = Value >> 32;
1430 }
Scott Michelad2715e2008-03-05 23:02:02 +00001431 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001432 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001433 }
1434 }
1435
Dan Gohman475871a2008-07-27 21:46:04 +00001436 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001437}
1438
1439/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1440/// and the value fits into a signed 10-bit constant, and if so, return the
1441/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001442SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001443 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001444 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001445 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001446 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001447 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001448 uint32_t upper = uint32_t(UValue >> 32);
1449 uint32_t lower = uint32_t(UValue);
1450 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001451 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001452 Value = Value >> 32;
1453 }
Scott Michelad2715e2008-03-05 23:02:02 +00001454 if (isS10Constant(Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001455 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001456 }
1457
Dan Gohman475871a2008-07-27 21:46:04 +00001458 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001459}
1460
1461/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1462/// and the value fits into a signed 8-bit constant, and if so, return the
1463/// constant.
1464///
1465/// @note: The incoming vector is v16i8 because that's the only way we can load
1466/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1467/// same value.
Dan Gohman475871a2008-07-27 21:46:04 +00001468SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001469 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001470 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001471 int Value = (int) CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001472 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001473 && Value <= 0xffff /* truncated from uint64_t */
1474 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001475 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001476 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001477 && (Value & 0xff) == Value)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001478 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001479 }
1480
Dan Gohman475871a2008-07-27 21:46:04 +00001481 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001482}
1483
1484/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1485/// and the value fits into a signed 16-bit constant, and if so, return the
1486/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001487SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001488 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001489 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001490 uint64_t Value = CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001491 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001492 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1493 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001494 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001495 }
1496
Dan Gohman475871a2008-07-27 21:46:04 +00001497 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001498}
1499
1500/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001501SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001502 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001503 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001504 }
1505
Dan Gohman475871a2008-07-27 21:46:04 +00001506 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001507}
1508
1509/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001510SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001511 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001512 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001513 }
1514
Dan Gohman475871a2008-07-27 21:46:04 +00001515 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001516}
1517
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001518//! Lower a BUILD_VECTOR instruction creatively:
1519SDValue
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001520LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001521 MVT VT = Op.getValueType();
Scott Michel7ea02ff2009-03-17 01:15:45 +00001522 MVT EltVT = VT.getVectorElementType();
Dale Johannesened2eee62009-02-06 01:31:28 +00001523 DebugLoc dl = Op.getDebugLoc();
Scott Michel7ea02ff2009-03-17 01:15:45 +00001524 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(Op.getNode());
1525 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerBUILD_VECTOR");
1526 unsigned minSplatBits = EltVT.getSizeInBits();
1527
1528 if (minSplatBits < 16)
1529 minSplatBits = 16;
1530
1531 APInt APSplatBits, APSplatUndef;
1532 unsigned SplatBitSize;
1533 bool HasAnyUndefs;
1534
1535 if (!BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
1536 HasAnyUndefs, minSplatBits)
1537 || minSplatBits < SplatBitSize)
1538 return SDValue(); // Wasn't a constant vector or splat exceeded min
1539
1540 uint64_t SplatBits = APSplatBits.getZExtValue();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001541
Duncan Sands83ec4b62008-06-06 12:08:01 +00001542 switch (VT.getSimpleVT()) {
Torok Edwindac237e2009-07-08 20:53:28 +00001543 default: {
1544 std::string msg;
1545 raw_string_ostream Msg(msg);
1546 Msg << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
1547 << VT.getMVTString();
1548 llvm_report_error(Msg.str());
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001549 /*NOTREACHED*/
Torok Edwindac237e2009-07-08 20:53:28 +00001550 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001551 case MVT::v4f32: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001552 uint32_t Value32 = uint32_t(SplatBits);
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001553 assert(SplatBitSize == 32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001554 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001555 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001556 SDValue T = DAG.getConstant(Value32, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001557 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4f32,
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001558 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001559 break;
1560 }
1561 case MVT::v2f64: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001562 uint64_t f64val = uint64_t(SplatBits);
Chris Lattnere7fa1f22009-03-26 05:29:34 +00001563 assert(SplatBitSize == 64
Scott Michel104de432008-11-24 17:11:17 +00001564 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001565 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001566 SDValue T = DAG.getConstant(f64val, MVT::i64);
Dale Johannesened2eee62009-02-06 01:31:28 +00001567 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64,
Evan Chenga87008d2009-02-25 22:49:59 +00001568 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001569 break;
1570 }
1571 case MVT::v16i8: {
1572 // 8-bit constants have to be expanded to 16-bits
Scott Michel7ea02ff2009-03-17 01:15:45 +00001573 unsigned short Value16 = SplatBits /* | (SplatBits << 8) */;
1574 SmallVector<SDValue, 8> Ops;
1575
1576 Ops.assign(8, DAG.getConstant(Value16, MVT::i16));
Dale Johannesened2eee62009-02-06 01:31:28 +00001577 return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
Scott Michel7ea02ff2009-03-17 01:15:45 +00001578 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001579 }
1580 case MVT::v8i16: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001581 unsigned short Value16 = SplatBits;
1582 SDValue T = DAG.getConstant(Value16, EltVT);
1583 SmallVector<SDValue, 8> Ops;
1584
1585 Ops.assign(8, T);
1586 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001587 }
1588 case MVT::v4i32: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001589 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga87008d2009-02-25 22:49:59 +00001590 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
Scott Michel266bc8f2007-12-04 22:23:35 +00001591 }
Scott Michel21213e72009-01-06 23:10:38 +00001592 case MVT::v2i32: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001593 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga87008d2009-02-25 22:49:59 +00001594 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T);
Scott Michel21213e72009-01-06 23:10:38 +00001595 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001596 case MVT::v2i64: {
Scott Michel7ea02ff2009-03-17 01:15:45 +00001597 return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
Scott Michel266bc8f2007-12-04 22:23:35 +00001598 }
1599 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001600
Dan Gohman475871a2008-07-27 21:46:04 +00001601 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001602}
1603
Scott Michel7ea02ff2009-03-17 01:15:45 +00001604/*!
1605 */
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001606SDValue
Scott Michel7ea02ff2009-03-17 01:15:45 +00001607SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal,
1608 DebugLoc dl) {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001609 uint32_t upper = uint32_t(SplatVal >> 32);
1610 uint32_t lower = uint32_t(SplatVal);
1611
1612 if (upper == lower) {
1613 // Magic constant that can be matched by IL, ILA, et. al.
1614 SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001615 return DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001616 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1617 Val, Val, Val, Val));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001618 } else {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001619 bool upper_special, lower_special;
1620
1621 // NOTE: This code creates common-case shuffle masks that can be easily
1622 // detected as common expressions. It is not attempting to create highly
1623 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1624
1625 // Detect if the upper or lower half is a special shuffle mask pattern:
1626 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1627 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1628
Scott Michel7ea02ff2009-03-17 01:15:45 +00001629 // Both upper and lower are special, lower to a constant pool load:
1630 if (lower_special && upper_special) {
1631 SDValue SplatValCN = DAG.getConstant(SplatVal, MVT::i64);
1632 return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
1633 SplatValCN, SplatValCN);
1634 }
1635
1636 SDValue LO32;
1637 SDValue HI32;
1638 SmallVector<SDValue, 16> ShufBytes;
1639 SDValue Result;
1640
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001641 // Create lower vector if not a special pattern
1642 if (!lower_special) {
1643 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001644 LO32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001645 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1646 LO32C, LO32C, LO32C, LO32C));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001647 }
1648
1649 // Create upper vector if not a special pattern
1650 if (!upper_special) {
1651 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
Dale Johannesened2eee62009-02-06 01:31:28 +00001652 HI32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga87008d2009-02-25 22:49:59 +00001653 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1654 HI32C, HI32C, HI32C, HI32C));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001655 }
1656
1657 // If either upper or lower are special, then the two input operands are
1658 // the same (basically, one of them is a "don't care")
1659 if (lower_special)
1660 LO32 = HI32;
1661 if (upper_special)
1662 HI32 = LO32;
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001663
1664 for (int i = 0; i < 4; ++i) {
1665 uint64_t val = 0;
1666 for (int j = 0; j < 4; ++j) {
1667 SDValue V;
1668 bool process_upper, process_lower;
1669 val <<= 8;
1670 process_upper = (upper_special && (i & 1) == 0);
1671 process_lower = (lower_special && (i & 1) == 1);
1672
1673 if (process_upper || process_lower) {
1674 if ((process_upper && upper == 0)
1675 || (process_lower && lower == 0))
1676 val |= 0x80;
1677 else if ((process_upper && upper == 0xffffffff)
1678 || (process_lower && lower == 0xffffffff))
1679 val |= 0xc0;
1680 else if ((process_upper && upper == 0x80000000)
1681 || (process_lower && lower == 0x80000000))
1682 val |= (j == 0 ? 0xe0 : 0x80);
1683 } else
1684 val |= i * 4 + j + ((i & 1) * 16);
1685 }
1686
1687 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
1688 }
1689
Dale Johannesened2eee62009-02-06 01:31:28 +00001690 return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32,
Evan Chenga87008d2009-02-25 22:49:59 +00001691 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1692 &ShufBytes[0], ShufBytes.size()));
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001693 }
1694}
1695
Scott Michel266bc8f2007-12-04 22:23:35 +00001696/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1697/// which the Cell can operate. The code inspects V3 to ascertain whether the
1698/// permutation vector, V3, is monotonically increasing with one "exception"
1699/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel7a1c9e92008-11-22 23:50:42 +00001700/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel266bc8f2007-12-04 22:23:35 +00001701/// In either case, the net result is going to eventually invoke SHUFB to
1702/// permute/shuffle the bytes from V1 and V2.
1703/// \note
Scott Michel7a1c9e92008-11-22 23:50:42 +00001704/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel266bc8f2007-12-04 22:23:35 +00001705/// control word for byte/halfword/word insertion. This takes care of a single
1706/// element move from V2 into V1.
1707/// \note
1708/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman475871a2008-07-27 21:46:04 +00001709static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
Nate Begeman9008ca62009-04-27 18:41:29 +00001710 const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +00001711 SDValue V1 = Op.getOperand(0);
1712 SDValue V2 = Op.getOperand(1);
Dale Johannesena05dca42009-02-04 23:02:30 +00001713 DebugLoc dl = Op.getDebugLoc();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001714
Scott Michel266bc8f2007-12-04 22:23:35 +00001715 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001716
Scott Michel266bc8f2007-12-04 22:23:35 +00001717 // If we have a single element being moved from V1 to V2, this can be handled
1718 // using the C*[DX] compute mask instructions, but the vector elements have
1719 // to be monotonically increasing with one exception element.
Scott Michelcc188272008-12-04 21:01:44 +00001720 MVT VecVT = V1.getValueType();
1721 MVT EltVT = VecVT.getVectorElementType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001722 unsigned EltsFromV2 = 0;
1723 unsigned V2Elt = 0;
1724 unsigned V2EltIdx0 = 0;
1725 unsigned CurrElt = 0;
Scott Michelcc188272008-12-04 21:01:44 +00001726 unsigned MaxElts = VecVT.getVectorNumElements();
1727 unsigned PrevElt = 0;
1728 unsigned V0Elt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001729 bool monotonic = true;
Scott Michelcc188272008-12-04 21:01:44 +00001730 bool rotate = true;
1731
1732 if (EltVT == MVT::i8) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001733 V2EltIdx0 = 16;
Scott Michelcc188272008-12-04 21:01:44 +00001734 } else if (EltVT == MVT::i16) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001735 V2EltIdx0 = 8;
Scott Michelcc188272008-12-04 21:01:44 +00001736 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001737 V2EltIdx0 = 4;
Scott Michelcc188272008-12-04 21:01:44 +00001738 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1739 V2EltIdx0 = 2;
1740 } else
Scott Michel266bc8f2007-12-04 22:23:35 +00001741 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1742
Nate Begeman9008ca62009-04-27 18:41:29 +00001743 for (unsigned i = 0; i != MaxElts; ++i) {
1744 if (SVN->getMaskElt(i) < 0)
1745 continue;
1746
1747 unsigned SrcElt = SVN->getMaskElt(i);
Scott Michel266bc8f2007-12-04 22:23:35 +00001748
Nate Begeman9008ca62009-04-27 18:41:29 +00001749 if (monotonic) {
1750 if (SrcElt >= V2EltIdx0) {
1751 if (1 >= (++EltsFromV2)) {
1752 V2Elt = (V2EltIdx0 - SrcElt) << 2;
Scott Michelcc188272008-12-04 21:01:44 +00001753 }
Nate Begeman9008ca62009-04-27 18:41:29 +00001754 } else if (CurrElt != SrcElt) {
1755 monotonic = false;
Scott Michelcc188272008-12-04 21:01:44 +00001756 }
1757
Nate Begeman9008ca62009-04-27 18:41:29 +00001758 ++CurrElt;
1759 }
1760
1761 if (rotate) {
1762 if (PrevElt > 0 && SrcElt < MaxElts) {
1763 if ((PrevElt == SrcElt - 1)
1764 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
Scott Michelcc188272008-12-04 21:01:44 +00001765 PrevElt = SrcElt;
Nate Begeman9008ca62009-04-27 18:41:29 +00001766 if (SrcElt == 0)
1767 V0Elt = i;
Scott Michelcc188272008-12-04 21:01:44 +00001768 } else {
Scott Michelcc188272008-12-04 21:01:44 +00001769 rotate = false;
1770 }
Nate Begeman9008ca62009-04-27 18:41:29 +00001771 } else if (PrevElt == 0) {
1772 // First time through, need to keep track of previous element
1773 PrevElt = SrcElt;
1774 } else {
1775 // This isn't a rotation, takes elements from vector 2
1776 rotate = false;
Scott Michelcc188272008-12-04 21:01:44 +00001777 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001778 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001779 }
1780
1781 if (EltsFromV2 == 1 && monotonic) {
1782 // Compute mask and shuffle
1783 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001784 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1785 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands83ec4b62008-06-06 12:08:01 +00001786 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001787 // Initialize temporary register to 0
Dan Gohman475871a2008-07-27 21:46:04 +00001788 SDValue InitTempReg =
Dale Johannesena05dca42009-02-04 23:02:30 +00001789 DAG.getCopyToReg(DAG.getEntryNode(), dl, VReg, DAG.getConstant(0, PtrVT));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001790 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman475871a2008-07-27 21:46:04 +00001791 SDValue ShufMaskOp =
Dale Johannesena05dca42009-02-04 23:02:30 +00001792 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001793 DAG.getTargetConstant(V2Elt, MVT::i32),
Dale Johannesena05dca42009-02-04 23:02:30 +00001794 DAG.getCopyFromReg(InitTempReg, dl, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001795 // Use shuffle mask in SHUFB synthetic instruction:
Scott Michel6e1d1472009-03-16 18:47:25 +00001796 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1,
Dale Johannesena05dca42009-02-04 23:02:30 +00001797 ShufMaskOp);
Scott Michelcc188272008-12-04 21:01:44 +00001798 } else if (rotate) {
1799 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michel1df30c42008-12-29 03:23:36 +00001800
Dale Johannesena05dca42009-02-04 23:02:30 +00001801 return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(),
Scott Michelcc188272008-12-04 21:01:44 +00001802 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001803 } else {
Gabor Greif93c53e52008-08-31 15:37:04 +00001804 // Convert the SHUFFLE_VECTOR mask's input element units to the
1805 // actual bytes.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001806 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001807
Dan Gohman475871a2008-07-27 21:46:04 +00001808 SmallVector<SDValue, 16> ResultMask;
Nate Begeman9008ca62009-04-27 18:41:29 +00001809 for (unsigned i = 0, e = MaxElts; i != e; ++i) {
1810 unsigned SrcElt = SVN->getMaskElt(i) < 0 ? 0 : SVN->getMaskElt(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001811
Nate Begeman9008ca62009-04-27 18:41:29 +00001812 for (unsigned j = 0; j < BytesPerElement; ++j)
1813 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001814 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001815
Evan Chenga87008d2009-02-25 22:49:59 +00001816 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
1817 &ResultMask[0], ResultMask.size());
Dale Johannesena05dca42009-02-04 23:02:30 +00001818 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
Scott Michel266bc8f2007-12-04 22:23:35 +00001819 }
1820}
1821
Dan Gohman475871a2008-07-27 21:46:04 +00001822static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1823 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Dale Johannesened2eee62009-02-06 01:31:28 +00001824 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00001825
Gabor Greifba36cb52008-08-28 21:40:38 +00001826 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001827 // For a constant, build the appropriate constant vector, which will
1828 // eventually simplify to a vector register load.
1829
Gabor Greifba36cb52008-08-28 21:40:38 +00001830 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman475871a2008-07-27 21:46:04 +00001831 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001832 MVT VT;
Scott Michel266bc8f2007-12-04 22:23:35 +00001833 size_t n_copies;
1834
1835 // Create a constant vector:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001836 switch (Op.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001837 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001838 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001839 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1840 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1841 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1842 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1843 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1844 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1845 }
1846
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001847 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001848 for (size_t j = 0; j < n_copies; ++j)
1849 ConstVecValues.push_back(CValue);
1850
Evan Chenga87008d2009-02-25 22:49:59 +00001851 return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(),
1852 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001853 } else {
1854 // Otherwise, copy the value from one register to another:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001855 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001856 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1857 case MVT::i8:
1858 case MVT::i16:
1859 case MVT::i32:
1860 case MVT::i64:
1861 case MVT::f32:
1862 case MVT::f64:
Dale Johannesened2eee62009-02-06 01:31:28 +00001863 return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001864 }
1865 }
1866
Dan Gohman475871a2008-07-27 21:46:04 +00001867 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001868}
1869
Dan Gohman475871a2008-07-27 21:46:04 +00001870static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001871 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001872 SDValue N = Op.getOperand(0);
1873 SDValue Elt = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00001874 DebugLoc dl = Op.getDebugLoc();
Scott Michel7a1c9e92008-11-22 23:50:42 +00001875 SDValue retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00001876
Scott Michel7a1c9e92008-11-22 23:50:42 +00001877 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1878 // Constant argument:
1879 int EltNo = (int) C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001880
Scott Michel7a1c9e92008-11-22 23:50:42 +00001881 // sanity checks:
1882 if (VT == MVT::i8 && EltNo >= 16)
1883 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1884 else if (VT == MVT::i16 && EltNo >= 8)
1885 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1886 else if (VT == MVT::i32 && EltNo >= 4)
1887 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1888 else if (VT == MVT::i64 && EltNo >= 2)
1889 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel266bc8f2007-12-04 22:23:35 +00001890
Scott Michel7a1c9e92008-11-22 23:50:42 +00001891 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1892 // i32 and i64: Element 0 is the preferred slot
Dale Johannesened2eee62009-02-06 01:31:28 +00001893 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001894 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001895
Scott Michel7a1c9e92008-11-22 23:50:42 +00001896 // Need to generate shuffle mask and extract:
1897 int prefslot_begin = -1, prefslot_end = -1;
1898 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1899
1900 switch (VT.getSimpleVT()) {
1901 default:
1902 assert(false && "Invalid value type!");
1903 case MVT::i8: {
1904 prefslot_begin = prefslot_end = 3;
1905 break;
1906 }
1907 case MVT::i16: {
1908 prefslot_begin = 2; prefslot_end = 3;
1909 break;
1910 }
1911 case MVT::i32:
1912 case MVT::f32: {
1913 prefslot_begin = 0; prefslot_end = 3;
1914 break;
1915 }
1916 case MVT::i64:
1917 case MVT::f64: {
1918 prefslot_begin = 0; prefslot_end = 7;
1919 break;
1920 }
1921 }
1922
1923 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1924 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1925
1926 unsigned int ShufBytes[16];
1927 for (int i = 0; i < 16; ++i) {
1928 // zero fill uppper part of preferred slot, don't care about the
1929 // other slots:
1930 unsigned int mask_val;
1931 if (i <= prefslot_end) {
1932 mask_val =
1933 ((i < prefslot_begin)
1934 ? 0x80
1935 : elt_byte + (i - prefslot_begin));
1936
1937 ShufBytes[i] = mask_val;
1938 } else
1939 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1940 }
1941
1942 SDValue ShufMask[4];
1943 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michelcc188272008-12-04 21:01:44 +00001944 unsigned bidx = i * 4;
Scott Michel7a1c9e92008-11-22 23:50:42 +00001945 unsigned int bits = ((ShufBytes[bidx] << 24) |
1946 (ShufBytes[bidx+1] << 16) |
1947 (ShufBytes[bidx+2] << 8) |
1948 ShufBytes[bidx+3]);
1949 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1950 }
1951
Scott Michel7ea02ff2009-03-17 01:15:45 +00001952 SDValue ShufMaskVec =
1953 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1954 &ShufMask[0], sizeof(ShufMask)/sizeof(ShufMask[0]));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001955
Dale Johannesened2eee62009-02-06 01:31:28 +00001956 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
1957 DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(),
Scott Michel7a1c9e92008-11-22 23:50:42 +00001958 N, N, ShufMaskVec));
1959 } else {
1960 // Variable index: Rotate the requested element into slot 0, then replicate
1961 // slot 0 across the vector
1962 MVT VecVT = N.getValueType();
1963 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
Torok Edwindac237e2009-07-08 20:53:28 +00001964 llvm_report_error("LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit"
1965 "vector type!");
Scott Michel7a1c9e92008-11-22 23:50:42 +00001966 }
1967
1968 // Make life easier by making sure the index is zero-extended to i32
1969 if (Elt.getValueType() != MVT::i32)
Dale Johannesened2eee62009-02-06 01:31:28 +00001970 Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001971
1972 // Scale the index to a bit/byte shift quantity
1973 APInt scaleFactor =
Scott Michel104de432008-11-24 17:11:17 +00001974 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1975 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel7a1c9e92008-11-22 23:50:42 +00001976 SDValue vecShift;
Scott Michel7a1c9e92008-11-22 23:50:42 +00001977
Scott Michel104de432008-11-24 17:11:17 +00001978 if (scaleShift > 0) {
1979 // Scale the shift factor:
Dale Johannesened2eee62009-02-06 01:31:28 +00001980 Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt,
Scott Michel1a6cdb62008-12-01 17:56:02 +00001981 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001982 }
1983
Dale Johannesened2eee62009-02-06 01:31:28 +00001984 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, dl, VecVT, N, Elt);
Scott Michel104de432008-11-24 17:11:17 +00001985
1986 // Replicate the bytes starting at byte 0 across the entire vector (for
1987 // consistency with the notion of a unified register set)
Scott Michel7a1c9e92008-11-22 23:50:42 +00001988 SDValue replicate;
1989
1990 switch (VT.getSimpleVT()) {
1991 default:
Torok Edwindac237e2009-07-08 20:53:28 +00001992 llvm_report_error("LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector"
1993 "type");
Scott Michel7a1c9e92008-11-22 23:50:42 +00001994 /*NOTREACHED*/
1995 case MVT::i8: {
Scott Michel104de432008-11-24 17:11:17 +00001996 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00001997 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1998 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001999 break;
2000 }
2001 case MVT::i16: {
Scott Michel104de432008-11-24 17:11:17 +00002002 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002003 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2004 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002005 break;
2006 }
2007 case MVT::i32:
2008 case MVT::f32: {
2009 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002010 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2011 factor, factor, factor, factor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002012 break;
2013 }
2014 case MVT::i64:
2015 case MVT::f64: {
2016 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2017 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002018 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
Evan Chenga87008d2009-02-25 22:49:59 +00002019 loFactor, hiFactor, loFactor, hiFactor);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002020 break;
2021 }
2022 }
2023
Dale Johannesened2eee62009-02-06 01:31:28 +00002024 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
2025 DAG.getNode(SPUISD::SHUFB, dl, VecVT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002026 vecShift, vecShift, replicate));
Scott Michel266bc8f2007-12-04 22:23:35 +00002027 }
2028
Scott Michel7a1c9e92008-11-22 23:50:42 +00002029 return retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00002030}
2031
Dan Gohman475871a2008-07-27 21:46:04 +00002032static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2033 SDValue VecOp = Op.getOperand(0);
2034 SDValue ValOp = Op.getOperand(1);
2035 SDValue IdxOp = Op.getOperand(2);
Dale Johannesened2eee62009-02-06 01:31:28 +00002036 DebugLoc dl = Op.getDebugLoc();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002037 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002038
2039 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2040 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2041
Duncan Sands83ec4b62008-06-06 12:08:01 +00002042 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel1a6cdb62008-12-01 17:56:02 +00002043 // Use $sp ($1) because it's always 16-byte aligned and it's available:
Dale Johannesened2eee62009-02-06 01:31:28 +00002044 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002045 DAG.getRegister(SPU::R1, PtrVT),
2046 DAG.getConstant(CN->getSExtValue(), PtrVT));
Dale Johannesened2eee62009-02-06 01:31:28 +00002047 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, VT, Pointer);
Scott Michel266bc8f2007-12-04 22:23:35 +00002048
Dan Gohman475871a2008-07-27 21:46:04 +00002049 SDValue result =
Dale Johannesened2eee62009-02-06 01:31:28 +00002050 DAG.getNode(SPUISD::SHUFB, dl, VT,
2051 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp),
Scott Michel1df30c42008-12-29 03:23:36 +00002052 VecOp,
Dale Johannesened2eee62009-02-06 01:31:28 +00002053 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, ShufMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00002054
2055 return result;
2056}
2057
Scott Michelf0569be2008-12-27 04:51:36 +00002058static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2059 const TargetLowering &TLI)
Scott Michela59d4692008-02-23 18:41:37 +00002060{
Dan Gohman475871a2008-07-27 21:46:04 +00002061 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Dale Johannesened2eee62009-02-06 01:31:28 +00002062 DebugLoc dl = Op.getDebugLoc();
Scott Michelf0569be2008-12-27 04:51:36 +00002063 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00002064
2065 assert(Op.getValueType() == MVT::i8);
2066 switch (Opc) {
2067 default:
2068 assert(0 && "Unhandled i8 math operator");
2069 /*NOTREACHED*/
2070 break;
Scott Michel02d711b2008-12-30 23:28:25 +00002071 case ISD::ADD: {
2072 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2073 // the result:
2074 SDValue N1 = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002075 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2076 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2077 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2078 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel02d711b2008-12-30 23:28:25 +00002079
2080 }
2081
Scott Michel266bc8f2007-12-04 22:23:35 +00002082 case ISD::SUB: {
2083 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2084 // the result:
Dan Gohman475871a2008-07-27 21:46:04 +00002085 SDValue N1 = Op.getOperand(1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002086 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2087 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
2088 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2089 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002090 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002091 case ISD::ROTR:
2092 case ISD::ROTL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002093 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002094 MVT N1VT = N1.getValueType();
2095
2096 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2097 if (!N1VT.bitsEq(ShiftVT)) {
2098 unsigned N1Opc = N1.getValueType().bitsLT(ShiftVT)
2099 ? ISD::ZERO_EXTEND
2100 : ISD::TRUNCATE;
2101 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2102 }
2103
2104 // Replicate lower 8-bits into upper 8:
Dan Gohman475871a2008-07-27 21:46:04 +00002105 SDValue ExpandArg =
Dale Johannesened2eee62009-02-06 01:31:28 +00002106 DAG.getNode(ISD::OR, dl, MVT::i16, N0,
2107 DAG.getNode(ISD::SHL, dl, MVT::i16,
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002108 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel7ea02ff2009-03-17 01:15:45 +00002109
2110 // Truncate back down to i8
Dale Johannesened2eee62009-02-06 01:31:28 +00002111 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2112 DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002113 }
2114 case ISD::SRL:
2115 case ISD::SHL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002116 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002117 MVT N1VT = N1.getValueType();
2118
2119 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i16, N0);
2120 if (!N1VT.bitsEq(ShiftVT)) {
2121 unsigned N1Opc = ISD::ZERO_EXTEND;
2122
2123 if (N1.getValueType().bitsGT(ShiftVT))
2124 N1Opc = ISD::TRUNCATE;
2125
2126 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2127 }
2128
Dale Johannesened2eee62009-02-06 01:31:28 +00002129 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2130 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002131 }
2132 case ISD::SRA: {
Dan Gohman475871a2008-07-27 21:46:04 +00002133 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002134 MVT N1VT = N1.getValueType();
2135
2136 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2137 if (!N1VT.bitsEq(ShiftVT)) {
2138 unsigned N1Opc = ISD::SIGN_EXTEND;
2139
2140 if (N1VT.bitsGT(ShiftVT))
2141 N1Opc = ISD::TRUNCATE;
2142 N1 = DAG.getNode(N1Opc, dl, ShiftVT, N1);
2143 }
2144
Dale Johannesened2eee62009-02-06 01:31:28 +00002145 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2146 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002147 }
2148 case ISD::MUL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002149 SDValue N1 = Op.getOperand(1);
Scott Michel7ea02ff2009-03-17 01:15:45 +00002150
2151 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N0);
2152 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i16, N1);
Dale Johannesened2eee62009-02-06 01:31:28 +00002153 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2154 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel266bc8f2007-12-04 22:23:35 +00002155 break;
2156 }
2157 }
2158
Dan Gohman475871a2008-07-27 21:46:04 +00002159 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002160}
2161
2162//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman475871a2008-07-27 21:46:04 +00002163static SDValue
2164LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2165 SDValue ConstVec;
2166 SDValue Arg;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002167 MVT VT = Op.getValueType();
Dale Johannesened2eee62009-02-06 01:31:28 +00002168 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002169
2170 ConstVec = Op.getOperand(0);
2171 Arg = Op.getOperand(1);
Gabor Greifba36cb52008-08-28 21:40:38 +00002172 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2173 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002174 ConstVec = ConstVec.getOperand(0);
2175 } else {
2176 ConstVec = Op.getOperand(1);
2177 Arg = Op.getOperand(0);
Gabor Greifba36cb52008-08-28 21:40:38 +00002178 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002179 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002180 }
2181 }
2182 }
2183
Gabor Greifba36cb52008-08-28 21:40:38 +00002184 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel7ea02ff2009-03-17 01:15:45 +00002185 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode());
2186 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed");
Scott Michel266bc8f2007-12-04 22:23:35 +00002187
Scott Michel7ea02ff2009-03-17 01:15:45 +00002188 APInt APSplatBits, APSplatUndef;
2189 unsigned SplatBitSize;
2190 bool HasAnyUndefs;
2191 unsigned minSplatBits = VT.getVectorElementType().getSizeInBits();
2192
2193 if (BCN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
2194 HasAnyUndefs, minSplatBits)
2195 && minSplatBits <= SplatBitSize) {
2196 uint64_t SplatBits = APSplatBits.getZExtValue();
Dan Gohman475871a2008-07-27 21:46:04 +00002197 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002198
Scott Michel7ea02ff2009-03-17 01:15:45 +00002199 SmallVector<SDValue, 16> tcVec;
2200 tcVec.assign(16, tc);
Dale Johannesened2eee62009-02-06 01:31:28 +00002201 return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg,
Scott Michel7ea02ff2009-03-17 01:15:45 +00002202 DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size()));
Scott Michel266bc8f2007-12-04 22:23:35 +00002203 }
2204 }
Scott Michel9de57a92009-01-26 22:33:37 +00002205
Nate Begeman24dc3462008-07-29 19:07:27 +00002206 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2207 // lowered. Return the operation, rather than a null SDValue.
2208 return Op;
Scott Michel266bc8f2007-12-04 22:23:35 +00002209}
2210
Scott Michel266bc8f2007-12-04 22:23:35 +00002211//! Custom lowering for CTPOP (count population)
2212/*!
2213 Custom lowering code that counts the number ones in the input
2214 operand. SPU has such an instruction, but it counts the number of
2215 ones per byte, which then have to be accumulated.
2216*/
Dan Gohman475871a2008-07-27 21:46:04 +00002217static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002218 MVT VT = Op.getValueType();
2219 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesena05dca42009-02-04 23:02:30 +00002220 DebugLoc dl = Op.getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002221
Duncan Sands83ec4b62008-06-06 12:08:01 +00002222 switch (VT.getSimpleVT()) {
2223 default:
2224 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002225 case MVT::i8: {
Dan Gohman475871a2008-07-27 21:46:04 +00002226 SDValue N = Op.getOperand(0);
2227 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002228
Dale Johannesena05dca42009-02-04 23:02:30 +00002229 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2230 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002231
Dale Johannesena05dca42009-02-04 23:02:30 +00002232 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002233 }
2234
2235 case MVT::i16: {
2236 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002237 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002238
Chris Lattner84bc5422007-12-31 04:13:23 +00002239 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002240
Dan Gohman475871a2008-07-27 21:46:04 +00002241 SDValue N = Op.getOperand(0);
2242 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2243 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002244 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002245
Dale Johannesena05dca42009-02-04 23:02:30 +00002246 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2247 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002248
2249 // CNTB_result becomes the chain to which all of the virtual registers
2250 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002251 SDValue CNTB_result =
Dale Johannesena05dca42009-02-04 23:02:30 +00002252 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002253
Dan Gohman475871a2008-07-27 21:46:04 +00002254 SDValue CNTB_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002255 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel266bc8f2007-12-04 22:23:35 +00002256
Dale Johannesena05dca42009-02-04 23:02:30 +00002257 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002258
Dale Johannesena05dca42009-02-04 23:02:30 +00002259 return DAG.getNode(ISD::AND, dl, MVT::i16,
2260 DAG.getNode(ISD::ADD, dl, MVT::i16,
2261 DAG.getNode(ISD::SRL, dl, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002262 Tmp1, Shift1),
2263 Tmp1),
2264 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002265 }
2266
2267 case MVT::i32: {
2268 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002269 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002270
Chris Lattner84bc5422007-12-31 04:13:23 +00002271 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2272 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002273
Dan Gohman475871a2008-07-27 21:46:04 +00002274 SDValue N = Op.getOperand(0);
2275 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2276 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2277 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2278 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002279
Dale Johannesena05dca42009-02-04 23:02:30 +00002280 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, dl, vecVT, N, N);
2281 SDValue CNTB = DAG.getNode(SPUISD::CNTB, dl, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002282
2283 // CNTB_result becomes the chain to which all of the virtual registers
2284 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002285 SDValue CNTB_result =
Dale Johannesena05dca42009-02-04 23:02:30 +00002286 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002287
Dan Gohman475871a2008-07-27 21:46:04 +00002288 SDValue CNTB_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002289 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel266bc8f2007-12-04 22:23:35 +00002290
Dan Gohman475871a2008-07-27 21:46:04 +00002291 SDValue Comp1 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002292 DAG.getNode(ISD::SRL, dl, MVT::i32,
Scott Michel6e1d1472009-03-16 18:47:25 +00002293 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32),
Dale Johannesena05dca42009-02-04 23:02:30 +00002294 Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002295
Dan Gohman475871a2008-07-27 21:46:04 +00002296 SDValue Sum1 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002297 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp1,
2298 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002299
Dan Gohman475871a2008-07-27 21:46:04 +00002300 SDValue Sum1_rescopy =
Dale Johannesena05dca42009-02-04 23:02:30 +00002301 DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002302
Dan Gohman475871a2008-07-27 21:46:04 +00002303 SDValue Comp2 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002304 DAG.getNode(ISD::SRL, dl, MVT::i32,
2305 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002306 Shift2);
Dan Gohman475871a2008-07-27 21:46:04 +00002307 SDValue Sum2 =
Dale Johannesena05dca42009-02-04 23:02:30 +00002308 DAG.getNode(ISD::ADD, dl, MVT::i32, Comp2,
2309 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002310
Dale Johannesena05dca42009-02-04 23:02:30 +00002311 return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002312 }
2313
2314 case MVT::i64:
2315 break;
2316 }
2317
Dan Gohman475871a2008-07-27 21:46:04 +00002318 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002319}
2320
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002321//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002322/*!
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002323 f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
2324 All conversions to i64 are expanded to a libcall.
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002325 */
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002326static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2327 SPUTargetLowering &TLI) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002328 MVT OpVT = Op.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002329 SDValue Op0 = Op.getOperand(0);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002330 MVT Op0VT = Op0.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002331
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002332 if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
2333 || OpVT == MVT::i64) {
2334 // Convert f32 / f64 to i32 / i64 via libcall.
2335 RTLIB::Libcall LC =
2336 (Op.getOpcode() == ISD::FP_TO_SINT)
2337 ? RTLIB::getFPTOSINT(Op0VT, OpVT)
2338 : RTLIB::getFPTOUINT(Op0VT, OpVT);
2339 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
2340 SDValue Dummy;
2341 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2342 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002343
Eli Friedman36df4992009-05-27 00:47:34 +00002344 return Op;
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002345}
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002346
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002347//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
2348/*!
2349 i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
2350 All conversions from i64 are expanded to a libcall.
2351 */
2352static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
2353 SPUTargetLowering &TLI) {
2354 MVT OpVT = Op.getValueType();
2355 SDValue Op0 = Op.getOperand(0);
2356 MVT Op0VT = Op0.getValueType();
2357
2358 if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
2359 || Op0VT == MVT::i64) {
2360 // Convert i32, i64 to f64 via libcall:
2361 RTLIB::Libcall LC =
2362 (Op.getOpcode() == ISD::SINT_TO_FP)
2363 ? RTLIB::getSINTTOFP(Op0VT, OpVT)
2364 : RTLIB::getUINTTOFP(Op0VT, OpVT);
2365 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
2366 SDValue Dummy;
2367 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2368 }
2369
Eli Friedman36df4992009-05-27 00:47:34 +00002370 return Op;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002371}
2372
2373//! Lower ISD::SETCC
2374/*!
2375 This handles MVT::f64 (double floating point) condition lowering
2376 */
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002377static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2378 const TargetLowering &TLI) {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002379 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen6f38cb62009-02-07 19:59:05 +00002380 DebugLoc dl = Op.getDebugLoc();
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002381 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2382
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002383 SDValue lhs = Op.getOperand(0);
2384 SDValue rhs = Op.getOperand(1);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002385 MVT lhsVT = lhs.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002386 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2387
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002388 MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
2389 APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2390 MVT IntVT(MVT::i64);
2391
2392 // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
2393 // selected to a NOP:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002394 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002395 SDValue lhsHi32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002396 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2397 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002398 i64lhs, DAG.getConstant(32, MVT::i32)));
2399 SDValue lhsHi32abs =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002400 DAG.getNode(ISD::AND, dl, MVT::i32,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002401 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2402 SDValue lhsLo32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002403 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002404
2405 // SETO and SETUO only use the lhs operand:
2406 if (CC->get() == ISD::SETO) {
2407 // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
2408 // SETUO
2409 APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
Dale Johannesenf5d97892009-02-04 01:48:28 +00002410 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2411 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002412 lhs, DAG.getConstantFP(0.0, lhsVT),
2413 ISD::SETUO),
2414 DAG.getConstant(ccResultAllOnes, ccResultVT));
2415 } else if (CC->get() == ISD::SETUO) {
2416 // Evaluates to true if Op0 is [SQ]NaN
Dale Johannesenf5d97892009-02-04 01:48:28 +00002417 return DAG.getNode(ISD::AND, dl, ccResultVT,
2418 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002419 lhsHi32abs,
2420 DAG.getConstant(0x7ff00000, MVT::i32),
2421 ISD::SETGE),
Dale Johannesenf5d97892009-02-04 01:48:28 +00002422 DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002423 lhsLo32,
2424 DAG.getConstant(0, MVT::i32),
2425 ISD::SETGT));
2426 }
2427
Dale Johannesenb300d2a2009-02-07 00:55:49 +00002428 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, rhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002429 SDValue rhsHi32 =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002430 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2431 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002432 i64rhs, DAG.getConstant(32, MVT::i32)));
2433
2434 // If a value is negative, subtract from the sign magnitude constant:
2435 SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
2436
2437 // Convert the sign-magnitude representation into 2's complement:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002438 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002439 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf5d97892009-02-04 01:48:28 +00002440 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002441 SDValue lhsSelect =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002442 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002443 lhsSelectMask, lhsSignMag2TC, i64lhs);
2444
Dale Johannesenf5d97892009-02-04 01:48:28 +00002445 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002446 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf5d97892009-02-04 01:48:28 +00002447 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002448 SDValue rhsSelect =
Dale Johannesenf5d97892009-02-04 01:48:28 +00002449 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002450 rhsSelectMask, rhsSignMag2TC, i64rhs);
2451
2452 unsigned compareOp;
2453
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002454 switch (CC->get()) {
2455 case ISD::SETOEQ:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002456 case ISD::SETUEQ:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002457 compareOp = ISD::SETEQ; break;
2458 case ISD::SETOGT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002459 case ISD::SETUGT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002460 compareOp = ISD::SETGT; break;
2461 case ISD::SETOGE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002462 case ISD::SETUGE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002463 compareOp = ISD::SETGE; break;
2464 case ISD::SETOLT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002465 case ISD::SETULT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002466 compareOp = ISD::SETLT; break;
2467 case ISD::SETOLE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002468 case ISD::SETULE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002469 compareOp = ISD::SETLE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002470 case ISD::SETUNE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002471 case ISD::SETONE:
2472 compareOp = ISD::SETNE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002473 default:
Torok Edwindac237e2009-07-08 20:53:28 +00002474 llvm_report_error("CellSPU ISel Select: unimplemented f64 condition");
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002475 }
2476
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002477 SDValue result =
Scott Michel6e1d1472009-03-16 18:47:25 +00002478 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
Dale Johannesenf5d97892009-02-04 01:48:28 +00002479 (ISD::CondCode) compareOp);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002480
2481 if ((CC->get() & 0x8) == 0) {
2482 // Ordered comparison:
Dale Johannesenf5d97892009-02-04 01:48:28 +00002483 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002484 lhs, DAG.getConstantFP(0.0, MVT::f64),
2485 ISD::SETO);
Dale Johannesenf5d97892009-02-04 01:48:28 +00002486 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002487 rhs, DAG.getConstantFP(0.0, MVT::f64),
2488 ISD::SETO);
Dale Johannesenf5d97892009-02-04 01:48:28 +00002489 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002490
Dale Johannesenf5d97892009-02-04 01:48:28 +00002491 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002492 }
2493
2494 return result;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002495}
2496
Scott Michel7a1c9e92008-11-22 23:50:42 +00002497//! Lower ISD::SELECT_CC
2498/*!
2499 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2500 SELB instruction.
2501
2502 \note Need to revisit this in the future: if the code path through the true
2503 and false value computations is longer than the latency of a branch (6
2504 cycles), then it would be more advantageous to branch and insert a new basic
2505 block and branch on the condition. However, this code does not make that
2506 assumption, given the simplisitc uses so far.
2507 */
2508
Scott Michelf0569be2008-12-27 04:51:36 +00002509static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2510 const TargetLowering &TLI) {
Scott Michel7a1c9e92008-11-22 23:50:42 +00002511 MVT VT = Op.getValueType();
2512 SDValue lhs = Op.getOperand(0);
2513 SDValue rhs = Op.getOperand(1);
2514 SDValue trueval = Op.getOperand(2);
2515 SDValue falseval = Op.getOperand(3);
2516 SDValue condition = Op.getOperand(4);
Dale Johannesende064702009-02-06 21:50:26 +00002517 DebugLoc dl = Op.getDebugLoc();
Scott Michel7a1c9e92008-11-22 23:50:42 +00002518
Scott Michelf0569be2008-12-27 04:51:36 +00002519 // NOTE: SELB's arguments: $rA, $rB, $mask
2520 //
2521 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2522 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2523 // condition was true and 0s where the condition was false. Hence, the
2524 // arguments to SELB get reversed.
2525
Scott Michel7a1c9e92008-11-22 23:50:42 +00002526 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2527 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2528 // with another "cannot select select_cc" assert:
2529
Dale Johannesende064702009-02-06 21:50:26 +00002530 SDValue compare = DAG.getNode(ISD::SETCC, dl,
Duncan Sands5480c042009-01-01 15:52:00 +00002531 TLI.getSetCCResultType(Op.getValueType()),
Scott Michelf0569be2008-12-27 04:51:36 +00002532 lhs, rhs, condition);
Dale Johannesende064702009-02-06 21:50:26 +00002533 return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002534}
2535
Scott Michelb30e8f62008-12-02 19:53:53 +00002536//! Custom lower ISD::TRUNCATE
2537static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2538{
Scott Michel6e1d1472009-03-16 18:47:25 +00002539 // Type to truncate to
Scott Michelb30e8f62008-12-02 19:53:53 +00002540 MVT VT = Op.getValueType();
2541 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2542 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesende064702009-02-06 21:50:26 +00002543 DebugLoc dl = Op.getDebugLoc();
Scott Michelb30e8f62008-12-02 19:53:53 +00002544
Scott Michel6e1d1472009-03-16 18:47:25 +00002545 // Type to truncate from
Scott Michelb30e8f62008-12-02 19:53:53 +00002546 SDValue Op0 = Op.getOperand(0);
2547 MVT Op0VT = Op0.getValueType();
Scott Michelb30e8f62008-12-02 19:53:53 +00002548
Scott Michelf0569be2008-12-27 04:51:36 +00002549 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel52d00012009-01-03 00:27:53 +00002550 // Create shuffle mask, least significant doubleword of quadword
Scott Michelf0569be2008-12-27 04:51:36 +00002551 unsigned maskHigh = 0x08090a0b;
2552 unsigned maskLow = 0x0c0d0e0f;
2553 // Use a shuffle to perform the truncation
Evan Chenga87008d2009-02-25 22:49:59 +00002554 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2555 DAG.getConstant(maskHigh, MVT::i32),
2556 DAG.getConstant(maskLow, MVT::i32),
2557 DAG.getConstant(maskHigh, MVT::i32),
2558 DAG.getConstant(maskLow, MVT::i32));
Scott Michelf0569be2008-12-27 04:51:36 +00002559
Scott Michel6e1d1472009-03-16 18:47:25 +00002560 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT,
2561 Op0, Op0, shufMask);
Scott Michelf0569be2008-12-27 04:51:36 +00002562
Scott Michel6e1d1472009-03-16 18:47:25 +00002563 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle);
Scott Michelb30e8f62008-12-02 19:53:53 +00002564 }
2565
Scott Michelf0569be2008-12-27 04:51:36 +00002566 return SDValue(); // Leave the truncate unmolested
Scott Michelb30e8f62008-12-02 19:53:53 +00002567}
2568
Scott Michel7a1c9e92008-11-22 23:50:42 +00002569//! Custom (target-specific) lowering entry point
2570/*!
2571 This is where LLVM's DAG selection process calls to do target-specific
2572 lowering of nodes.
2573 */
Dan Gohman475871a2008-07-27 21:46:04 +00002574SDValue
2575SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel266bc8f2007-12-04 22:23:35 +00002576{
Scott Michela59d4692008-02-23 18:41:37 +00002577 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002578 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002579
2580 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002581 default: {
Torok Edwindac237e2009-07-08 20:53:28 +00002582#ifndef NDEBUG
Scott Michel266bc8f2007-12-04 22:23:35 +00002583 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002584 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greifba36cb52008-08-28 21:40:38 +00002585 cerr << "*Op.getNode():\n";
2586 Op.getNode()->dump();
Torok Edwindac237e2009-07-08 20:53:28 +00002587#endif
2588 llvm_unreachable();
Scott Michel266bc8f2007-12-04 22:23:35 +00002589 }
2590 case ISD::LOAD:
Scott Michelb30e8f62008-12-02 19:53:53 +00002591 case ISD::EXTLOAD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002592 case ISD::SEXTLOAD:
2593 case ISD::ZEXTLOAD:
2594 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2595 case ISD::STORE:
2596 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2597 case ISD::ConstantPool:
2598 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2599 case ISD::GlobalAddress:
2600 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2601 case ISD::JumpTable:
2602 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002603 case ISD::ConstantFP:
2604 return LowerConstantFP(Op, DAG);
2605 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002606 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002607 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002608 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002609 case ISD::RET:
2610 return LowerRET(Op, DAG, getTargetMachine());
2611
Scott Michel02d711b2008-12-30 23:28:25 +00002612 // i8, i64 math ops:
Scott Michel8bf61e82008-06-02 22:18:03 +00002613 case ISD::ADD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002614 case ISD::SUB:
2615 case ISD::ROTR:
2616 case ISD::ROTL:
2617 case ISD::SRL:
2618 case ISD::SHL:
Scott Michel8bf61e82008-06-02 22:18:03 +00002619 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002620 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002621 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michela59d4692008-02-23 18:41:37 +00002622 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002623 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002624
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002625 case ISD::FP_TO_SINT:
2626 case ISD::FP_TO_UINT:
2627 return LowerFP_TO_INT(Op, DAG, *this);
2628
2629 case ISD::SINT_TO_FP:
2630 case ISD::UINT_TO_FP:
2631 return LowerINT_TO_FP(Op, DAG, *this);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002632
Scott Michel266bc8f2007-12-04 22:23:35 +00002633 // Vector-related lowering.
2634 case ISD::BUILD_VECTOR:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002635 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002636 case ISD::SCALAR_TO_VECTOR:
2637 return LowerSCALAR_TO_VECTOR(Op, DAG);
2638 case ISD::VECTOR_SHUFFLE:
2639 return LowerVECTOR_SHUFFLE(Op, DAG);
2640 case ISD::EXTRACT_VECTOR_ELT:
2641 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2642 case ISD::INSERT_VECTOR_ELT:
2643 return LowerINSERT_VECTOR_ELT(Op, DAG);
2644
2645 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2646 case ISD::AND:
2647 case ISD::OR:
2648 case ISD::XOR:
2649 return LowerByteImmed(Op, DAG);
2650
2651 // Vector and i8 multiply:
2652 case ISD::MUL:
Scott Michel02d711b2008-12-30 23:28:25 +00002653 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002654 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel266bc8f2007-12-04 22:23:35 +00002655
Scott Michel266bc8f2007-12-04 22:23:35 +00002656 case ISD::CTPOP:
2657 return LowerCTPOP(Op, DAG);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002658
2659 case ISD::SELECT_CC:
Scott Michelf0569be2008-12-27 04:51:36 +00002660 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelb30e8f62008-12-02 19:53:53 +00002661
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002662 case ISD::SETCC:
2663 return LowerSETCC(Op, DAG, *this);
2664
Scott Michelb30e8f62008-12-02 19:53:53 +00002665 case ISD::TRUNCATE:
2666 return LowerTRUNCATE(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002667 }
2668
Dan Gohman475871a2008-07-27 21:46:04 +00002669 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002670}
2671
Duncan Sands1607f052008-12-01 11:39:25 +00002672void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2673 SmallVectorImpl<SDValue>&Results,
2674 SelectionDAG &DAG)
Scott Michel73ce1c52008-11-10 23:43:06 +00002675{
2676#if 0
2677 unsigned Opc = (unsigned) N->getOpcode();
2678 MVT OpVT = N->getValueType(0);
2679
2680 switch (Opc) {
2681 default: {
2682 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2683 cerr << "Op.getOpcode() = " << Opc << "\n";
2684 cerr << "*Op.getNode():\n";
2685 N->dump();
2686 abort();
2687 /*NOTREACHED*/
2688 }
2689 }
2690#endif
2691
2692 /* Otherwise, return unchanged */
Scott Michel73ce1c52008-11-10 23:43:06 +00002693}
2694
Scott Michel266bc8f2007-12-04 22:23:35 +00002695//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002696// Target Optimization Hooks
2697//===----------------------------------------------------------------------===//
2698
Dan Gohman475871a2008-07-27 21:46:04 +00002699SDValue
Scott Michel266bc8f2007-12-04 22:23:35 +00002700SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2701{
2702#if 0
2703 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002704#endif
2705 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002706 SelectionDAG &DAG = DCI.DAG;
Scott Michel1a6cdb62008-12-01 17:56:02 +00002707 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2708 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michelf0569be2008-12-27 04:51:36 +00002709 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel1a6cdb62008-12-01 17:56:02 +00002710 SDValue Result; // Initially, empty result
Dale Johannesende064702009-02-06 21:50:26 +00002711 DebugLoc dl = N->getDebugLoc();
Scott Michel266bc8f2007-12-04 22:23:35 +00002712
2713 switch (N->getOpcode()) {
2714 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002715 case ISD::ADD: {
Dan Gohman475871a2008-07-27 21:46:04 +00002716 SDValue Op1 = N->getOperand(1);
Scott Michel053c1da2008-01-29 02:16:57 +00002717
Scott Michelf0569be2008-12-27 04:51:36 +00002718 if (Op0.getOpcode() == SPUISD::IndirectAddr
2719 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2720 // Normalize the operands to reduce repeated code
2721 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michel1df30c42008-12-29 03:23:36 +00002722
Scott Michelf0569be2008-12-27 04:51:36 +00002723 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2724 IndirectArg = Op1;
2725 AddArg = Op0;
2726 }
2727
2728 if (isa<ConstantSDNode>(AddArg)) {
2729 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2730 SDValue IndOp1 = IndirectArg.getOperand(1);
2731
2732 if (CN0->isNullValue()) {
2733 // (add (SPUindirect <arg>, <arg>), 0) ->
2734 // (SPUindirect <arg>, <arg>)
Scott Michel053c1da2008-01-29 02:16:57 +00002735
Scott Michel23f2ff72008-12-04 17:16:59 +00002736#if !defined(NDEBUG)
Scott Michelf0569be2008-12-27 04:51:36 +00002737 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002738 cerr << "\n"
Scott Michelf0569be2008-12-27 04:51:36 +00002739 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2740 << "With: (SPUindirect <arg>, <arg>)\n";
2741 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002742#endif
2743
Scott Michelf0569be2008-12-27 04:51:36 +00002744 return IndirectArg;
2745 } else if (isa<ConstantSDNode>(IndOp1)) {
2746 // (add (SPUindirect <arg>, <const>), <const>) ->
2747 // (SPUindirect <arg>, <const + const>)
2748 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2749 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2750 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michel053c1da2008-01-29 02:16:57 +00002751
Scott Michelf0569be2008-12-27 04:51:36 +00002752#if !defined(NDEBUG)
2753 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2754 cerr << "\n"
2755 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2756 << "), " << CN0->getSExtValue() << ")\n"
2757 << "With: (SPUindirect <arg>, "
2758 << combinedConst << ")\n";
2759 }
2760#endif
Scott Michel053c1da2008-01-29 02:16:57 +00002761
Dale Johannesende064702009-02-06 21:50:26 +00002762 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michelf0569be2008-12-27 04:51:36 +00002763 IndirectArg, combinedValue);
2764 }
Scott Michel053c1da2008-01-29 02:16:57 +00002765 }
2766 }
Scott Michela59d4692008-02-23 18:41:37 +00002767 break;
2768 }
2769 case ISD::SIGN_EXTEND:
2770 case ISD::ZERO_EXTEND:
2771 case ISD::ANY_EXTEND: {
Scott Michel1a6cdb62008-12-01 17:56:02 +00002772 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michela59d4692008-02-23 18:41:37 +00002773 // (any_extend (SPUextract_elt0 <arg>)) ->
2774 // (SPUextract_elt0 <arg>)
2775 // Types must match, however...
Scott Michel23f2ff72008-12-04 17:16:59 +00002776#if !defined(NDEBUG)
2777 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002778 cerr << "\nReplace: ";
2779 N->dump(&DAG);
2780 cerr << "\nWith: ";
2781 Op0.getNode()->dump(&DAG);
2782 cerr << "\n";
Scott Michel23f2ff72008-12-04 17:16:59 +00002783 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002784#endif
Scott Michela59d4692008-02-23 18:41:37 +00002785
2786 return Op0;
2787 }
2788 break;
2789 }
2790 case SPUISD::IndirectAddr: {
2791 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002792 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2793 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michela59d4692008-02-23 18:41:37 +00002794 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2795 // (SPUaform <addr>, 0)
2796
2797 DEBUG(cerr << "Replace: ");
2798 DEBUG(N->dump(&DAG));
2799 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002800 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002801 DEBUG(cerr << "\n");
2802
2803 return Op0;
2804 }
Scott Michelf0569be2008-12-27 04:51:36 +00002805 } else if (Op0.getOpcode() == ISD::ADD) {
2806 SDValue Op1 = N->getOperand(1);
2807 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2808 // (SPUindirect (add <arg>, <arg>), 0) ->
2809 // (SPUindirect <arg>, <arg>)
2810 if (CN1->isNullValue()) {
2811
2812#if !defined(NDEBUG)
2813 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2814 cerr << "\n"
2815 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2816 << "With: (SPUindirect <arg>, <arg>)\n";
2817 }
2818#endif
2819
Dale Johannesende064702009-02-06 21:50:26 +00002820 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michelf0569be2008-12-27 04:51:36 +00002821 Op0.getOperand(0), Op0.getOperand(1));
2822 }
2823 }
Scott Michela59d4692008-02-23 18:41:37 +00002824 }
2825 break;
2826 }
2827 case SPUISD::SHLQUAD_L_BITS:
2828 case SPUISD::SHLQUAD_L_BYTES:
2829 case SPUISD::VEC_SHL:
2830 case SPUISD::VEC_SRL:
2831 case SPUISD::VEC_SRA:
Scott Michelf0569be2008-12-27 04:51:36 +00002832 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman475871a2008-07-27 21:46:04 +00002833 SDValue Op1 = N->getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00002834
Scott Michelf0569be2008-12-27 04:51:36 +00002835 // Kill degenerate vector shifts:
2836 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2837 if (CN->isNullValue()) {
Scott Michela59d4692008-02-23 18:41:37 +00002838 Result = Op0;
2839 }
2840 }
2841 break;
2842 }
Scott Michelf0569be2008-12-27 04:51:36 +00002843 case SPUISD::PREFSLOT2VEC: {
Scott Michela59d4692008-02-23 18:41:37 +00002844 switch (Op0.getOpcode()) {
2845 default:
2846 break;
2847 case ISD::ANY_EXTEND:
2848 case ISD::ZERO_EXTEND:
2849 case ISD::SIGN_EXTEND: {
Scott Michel1df30c42008-12-29 03:23:36 +00002850 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michela59d4692008-02-23 18:41:37 +00002851 // <arg>
Scott Michel1df30c42008-12-29 03:23:36 +00002852 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman475871a2008-07-27 21:46:04 +00002853 SDValue Op00 = Op0.getOperand(0);
Scott Michel104de432008-11-24 17:11:17 +00002854 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman475871a2008-07-27 21:46:04 +00002855 SDValue Op000 = Op00.getOperand(0);
Scott Michel1a6cdb62008-12-01 17:56:02 +00002856 if (Op000.getValueType() == NodeVT) {
Scott Michela59d4692008-02-23 18:41:37 +00002857 Result = Op000;
2858 }
2859 }
2860 break;
2861 }
Scott Michel104de432008-11-24 17:11:17 +00002862 case SPUISD::VEC2PREFSLOT: {
Scott Michel1df30c42008-12-29 03:23:36 +00002863 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michela59d4692008-02-23 18:41:37 +00002864 // <arg>
2865 Result = Op0.getOperand(0);
2866 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002867 }
Scott Michela59d4692008-02-23 18:41:37 +00002868 }
2869 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002870 }
2871 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002872
Scott Michel58c58182008-01-17 20:38:41 +00002873 // Otherwise, return unchanged.
Scott Michel1a6cdb62008-12-01 17:56:02 +00002874#ifndef NDEBUG
Gabor Greifba36cb52008-08-28 21:40:38 +00002875 if (Result.getNode()) {
Scott Michela59d4692008-02-23 18:41:37 +00002876 DEBUG(cerr << "\nReplace.SPU: ");
2877 DEBUG(N->dump(&DAG));
2878 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002879 DEBUG(Result.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002880 DEBUG(cerr << "\n");
2881 }
2882#endif
2883
2884 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002885}
2886
2887//===----------------------------------------------------------------------===//
2888// Inline Assembly Support
2889//===----------------------------------------------------------------------===//
2890
2891/// getConstraintType - Given a constraint letter, return the type of
2892/// constraint it is for this target.
Scott Michel5af8f0e2008-07-16 17:17:29 +00002893SPUTargetLowering::ConstraintType
Scott Michel266bc8f2007-12-04 22:23:35 +00002894SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2895 if (ConstraintLetter.size() == 1) {
2896 switch (ConstraintLetter[0]) {
2897 default: break;
2898 case 'b':
2899 case 'r':
2900 case 'f':
2901 case 'v':
2902 case 'y':
2903 return C_RegisterClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002904 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002905 }
2906 return TargetLowering::getConstraintType(ConstraintLetter);
2907}
2908
Scott Michel5af8f0e2008-07-16 17:17:29 +00002909std::pair<unsigned, const TargetRegisterClass*>
Scott Michel266bc8f2007-12-04 22:23:35 +00002910SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002911 MVT VT) const
Scott Michel266bc8f2007-12-04 22:23:35 +00002912{
2913 if (Constraint.size() == 1) {
2914 // GCC RS6000 Constraint Letters
2915 switch (Constraint[0]) {
2916 case 'b': // R1-R31
2917 case 'r': // R0-R31
2918 if (VT == MVT::i64)
2919 return std::make_pair(0U, SPU::R64CRegisterClass);
2920 return std::make_pair(0U, SPU::R32CRegisterClass);
2921 case 'f':
2922 if (VT == MVT::f32)
2923 return std::make_pair(0U, SPU::R32FPRegisterClass);
2924 else if (VT == MVT::f64)
2925 return std::make_pair(0U, SPU::R64FPRegisterClass);
2926 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002927 case 'v':
Scott Michel266bc8f2007-12-04 22:23:35 +00002928 return std::make_pair(0U, SPU::GPRCRegisterClass);
2929 }
2930 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00002931
Scott Michel266bc8f2007-12-04 22:23:35 +00002932 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2933}
2934
Scott Michela59d4692008-02-23 18:41:37 +00002935//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00002936void
Dan Gohman475871a2008-07-27 21:46:04 +00002937SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00002938 const APInt &Mask,
Scott Michel5af8f0e2008-07-16 17:17:29 +00002939 APInt &KnownZero,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00002940 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002941 const SelectionDAG &DAG,
2942 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00002943#if 0
Dan Gohmande551f92009-04-01 18:45:54 +00002944 const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT;
Scott Michela59d4692008-02-23 18:41:37 +00002945
2946 switch (Op.getOpcode()) {
2947 default:
2948 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2949 break;
Scott Michela59d4692008-02-23 18:41:37 +00002950 case CALL:
2951 case SHUFB:
Scott Michel7a1c9e92008-11-22 23:50:42 +00002952 case SHUFFLE_MASK:
Scott Michela59d4692008-02-23 18:41:37 +00002953 case CNTB:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002954 case SPUISD::PREFSLOT2VEC:
Scott Michela59d4692008-02-23 18:41:37 +00002955 case SPUISD::LDRESULT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002956 case SPUISD::VEC2PREFSLOT:
Scott Michel203b2d62008-04-30 00:30:08 +00002957 case SPUISD::SHLQUAD_L_BITS:
2958 case SPUISD::SHLQUAD_L_BYTES:
2959 case SPUISD::VEC_SHL:
2960 case SPUISD::VEC_SRL:
2961 case SPUISD::VEC_SRA:
2962 case SPUISD::VEC_ROTL:
2963 case SPUISD::VEC_ROTR:
Scott Michel203b2d62008-04-30 00:30:08 +00002964 case SPUISD::ROTBYTES_LEFT:
Scott Michel8bf61e82008-06-02 22:18:03 +00002965 case SPUISD::SELECT_MASK:
2966 case SPUISD::SELB:
Scott Michela59d4692008-02-23 18:41:37 +00002967 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002968#endif
Scott Michel266bc8f2007-12-04 22:23:35 +00002969}
Scott Michel02d711b2008-12-30 23:28:25 +00002970
Scott Michelf0569be2008-12-27 04:51:36 +00002971unsigned
2972SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2973 unsigned Depth) const {
2974 switch (Op.getOpcode()) {
2975 default:
2976 return 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00002977
Scott Michelf0569be2008-12-27 04:51:36 +00002978 case ISD::SETCC: {
2979 MVT VT = Op.getValueType();
2980
2981 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
2982 VT = MVT::i32;
2983 }
2984 return VT.getSizeInBits();
2985 }
2986 }
2987}
Scott Michel1df30c42008-12-29 03:23:36 +00002988
Scott Michel203b2d62008-04-30 00:30:08 +00002989// LowerAsmOperandForConstraint
2990void
Dan Gohman475871a2008-07-27 21:46:04 +00002991SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michel203b2d62008-04-30 00:30:08 +00002992 char ConstraintLetter,
Evan Chengda43bcf2008-09-24 00:05:32 +00002993 bool hasMemory,
Dan Gohman475871a2008-07-27 21:46:04 +00002994 std::vector<SDValue> &Ops,
Scott Michel203b2d62008-04-30 00:30:08 +00002995 SelectionDAG &DAG) const {
2996 // Default, for the time being, to the base class handler
Evan Chengda43bcf2008-09-24 00:05:32 +00002997 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2998 Ops, DAG);
Scott Michel203b2d62008-04-30 00:30:08 +00002999}
3000
Scott Michel266bc8f2007-12-04 22:23:35 +00003001/// isLegalAddressImmediate - Return true if the integer value can be used
3002/// as the offset of the target addressing mode.
Gabor Greif93c53e52008-08-31 15:37:04 +00003003bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3004 const Type *Ty) const {
Scott Michel266bc8f2007-12-04 22:23:35 +00003005 // SPU's addresses are 256K:
3006 return (V > -(1 << 18) && V < (1 << 18) - 1);
3007}
3008
3009bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel5af8f0e2008-07-16 17:17:29 +00003010 return false;
Scott Michel266bc8f2007-12-04 22:23:35 +00003011}
Dan Gohman6520e202008-10-18 02:06:02 +00003012
3013bool
3014SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
3015 // The SPU target isn't yet aware of offsets.
3016 return false;
3017}