blob: 2042a93e919be6d3fee017c320deedd8f36bb60d [file] [log] [blame]
Scott Michel6e22c652007-12-04 22:23:35 +00001//
Scott Michel839ad0a2009-03-17 01:15:45 +00002//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
Scott Michel6e22c652007-12-04 22:23:35 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-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 Michel6e22c652007-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 Michelc3a19102008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel82335272008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel6e22c652007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michel9e3e4a92009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel6e22c652007-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 Lattnera10fff52007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel6e22c652007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel6e22c652007-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 Edwinfb8d6d52009-07-08 20:53:28 +000031#include "llvm/Support/ErrorHandling.h"
Scott Michel6e22c652007-12-04 22:23:35 +000032#include "llvm/Support/MathExtras.h"
Torok Edwinfb8d6d52009-07-08 20:53:28 +000033#include "llvm/Support/raw_ostream.h"
Scott Michel6e22c652007-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 Sands13237ac2008-06-06 12:08:01 +000044 //! MVT mapping to useful data for Cell SPU
Scott Michel6e22c652007-12-04 22:23:35 +000045 struct valtype_map_s {
Scott Michel0be03392008-11-22 23:50:42 +000046 const MVT valtype;
47 const int prefslot_byte;
Scott Michel6e22c652007-12-04 22:23:35 +000048 };
Scott Michelfe095082008-07-16 17:17:29 +000049
Scott Michel6e22c652007-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 Sands13237ac2008-06-06 12:08:01 +000063 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel6e22c652007-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 Michelbb713ae2008-01-30 02:55:46 +000068 retval = valtype_map + i;
69 break;
Scott Michel6e22c652007-12-04 22:23:35 +000070 }
71 }
72
73#ifndef NDEBUG
74 if (retval == 0) {
Torok Edwinfb8d6d52009-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 Michel6e22c652007-12-04 22:23:35 +000080 }
81#endif
82
83 return retval;
84 }
Scott Michela292fc62009-01-15 04:41:47 +000085
Scott Michel9e3e4a92009-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();
Owen Anderson0504e0a2009-07-09 17:57:24 +0000105 const Type *ArgTy = ArgVT.getTypeForMVT(*DAG.getContext());
Scott Michel9e3e4a92009-01-26 03:31:40 +0000106 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.
Owen Anderson0504e0a2009-07-09 17:57:24 +0000116 const Type *RetTy =
117 Op.getNode()->getValueType(0).getTypeForMVT(*DAG.getContext());
Scott Michel9e3e4a92009-01-26 03:31:40 +0000118 std::pair<SDValue, SDValue> CallInfo =
119 TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
Tilmann Schelleraea60592009-07-03 06:44:53 +0000120 0, CallingConv::C, false, Callee, Args, DAG,
Dale Johannesen9c310712009-02-07 19:59:05 +0000121 Op.getDebugLoc());
Scott Michel9e3e4a92009-01-26 03:31:40 +0000122
123 return CallInfo.first;
124 }
Scott Michel6e22c652007-12-04 22:23:35 +0000125}
126
127SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
128 : TargetLowering(TM),
129 SPUTM(TM)
130{
131 // Fold away setcc operations if possible.
132 setPow2DivIsCheap();
133
134 // Use _setjmp/_longjmp instead of setjmp/longjmp.
135 setUseUnderscoreSetJmp(true);
136 setUseUnderscoreLongJmp(true);
Scott Michelfe095082008-07-16 17:17:29 +0000137
Scott Micheled7d79f2009-01-21 04:58:48 +0000138 // Set RTLIB libcall names as used by SPU:
139 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
140
Scott Michel6e22c652007-12-04 22:23:35 +0000141 // Set up the SPU's register classes:
Scott Michelc5cccb92007-12-17 22:32:34 +0000142 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
143 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
144 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
145 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
146 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
147 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel6e22c652007-12-04 22:23:35 +0000148 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michelfe095082008-07-16 17:17:29 +0000149
Scott Michel6e22c652007-12-04 22:23:35 +0000150 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng07d53b12008-10-14 21:26:46 +0000151 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
152 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
153 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +0000154
Scott Michel82335272008-12-27 04:51:36 +0000155 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
156 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michel73640252008-12-02 19:53:53 +0000157
Scott Michel6e22c652007-12-04 22:23:35 +0000158 // SPU constant load actions are custom lowered:
Nate Begeman4b3210a2008-02-14 18:43:04 +0000159 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000160 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
161
162 // SPU's loads and stores have to be custom lowered:
Scott Michel6887caf2009-01-06 03:36:14 +0000163 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel6e22c652007-12-04 22:23:35 +0000164 ++sctype) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000165 MVT VT = (MVT::SimpleValueType)sctype;
166
Scott Michel82335272008-12-27 04:51:36 +0000167 setOperationAction(ISD::LOAD, VT, Custom);
168 setOperationAction(ISD::STORE, VT, Custom);
169 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
170 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
171 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
172
173 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
174 MVT StoreVT = (MVT::SimpleValueType) stype;
175 setTruncStoreAction(VT, StoreVT, Expand);
176 }
Scott Michel6e22c652007-12-04 22:23:35 +0000177 }
178
Scott Michel82335272008-12-27 04:51:36 +0000179 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
180 ++sctype) {
181 MVT VT = (MVT::SimpleValueType) sctype;
182
183 setOperationAction(ISD::LOAD, VT, Custom);
184 setOperationAction(ISD::STORE, VT, Custom);
185
186 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
187 MVT StoreVT = (MVT::SimpleValueType) stype;
188 setTruncStoreAction(VT, StoreVT, Expand);
189 }
190 }
191
Scott Michel6e22c652007-12-04 22:23:35 +0000192 // Expand the jumptable branches
193 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
194 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel0be03392008-11-22 23:50:42 +0000195
196 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michelfe095082008-07-16 17:17:29 +0000197 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel0be03392008-11-22 23:50:42 +0000198 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
199 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
200 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
201 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000202
203 // SPU has no intrinsics for these particular operations:
Andrew Lenharthfedcf472008-02-16 14:46:26 +0000204 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
205
Scott Michel82335272008-12-27 04:51:36 +0000206 // SPU has no SREM/UREM instructions
Scott Michel6e22c652007-12-04 22:23:35 +0000207 setOperationAction(ISD::SREM, MVT::i32, Expand);
208 setOperationAction(ISD::UREM, MVT::i32, Expand);
209 setOperationAction(ISD::SREM, MVT::i64, Expand);
210 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000211
Scott Michel6e22c652007-12-04 22:23:35 +0000212 // We don't support sin/cos/sqrt/fmod
213 setOperationAction(ISD::FSIN , MVT::f64, Expand);
214 setOperationAction(ISD::FCOS , MVT::f64, Expand);
215 setOperationAction(ISD::FREM , MVT::f64, Expand);
216 setOperationAction(ISD::FSIN , MVT::f32, Expand);
217 setOperationAction(ISD::FCOS , MVT::f32, Expand);
218 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000219
Scott Michel9e3e4a92009-01-26 03:31:40 +0000220 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
221 // for f32!)
Scott Michel6e22c652007-12-04 22:23:35 +0000222 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
223 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000224
Scott Michel6e22c652007-12-04 22:23:35 +0000225 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
226 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
227
228 // SPU can do rotate right and left, so legalize it... but customize for i8
229 // because instructions don't exist.
Bill Wendlingaebd2662008-08-31 02:59:23 +0000230
231 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
232 // .td files.
233 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
234 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
235 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
236
Scott Michel6e22c652007-12-04 22:23:35 +0000237 setOperationAction(ISD::ROTL, MVT::i32, Legal);
238 setOperationAction(ISD::ROTL, MVT::i16, Legal);
239 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Michel3726019a2008-11-20 16:36:33 +0000240
Scott Michel6e22c652007-12-04 22:23:35 +0000241 // SPU has no native version of shift left/right for i8
242 setOperationAction(ISD::SHL, MVT::i8, Custom);
243 setOperationAction(ISD::SRL, MVT::i8, Custom);
244 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michelc6918c12008-11-21 02:56:16 +0000245
Scott Michel41236c02008-12-30 23:28:25 +0000246 // Make these operations legal and handle them during instruction selection:
247 setOperationAction(ISD::SHL, MVT::i64, Legal);
248 setOperationAction(ISD::SRL, MVT::i64, Legal);
249 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000250
Scott Michelfe095082008-07-16 17:17:29 +0000251 // Custom lower i8, i32 and i64 multiplications
252 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000253 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michela292fc62009-01-15 04:41:47 +0000254 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michelc6918c12008-11-21 02:56:16 +0000255
Eli Friedman48021d12009-06-16 06:40:59 +0000256 // Expand double-width multiplication
257 // FIXME: It would probably be reasonable to support some of these operations
258 setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand);
259 setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand);
260 setOperationAction(ISD::MULHU, MVT::i8, Expand);
261 setOperationAction(ISD::MULHS, MVT::i8, Expand);
262 setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand);
263 setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand);
264 setOperationAction(ISD::MULHU, MVT::i16, Expand);
265 setOperationAction(ISD::MULHS, MVT::i16, Expand);
266 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
267 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
268 setOperationAction(ISD::MULHU, MVT::i32, Expand);
269 setOperationAction(ISD::MULHS, MVT::i32, Expand);
270 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
271 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
272 setOperationAction(ISD::MULHU, MVT::i64, Expand);
273 setOperationAction(ISD::MULHS, MVT::i64, Expand);
274
Scott Micheld831cc42008-06-02 22:18:03 +0000275 // Need to custom handle (some) common i8, i64 math ops
Scott Michel41236c02008-12-30 23:28:25 +0000276 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michela292fc62009-01-15 04:41:47 +0000277 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000278 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michela292fc62009-01-15 04:41:47 +0000279 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michelfe095082008-07-16 17:17:29 +0000280
Scott Michel6e22c652007-12-04 22:23:35 +0000281 // SPU does not have BSWAP. It does have i32 support CTLZ.
282 // CTPOP has to be custom lowered.
283 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
284 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
285
286 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
287 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
288 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
289 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
290
291 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
292 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
293
294 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michelfe095082008-07-16 17:17:29 +0000295
Scott Micheld831cc42008-06-02 22:18:03 +0000296 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel92275422008-03-10 23:49:09 +0000297 // select ought to work:
Scott Michel48e33752008-03-10 16:58:52 +0000298 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel42f56b42008-03-05 23:02:02 +0000299 setOperationAction(ISD::SELECT, MVT::i16, Legal);
300 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel82335272008-12-27 04:51:36 +0000301 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000302
Scott Michel48e33752008-03-10 16:58:52 +0000303 setOperationAction(ISD::SETCC, MVT::i8, Legal);
304 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000305 setOperationAction(ISD::SETCC, MVT::i32, Legal);
306 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Micheled7d79f2009-01-21 04:58:48 +0000307 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michel42f56b42008-03-05 23:02:02 +0000308
Scott Michel82335272008-12-27 04:51:36 +0000309 // Custom lower i128 -> i64 truncates
Scott Michel73640252008-12-02 19:53:53 +0000310 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
311
Scott Michel9e3e4a92009-01-26 03:31:40 +0000312 // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
313 // to expand to a libcall, hence the custom lowering:
314 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
315 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000316
317 // FDIV on SPU requires custom lowering
Scott Michel9e3e4a92009-01-26 03:31:40 +0000318 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel6e22c652007-12-04 22:23:35 +0000319
Scott Michel49483182009-01-26 22:33:37 +0000320 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
Scott Michel9e3e4a92009-01-26 03:31:40 +0000321 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000322 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
Scott Michel9e3e4a92009-01-26 03:31:40 +0000323 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
324 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000325 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
Scott Michel9e3e4a92009-01-26 03:31:40 +0000326 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel6e22c652007-12-04 22:23:35 +0000327 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
328 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
329
Scott Michel5f1470f2007-12-20 00:44:13 +0000330 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
331 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
332 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
333 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel6e22c652007-12-04 22:23:35 +0000334
335 // We cannot sextinreg(i1). Expand to shifts.
336 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000337
Scott Michel6e22c652007-12-04 22:23:35 +0000338 // Support label based line numbers.
Dan Gohman5c73a882008-06-30 20:59:49 +0000339 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000340 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000341
342 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel6e22c652007-12-04 22:23:35 +0000343 // appropriate instructions to materialize the address.
Scott Michelc6918c12008-11-21 02:56:16 +0000344 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelceae3bb2008-01-29 02:16:57 +0000345 ++sctype) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000346 MVT VT = (MVT::SimpleValueType)sctype;
347
Scott Michelb8ee30d2008-12-29 03:23:36 +0000348 setOperationAction(ISD::GlobalAddress, VT, Custom);
349 setOperationAction(ISD::ConstantPool, VT, Custom);
350 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelceae3bb2008-01-29 02:16:57 +0000351 }
Scott Michel6e22c652007-12-04 22:23:35 +0000352
353 // RET must be custom lowered, to meet ABI requirements
354 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000355
Scott Michel6e22c652007-12-04 22:23:35 +0000356 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
357 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000358
Scott Michel6e22c652007-12-04 22:23:35 +0000359 // Use the default implementation.
360 setOperationAction(ISD::VAARG , MVT::Other, Expand);
361 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
362 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michelfe095082008-07-16 17:17:29 +0000363 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000364 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
365 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
366 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
367
368 // Cell SPU has instructions for converting between i64 and fp.
369 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
370 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michelfe095082008-07-16 17:17:29 +0000371
Scott Michel6e22c652007-12-04 22:23:35 +0000372 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
373 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
374
375 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
376 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
377
378 // First set operation action for all vector types to expand. Then we
379 // will selectively turn on ones that can be effectively codegen'd.
380 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
381 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
382 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
383 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
384 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
385 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
386
Scott Michel494daa72009-01-06 23:10:38 +0000387 // "Odd size" vector classes that we're willing to support:
388 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
389
Duncan Sands13237ac2008-06-06 12:08:01 +0000390 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
391 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
392 MVT VT = (MVT::SimpleValueType)i;
Scott Michel6e22c652007-12-04 22:23:35 +0000393
Duncan Sands13237ac2008-06-06 12:08:01 +0000394 // add/sub are legal for all supported vector VT's.
Scott Michel9e3e4a92009-01-26 03:31:40 +0000395 setOperationAction(ISD::ADD, VT, Legal);
396 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands13237ac2008-06-06 12:08:01 +0000397 // mul has to be custom lowered.
Scott Michel9e3e4a92009-01-26 03:31:40 +0000398 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands13237ac2008-06-06 12:08:01 +0000399
Scott Michel9e3e4a92009-01-26 03:31:40 +0000400 setOperationAction(ISD::AND, VT, Legal);
401 setOperationAction(ISD::OR, VT, Legal);
402 setOperationAction(ISD::XOR, VT, Legal);
403 setOperationAction(ISD::LOAD, VT, Legal);
404 setOperationAction(ISD::SELECT, VT, Legal);
405 setOperationAction(ISD::STORE, VT, Legal);
Scott Michelfe095082008-07-16 17:17:29 +0000406
Scott Michel6e22c652007-12-04 22:23:35 +0000407 // These operations need to be expanded:
Scott Michel9e3e4a92009-01-26 03:31:40 +0000408 setOperationAction(ISD::SDIV, VT, Expand);
409 setOperationAction(ISD::SREM, VT, Expand);
410 setOperationAction(ISD::UDIV, VT, Expand);
411 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel6e22c652007-12-04 22:23:35 +0000412
413 // Custom lower build_vector, constant pool spills, insert and
414 // extract vector elements:
Duncan Sands13237ac2008-06-06 12:08:01 +0000415 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
416 setOperationAction(ISD::ConstantPool, VT, Custom);
417 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
418 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
419 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
420 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel6e22c652007-12-04 22:23:35 +0000421 }
422
Scott Michel6e22c652007-12-04 22:23:35 +0000423 setOperationAction(ISD::AND, MVT::v16i8, Custom);
424 setOperationAction(ISD::OR, MVT::v16i8, Custom);
425 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
426 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel8d5841a2008-01-11 02:53:15 +0000427
Scott Michel41236c02008-12-30 23:28:25 +0000428 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelb8ee30d2008-12-29 03:23:36 +0000429
Scott Michel6e22c652007-12-04 22:23:35 +0000430 setShiftAmountType(MVT::i32);
Scott Michel82335272008-12-27 04:51:36 +0000431 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michelfe095082008-07-16 17:17:29 +0000432
Scott Michel6e22c652007-12-04 22:23:35 +0000433 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michelfe095082008-07-16 17:17:29 +0000434
Scott Michel6e22c652007-12-04 22:23:35 +0000435 // We have target-specific dag combine patterns for the following nodes:
Scott Michelceae3bb2008-01-29 02:16:57 +0000436 setTargetDAGCombine(ISD::ADD);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000437 setTargetDAGCombine(ISD::ZERO_EXTEND);
438 setTargetDAGCombine(ISD::SIGN_EXTEND);
439 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michelfe095082008-07-16 17:17:29 +0000440
Scott Michel6e22c652007-12-04 22:23:35 +0000441 computeRegisterProperties();
Scott Michel0be03392008-11-22 23:50:42 +0000442
Scott Michel8deac5d2008-12-09 03:37:19 +0000443 // Set pre-RA register scheduler default to BURR, which produces slightly
444 // better code than the default (could also be TDRR, but TargetLowering.h
445 // needs a mod to support that model):
446 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel6e22c652007-12-04 22:23:35 +0000447}
448
449const char *
450SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
451{
452 if (node_names.empty()) {
453 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
454 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
455 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
456 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel8d5841a2008-01-11 02:53:15 +0000457 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelceae3bb2008-01-29 02:16:57 +0000458 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel6e22c652007-12-04 22:23:35 +0000459 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
460 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
461 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel0be03392008-11-22 23:50:42 +0000462 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel6e22c652007-12-04 22:23:35 +0000463 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelb8ee30d2008-12-29 03:23:36 +0000464 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelefc8c7a2008-11-24 17:11:17 +0000465 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel7d5eaec2008-02-23 18:41:37 +0000466 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
467 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel6e22c652007-12-04 22:23:35 +0000468 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
469 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
470 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
471 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
472 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Micheled7d79f2009-01-21 04:58:48 +0000473 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
474 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
475 "SPUISD::ROTBYTES_LEFT_BITS";
Scott Micheld831cc42008-06-02 22:18:03 +0000476 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel6e22c652007-12-04 22:23:35 +0000477 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michela292fc62009-01-15 04:41:47 +0000478 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
479 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
480 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel6e22c652007-12-04 22:23:35 +0000481 }
482
483 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
484
485 return ((i != node_names.end()) ? i->second : 0);
486}
487
Bill Wendling512ff732009-07-01 18:50:55 +0000488/// getFunctionAlignment - Return the Log2 alignment of this function.
Bill Wendling31ceb1b2009-06-30 22:38:32 +0000489unsigned SPUTargetLowering::getFunctionAlignment(const Function *) const {
490 return 3;
491}
492
Scott Michel82335272008-12-27 04:51:36 +0000493//===----------------------------------------------------------------------===//
494// Return the Cell SPU's SETCC result type
495//===----------------------------------------------------------------------===//
496
Duncan Sands8feb6942009-01-01 15:52:00 +0000497MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel82335272008-12-27 04:51:36 +0000498 // i16 and i32 are valid SETCC result types
499 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel48e33752008-03-10 16:58:52 +0000500}
501
Scott Michel6e22c652007-12-04 22:23:35 +0000502//===----------------------------------------------------------------------===//
503// Calling convention code:
504//===----------------------------------------------------------------------===//
505
506#include "SPUGenCallingConv.inc"
507
508//===----------------------------------------------------------------------===//
509// LowerOperation implementation
510//===----------------------------------------------------------------------===//
511
512/// Custom lower loads for CellSPU
513/*!
514 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
515 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel40f54d22008-12-04 03:02:42 +0000516
517 For extending loads, we also want to ensure that the following sequence is
518 emitted, e.g. for MVT::f32 extending load to MVT::f64:
519
520\verbatim
Scott Michelb8ee30d2008-12-29 03:23:36 +0000521%1 v16i8,ch = load
Scott Michel40f54d22008-12-04 03:02:42 +0000522%2 v16i8,ch = rotate %1
Scott Michelb8ee30d2008-12-29 03:23:36 +0000523%3 v4f8, ch = bitconvert %2
Scott Michel40f54d22008-12-04 03:02:42 +0000524%4 f32 = vec2perfslot %3
525%5 f64 = fp_extend %4
526\endverbatim
527*/
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000528static SDValue
529LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel6e22c652007-12-04 22:23:35 +0000530 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000531 SDValue the_chain = LN->getChain();
Scott Michel82335272008-12-27 04:51:36 +0000532 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel40f54d22008-12-04 03:02:42 +0000533 MVT InVT = LN->getMemoryVT();
534 MVT OutVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000535 ISD::LoadExtType ExtType = LN->getExtensionType();
536 unsigned alignment = LN->getAlignment();
Scott Michel82335272008-12-27 04:51:36 +0000537 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Dale Johannesen021052a2009-02-04 20:06:27 +0000538 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +0000539
Scott Michel6e22c652007-12-04 22:23:35 +0000540 switch (LN->getAddressingMode()) {
541 case ISD::UNINDEXED: {
Scott Michel82335272008-12-27 04:51:36 +0000542 SDValue result;
543 SDValue basePtr = LN->getBasePtr();
544 SDValue rotate;
Scott Michel6e22c652007-12-04 22:23:35 +0000545
Scott Michel82335272008-12-27 04:51:36 +0000546 if (alignment == 16) {
547 ConstantSDNode *CN;
Scott Michel8d5841a2008-01-11 02:53:15 +0000548
Scott Michel82335272008-12-27 04:51:36 +0000549 // Special cases for a known aligned load to simplify the base pointer
550 // and the rotation amount:
551 if (basePtr.getOpcode() == ISD::ADD
552 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
553 // Known offset into basePtr
554 int64_t offset = CN->getSExtValue();
555 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Michel8d5841a2008-01-11 02:53:15 +0000556
Scott Michel82335272008-12-27 04:51:36 +0000557 if (rotamt < 0)
558 rotamt += 16;
559
560 rotate = DAG.getConstant(rotamt, MVT::i16);
561
562 // Simplify the base pointer for this case:
563 basePtr = basePtr.getOperand(0);
564 if ((offset & ~0xf) > 0) {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000565 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000566 basePtr,
567 DAG.getConstant((offset & ~0xf), PtrVT));
568 }
569 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
570 || (basePtr.getOpcode() == SPUISD::IndirectAddr
571 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
572 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
573 // Plain aligned a-form address: rotate into preferred slot
574 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
575 int64_t rotamt = -vtm->prefslot_byte;
576 if (rotamt < 0)
577 rotamt += 16;
578 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Michel8d5841a2008-01-11 02:53:15 +0000579 } else {
Scott Michel82335272008-12-27 04:51:36 +0000580 // Offset the rotate amount by the basePtr and the preferred slot
581 // byte offset
582 int64_t rotamt = -vtm->prefslot_byte;
583 if (rotamt < 0)
584 rotamt += 16;
Dale Johannesen021052a2009-02-04 20:06:27 +0000585 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000586 basePtr,
Scott Michelbb713ae2008-01-30 02:55:46 +0000587 DAG.getConstant(rotamt, PtrVT));
Scott Michel8d5841a2008-01-11 02:53:15 +0000588 }
Scott Michel82335272008-12-27 04:51:36 +0000589 } else {
590 // Unaligned load: must be more pessimistic about addressing modes:
591 if (basePtr.getOpcode() == ISD::ADD) {
592 MachineFunction &MF = DAG.getMachineFunction();
593 MachineRegisterInfo &RegInfo = MF.getRegInfo();
594 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
595 SDValue Flag;
Scott Michel8d5841a2008-01-11 02:53:15 +0000596
Scott Michel82335272008-12-27 04:51:36 +0000597 SDValue Op0 = basePtr.getOperand(0);
598 SDValue Op1 = basePtr.getOperand(1);
599
600 if (isa<ConstantSDNode>(Op1)) {
601 // Convert the (add <ptr>, <const>) to an indirect address contained
602 // in a register. Note that this is done because we need to avoid
603 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000604 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen021052a2009-02-04 20:06:27 +0000605 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
606 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michel82335272008-12-27 04:51:36 +0000607 } else {
608 // Convert the (add <arg1>, <arg2>) to an indirect address, which
609 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000610 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel82335272008-12-27 04:51:36 +0000611 }
612 } else {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000613 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000614 basePtr,
615 DAG.getConstant(0, PtrVT));
616 }
617
618 // Offset the rotate amount by the basePtr and the preferred slot
619 // byte offset
Dale Johannesen021052a2009-02-04 20:06:27 +0000620 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000621 basePtr,
622 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel6e22c652007-12-04 22:23:35 +0000623 }
Scott Michel8d5841a2008-01-11 02:53:15 +0000624
Scott Michel82335272008-12-27 04:51:36 +0000625 // Re-emit as a v16i8 vector load
Dale Johannesen021052a2009-02-04 20:06:27 +0000626 result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel82335272008-12-27 04:51:36 +0000627 LN->getSrcValue(), LN->getSrcValueOffset(),
628 LN->isVolatile(), 16);
629
630 // Update the chain
631 the_chain = result.getValue(1);
632
633 // Rotate into the preferred slot:
Dale Johannesen021052a2009-02-04 20:06:27 +0000634 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::v16i8,
Scott Michel82335272008-12-27 04:51:36 +0000635 result.getValue(0), rotate);
636
Scott Michel40f54d22008-12-04 03:02:42 +0000637 // Convert the loaded v16i8 vector to the appropriate vector type
638 // specified by the operand:
639 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
Dale Johannesen021052a2009-02-04 20:06:27 +0000640 result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT,
641 DAG.getNode(ISD::BIT_CONVERT, dl, vecVT, result));
Scott Michelfe095082008-07-16 17:17:29 +0000642
Scott Michel40f54d22008-12-04 03:02:42 +0000643 // Handle extending loads by extending the scalar result:
644 if (ExtType == ISD::SEXTLOAD) {
Dale Johannesen021052a2009-02-04 20:06:27 +0000645 result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result);
Scott Michel40f54d22008-12-04 03:02:42 +0000646 } else if (ExtType == ISD::ZEXTLOAD) {
Dale Johannesen021052a2009-02-04 20:06:27 +0000647 result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result);
Scott Michel40f54d22008-12-04 03:02:42 +0000648 } else if (ExtType == ISD::EXTLOAD) {
649 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Michel8d5841a2008-01-11 02:53:15 +0000650
Scott Michel40f54d22008-12-04 03:02:42 +0000651 if (OutVT.isFloatingPoint())
Scott Michel95b2a202009-01-26 03:37:41 +0000652 NewOpc = ISD::FP_EXTEND;
Scott Michel8d5841a2008-01-11 02:53:15 +0000653
Dale Johannesen021052a2009-02-04 20:06:27 +0000654 result = DAG.getNode(NewOpc, dl, OutVT, result);
Scott Michel8d5841a2008-01-11 02:53:15 +0000655 }
656
Scott Michel40f54d22008-12-04 03:02:42 +0000657 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000658 SDValue retops[2] = {
Scott Michele4d3e3c2008-01-17 20:38:41 +0000659 result,
Scott Michelbb713ae2008-01-30 02:55:46 +0000660 the_chain
Scott Michele4d3e3c2008-01-17 20:38:41 +0000661 };
Scott Michel8d5841a2008-01-11 02:53:15 +0000662
Dale Johannesen021052a2009-02-04 20:06:27 +0000663 result = DAG.getNode(SPUISD::LDRESULT, dl, retvts,
Scott Michele4d3e3c2008-01-17 20:38:41 +0000664 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel8d5841a2008-01-11 02:53:15 +0000665 return result;
Scott Michel6e22c652007-12-04 22:23:35 +0000666 }
667 case ISD::PRE_INC:
668 case ISD::PRE_DEC:
669 case ISD::POST_INC:
670 case ISD::POST_DEC:
671 case ISD::LAST_INDEXED_MODE:
Torok Edwinfb8d6d52009-07-08 20:53:28 +0000672 {
673 std::string msg;
674 raw_string_ostream Msg(msg);
675 Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
Scott Michel6e22c652007-12-04 22:23:35 +0000676 "UNINDEXED\n";
Torok Edwinfb8d6d52009-07-08 20:53:28 +0000677 Msg << (unsigned) LN->getAddressingMode();
678 llvm_report_error(Msg.str());
679 /*NOTREACHED*/
680 }
Scott Michel6e22c652007-12-04 22:23:35 +0000681 }
682
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000683 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000684}
685
686/// Custom lower stores for CellSPU
687/*!
688 All CellSPU stores are aligned to 16-byte boundaries, so for elements
689 within a 16-byte block, we have to generate a shuffle to insert the
690 requested element into its place, then store the resulting block.
691 */
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000692static SDValue
693LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel6e22c652007-12-04 22:23:35 +0000694 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000695 SDValue Value = SN->getValue();
Duncan Sands13237ac2008-06-06 12:08:01 +0000696 MVT VT = Value.getValueType();
697 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
698 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Dale Johannesen021052a2009-02-04 20:06:27 +0000699 DebugLoc dl = Op.getDebugLoc();
Scott Michel8d5841a2008-01-11 02:53:15 +0000700 unsigned alignment = SN->getAlignment();
Scott Michel6e22c652007-12-04 22:23:35 +0000701
702 switch (SN->getAddressingMode()) {
703 case ISD::UNINDEXED: {
Scott Michelc6918c12008-11-21 02:56:16 +0000704 // The vector type we really want to load from the 16-byte chunk.
Scott Michelef5e6932008-11-19 17:45:08 +0000705 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
706 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel6e22c652007-12-04 22:23:35 +0000707
Scott Michel82335272008-12-27 04:51:36 +0000708 SDValue alignLoadVec;
709 SDValue basePtr = SN->getBasePtr();
710 SDValue the_chain = SN->getChain();
711 SDValue insertEltOffs;
Scott Michel6e22c652007-12-04 22:23:35 +0000712
Scott Michel82335272008-12-27 04:51:36 +0000713 if (alignment == 16) {
714 ConstantSDNode *CN;
715
716 // Special cases for a known aligned load to simplify the base pointer
717 // and insertion byte:
718 if (basePtr.getOpcode() == ISD::ADD
719 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
720 // Known offset into basePtr
721 int64_t offset = CN->getSExtValue();
722
723 // Simplify the base pointer for this case:
724 basePtr = basePtr.getOperand(0);
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000725 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000726 basePtr,
727 DAG.getConstant((offset & 0xf), PtrVT));
728
729 if ((offset & ~0xf) > 0) {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000730 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000731 basePtr,
732 DAG.getConstant((offset & ~0xf), PtrVT));
733 }
734 } else {
735 // Otherwise, assume it's at byte 0 of basePtr
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000736 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000737 basePtr,
738 DAG.getConstant(0, PtrVT));
739 }
740 } else {
741 // Unaligned load: must be more pessimistic about addressing modes:
742 if (basePtr.getOpcode() == ISD::ADD) {
743 MachineFunction &MF = DAG.getMachineFunction();
744 MachineRegisterInfo &RegInfo = MF.getRegInfo();
745 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
746 SDValue Flag;
747
748 SDValue Op0 = basePtr.getOperand(0);
749 SDValue Op1 = basePtr.getOperand(1);
750
751 if (isa<ConstantSDNode>(Op1)) {
752 // Convert the (add <ptr>, <const>) to an indirect address contained
753 // in a register. Note that this is done because we need to avoid
754 // creating a 0(reg) d-form address due to the SPU's block loads.
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000755 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesen021052a2009-02-04 20:06:27 +0000756 the_chain = DAG.getCopyToReg(the_chain, dl, VReg, basePtr, Flag);
757 basePtr = DAG.getCopyFromReg(the_chain, dl, VReg, PtrVT);
Scott Michel82335272008-12-27 04:51:36 +0000758 } else {
759 // Convert the (add <arg1>, <arg2>) to an indirect address, which
760 // will likely be lowered as a reg(reg) x-form address.
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000761 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel82335272008-12-27 04:51:36 +0000762 }
763 } else {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000764 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000765 basePtr,
766 DAG.getConstant(0, PtrVT));
767 }
768
769 // Insertion point is solely determined by basePtr's contents
Dale Johannesen021052a2009-02-04 20:06:27 +0000770 insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel82335272008-12-27 04:51:36 +0000771 basePtr,
772 DAG.getConstant(0, PtrVT));
773 }
774
775 // Re-emit as a v16i8 vector load
Dale Johannesen021052a2009-02-04 20:06:27 +0000776 alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel82335272008-12-27 04:51:36 +0000777 SN->getSrcValue(), SN->getSrcValueOffset(),
778 SN->isVolatile(), 16);
779
780 // Update the chain
781 the_chain = alignLoadVec.getValue(1);
Scott Michel6e22c652007-12-04 22:23:35 +0000782
Scott Michel8d5841a2008-01-11 02:53:15 +0000783 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000784 SDValue theValue = SN->getValue();
785 SDValue result;
Scott Michel6e22c652007-12-04 22:23:35 +0000786
787 if (StVT != VT
Scott Michelbb713ae2008-01-30 02:55:46 +0000788 && (theValue.getOpcode() == ISD::AssertZext
789 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel6e22c652007-12-04 22:23:35 +0000790 // Drill down and get the value for zero- and sign-extended
791 // quantities
Scott Michelfe095082008-07-16 17:17:29 +0000792 theValue = theValue.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +0000793 }
794
Scott Michel8d5841a2008-01-11 02:53:15 +0000795 // If the base pointer is already a D-form address, then just create
796 // a new D-form address with a slot offset and the orignal base pointer.
797 // Otherwise generate a D-form address with the slot offset relative
798 // to the stack pointer, which is always aligned.
Scott Michel82335272008-12-27 04:51:36 +0000799#if !defined(NDEBUG)
800 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
801 cerr << "CellSPU LowerSTORE: basePtr = ";
802 basePtr.getNode()->dump(&DAG);
803 cerr << "\n";
804 }
805#endif
Scott Michel8d5841a2008-01-11 02:53:15 +0000806
Scott Michel3462c8e2008-11-19 15:24:16 +0000807 SDValue insertEltOp =
Dale Johannesen021052a2009-02-04 20:06:27 +0000808 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, insertEltOffs);
Scott Michelef5e6932008-11-19 17:45:08 +0000809 SDValue vectorizeOp =
Dale Johannesen021052a2009-02-04 20:06:27 +0000810 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, theValue);
Scott Michel3462c8e2008-11-19 15:24:16 +0000811
Dale Johannesen021052a2009-02-04 20:06:27 +0000812 result = DAG.getNode(SPUISD::SHUFB, dl, vecVT,
Scott Michel95b2a202009-01-26 03:37:41 +0000813 vectorizeOp, alignLoadVec,
Scott Micheld1db1ab2009-03-16 18:47:25 +0000814 DAG.getNode(ISD::BIT_CONVERT, dl,
Dale Johannesen021052a2009-02-04 20:06:27 +0000815 MVT::v4i32, insertEltOp));
Scott Michel6e22c652007-12-04 22:23:35 +0000816
Dale Johannesen021052a2009-02-04 20:06:27 +0000817 result = DAG.getStore(the_chain, dl, result, basePtr,
Scott Michel6e22c652007-12-04 22:23:35 +0000818 LN->getSrcValue(), LN->getSrcValueOffset(),
819 LN->isVolatile(), LN->getAlignment());
820
Scott Michel187250b2008-12-04 17:16:59 +0000821#if 0 && !defined(NDEBUG)
Scott Michel3462c8e2008-11-19 15:24:16 +0000822 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
823 const SDValue &currentRoot = DAG.getRoot();
824
825 DAG.setRoot(result);
826 cerr << "------- CellSPU:LowerStore result:\n";
827 DAG.dump();
828 cerr << "-------\n";
829 DAG.setRoot(currentRoot);
830 }
831#endif
Scott Michel73640252008-12-02 19:53:53 +0000832
Scott Michel6e22c652007-12-04 22:23:35 +0000833 return result;
834 /*UNREACHED*/
835 }
836 case ISD::PRE_INC:
837 case ISD::PRE_DEC:
838 case ISD::POST_INC:
839 case ISD::POST_DEC:
840 case ISD::LAST_INDEXED_MODE:
Torok Edwinfb8d6d52009-07-08 20:53:28 +0000841 {
842 std::string msg;
843 raw_string_ostream Msg(msg);
844 Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
Scott Michel6e22c652007-12-04 22:23:35 +0000845 "UNINDEXED\n";
Torok Edwinfb8d6d52009-07-08 20:53:28 +0000846 Msg << (unsigned) SN->getAddressingMode();
847 llvm_report_error(Msg.str());
848 /*NOTREACHED*/
849 }
Scott Michel6e22c652007-12-04 22:23:35 +0000850 }
851
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000852 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000853}
854
Scott Michela292fc62009-01-15 04:41:47 +0000855//! Generate the address of a constant pool entry.
856SDValue
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000857LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000858 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000859 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
860 Constant *C = CP->getConstVal();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000861 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
862 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8d5841a2008-01-11 02:53:15 +0000863 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000864 // FIXME there is no actual debug info here
865 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +0000866
867 if (TM.getRelocationModel() == Reloc::Static) {
868 if (!ST->usingLargeMem()) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000869 // Just return the SDValue with the constant pool address in it.
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000870 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero);
Scott Michel6e22c652007-12-04 22:23:35 +0000871 } else {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000872 SDValue Hi = DAG.getNode(SPUISD::Hi, dl, PtrVT, CPI, Zero);
873 SDValue Lo = DAG.getNode(SPUISD::Lo, dl, PtrVT, CPI, Zero);
874 return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
Scott Michel6e22c652007-12-04 22:23:35 +0000875 }
876 }
877
Torok Edwinfbcc6632009-07-14 16:55:14 +0000878 llvm_unreachable("LowerConstantPool: Relocation model other than static"
Torok Edwin6cdb8972009-07-14 12:22:58 +0000879 " not supported.");
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000880 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000881}
882
Scott Michela292fc62009-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 Gohman2ce6f2a2008-07-27 21:46:04 +0000889static SDValue
890LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000891 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000892 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000893 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
894 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel6e22c652007-12-04 22:23:35 +0000895 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000896 // FIXME there is no actual debug info here
897 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +0000898
899 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel7d5eaec2008-02-23 18:41:37 +0000900 if (!ST->usingLargeMem()) {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000901 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero);
Scott Michel7d5eaec2008-02-23 18:41:37 +0000902 } else {
Dale Johannesen400dc2e2009-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 Michel7d5eaec2008-02-23 18:41:37 +0000906 }
Scott Michel6e22c652007-12-04 22:23:35 +0000907 }
908
Torok Edwinfbcc6632009-07-14 16:55:14 +0000909 llvm_unreachable("LowerJumpTable: Relocation model other than static"
Torok Edwin6cdb8972009-07-14 12:22:58 +0000910 " not supported.");
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000911 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000912}
913
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000914static SDValue
915LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000916 MVT PtrVT = Op.getValueType();
Scott Michel6e22c652007-12-04 22:23:35 +0000917 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
918 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000919 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel6e22c652007-12-04 22:23:35 +0000920 const TargetMachine &TM = DAG.getTarget();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000921 SDValue Zero = DAG.getConstant(0, PtrVT);
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000922 // FIXME there is no actual debug info here
923 DebugLoc dl = Op.getDebugLoc();
Scott Michelfe095082008-07-16 17:17:29 +0000924
Scott Michel6e22c652007-12-04 22:23:35 +0000925 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelceae3bb2008-01-29 02:16:57 +0000926 if (!ST->usingLargeMem()) {
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000927 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero);
Scott Michelceae3bb2008-01-29 02:16:57 +0000928 } else {
Dale Johannesen400dc2e2009-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 Michelceae3bb2008-01-29 02:16:57 +0000932 }
Scott Michel6e22c652007-12-04 22:23:35 +0000933 } else {
Torok Edwinfb8d6d52009-07-08 20:53:28 +0000934 llvm_report_error("LowerGlobalAddress: Relocation model other than static"
935 "not supported.");
Scott Michel6e22c652007-12-04 22:23:35 +0000936 /*NOTREACHED*/
937 }
938
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000939 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000940}
941
Nate Begeman4b3210a2008-02-14 18:43:04 +0000942//! Custom lower double precision floating point constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000943static SDValue
944LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000945 MVT VT = Op.getValueType();
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000946 // FIXME there is no actual debug info here
947 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +0000948
Nate Begeman4b3210a2008-02-14 18:43:04 +0000949 if (VT == MVT::f64) {
Scott Michel08a4e202008-12-01 17:56:02 +0000950 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
951
952 assert((FP != 0) &&
953 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelb8ee30d2008-12-29 03:23:36 +0000954
Scott Michel098c1132007-12-19 20:15:47 +0000955 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel08a4e202008-12-01 17:56:02 +0000956 SDValue T = DAG.getConstant(dbits, MVT::i64);
Evan Chenga49de9d2009-02-25 22:49:59 +0000957 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T);
Dale Johannesen400dc2e2009-02-06 21:50:26 +0000958 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
Dale Johannesen62fd95d2009-02-07 00:55:49 +0000959 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Tvec));
Scott Michel6e22c652007-12-04 22:23:35 +0000960 }
961
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000962 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +0000963}
964
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000965static SDValue
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000966LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel6e22c652007-12-04 22:23:35 +0000967{
968 MachineFunction &MF = DAG.getMachineFunction();
969 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera10fff52007-12-31 04:13:23 +0000970 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel487c4342008-10-30 01:51:48 +0000971 SmallVector<SDValue, 48> ArgValues;
Dan Gohman2ce6f2a2008-07-27 21:46:04 +0000972 SDValue Root = Op.getOperand(0);
Dan Gohmaneffb8942008-09-12 16:56:44 +0000973 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Dale Johannesen021052a2009-02-04 20:06:27 +0000974 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +0000975
976 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
977 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michelfe095082008-07-16 17:17:29 +0000978
Scott Michel6e22c652007-12-04 22:23:35 +0000979 unsigned ArgOffset = SPUFrameInfo::minStackSize();
980 unsigned ArgRegIdx = 0;
981 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michelfe095082008-07-16 17:17:29 +0000982
Duncan Sands13237ac2008-06-06 12:08:01 +0000983 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michelfe095082008-07-16 17:17:29 +0000984
Scott Michel6e22c652007-12-04 22:23:35 +0000985 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif81d6a382008-08-31 15:37:04 +0000986 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
987 ArgNo != e; ++ArgNo) {
Duncan Sands13237ac2008-06-06 12:08:01 +0000988 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
989 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michel487c4342008-10-30 01:51:48 +0000990 SDValue ArgVal;
Scott Michel6e22c652007-12-04 22:23:35 +0000991
Scott Michel487c4342008-10-30 01:51:48 +0000992 if (ArgRegIdx < NumArgRegs) {
993 const TargetRegisterClass *ArgRegClass;
Scott Michelfe095082008-07-16 17:17:29 +0000994
Scott Michel487c4342008-10-30 01:51:48 +0000995 switch (ObjectVT.getSimpleVT()) {
996 default: {
Torok Edwinfb8d6d52009-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 Michel487c4342008-10-30 01:51:48 +00001002 }
1003 case MVT::i8:
Scott Michelc6918c12008-11-21 02:56:16 +00001004 ArgRegClass = &SPU::R8CRegClass;
1005 break;
Scott Michel487c4342008-10-30 01:51:48 +00001006 case MVT::i16:
Scott Michelc6918c12008-11-21 02:56:16 +00001007 ArgRegClass = &SPU::R16CRegClass;
1008 break;
Scott Michel487c4342008-10-30 01:51:48 +00001009 case MVT::i32:
Scott Michelc6918c12008-11-21 02:56:16 +00001010 ArgRegClass = &SPU::R32CRegClass;
1011 break;
Scott Michel487c4342008-10-30 01:51:48 +00001012 case MVT::i64:
Scott Michelc6918c12008-11-21 02:56:16 +00001013 ArgRegClass = &SPU::R64CRegClass;
1014 break;
Scott Michel6887caf2009-01-06 03:36:14 +00001015 case MVT::i128:
1016 ArgRegClass = &SPU::GPRCRegClass;
1017 break;
Scott Michel487c4342008-10-30 01:51:48 +00001018 case MVT::f32:
Scott Michelc6918c12008-11-21 02:56:16 +00001019 ArgRegClass = &SPU::R32FPRegClass;
1020 break;
Scott Michel487c4342008-10-30 01:51:48 +00001021 case MVT::f64:
Scott Michelc6918c12008-11-21 02:56:16 +00001022 ArgRegClass = &SPU::R64FPRegClass;
1023 break;
Scott Michel487c4342008-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 Michelc6918c12008-11-21 02:56:16 +00001030 ArgRegClass = &SPU::VECREGRegClass;
1031 break;
Scott Michel487c4342008-10-30 01:51:48 +00001032 }
1033
1034 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
1035 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Dale Johannesen021052a2009-02-04 20:06:27 +00001036 ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT);
Scott Michel487c4342008-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 Lattnerf6518cf2008-02-13 07:35:30 +00001042 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001043 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Dale Johannesen021052a2009-02-04 20:06:27 +00001044 ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0);
Scott Michel6e22c652007-12-04 22:23:35 +00001045 ArgOffset += StackSlotSize;
1046 }
Scott Michelfe095082008-07-16 17:17:29 +00001047
Scott Michel6e22c652007-12-04 22:23:35 +00001048 ArgValues.push_back(ArgVal);
Scott Michel487c4342008-10-30 01:51:48 +00001049 // Update the chain
1050 Root = ArgVal.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +00001051 }
Scott Michelfe095082008-07-16 17:17:29 +00001052
Scott Michel487c4342008-10-30 01:51:48 +00001053 // vararg handling:
Scott Michel6e22c652007-12-04 22:23:35 +00001054 if (isVarArg) {
Scott Michel487c4342008-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 Michel6e22c652007-12-04 22:23:35 +00001061 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michel487c4342008-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 Johannesen021052a2009-02-04 20:06:27 +00001065 SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0);
Scott Michel487c4342008-10-30 01:51:48 +00001066 Root = Store.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +00001067 MemOps.push_back(Store);
Scott Michel487c4342008-10-30 01:51:48 +00001068
1069 // Increment address by stack slot size for the next stored argument
1070 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001071 }
1072 if (!MemOps.empty())
Scott Micheld1db1ab2009-03-16 18:47:25 +00001073 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Dale Johannesen021052a2009-02-04 20:06:27 +00001074 &MemOps[0], MemOps.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001075 }
Scott Michelfe095082008-07-16 17:17:29 +00001076
Scott Michel6e22c652007-12-04 22:23:35 +00001077 ArgValues.push_back(Root);
Scott Michelfe095082008-07-16 17:17:29 +00001078
Scott Michel6e22c652007-12-04 22:23:35 +00001079 // Return the new list of results.
Dale Johannesen021052a2009-02-04 20:06:27 +00001080 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
Duncan Sands3d960942008-12-01 11:41:29 +00001081 &ArgValues[0], ArgValues.size());
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001086static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michelaab89ca2008-11-11 03:06:06 +00001087 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel6e22c652007-12-04 22:23:35 +00001088 if (!C) return 0;
Scott Michelfe095082008-07-16 17:17:29 +00001089
Dan Gohmaneffb8942008-09-12 16:56:44 +00001090 int Addr = C->getZExtValue();
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00001094
Dan Gohmaneffb8942008-09-12 16:56:44 +00001095 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel6e22c652007-12-04 22:23:35 +00001096}
1097
Scott Michel494daa72009-01-06 23:10:38 +00001098static SDValue
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001099LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohmand3fe1742008-09-13 01:54:27 +00001100 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1101 SDValue Chain = TheCall->getChain();
Dan Gohmand3fe1742008-09-13 01:54:27 +00001102 SDValue Callee = TheCall->getCallee();
1103 unsigned NumOps = TheCall->getNumArgs();
Scott Michel6e22c652007-12-04 22:23:35 +00001104 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1105 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1106 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Dale Johannesen021052a2009-02-04 20:06:27 +00001107 DebugLoc dl = TheCall->getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +00001108
1109 // Handy pointer type
Duncan Sands13237ac2008-06-06 12:08:01 +00001110 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michelfe095082008-07-16 17:17:29 +00001111
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00001116
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001120 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michelfe095082008-07-16 17:17:29 +00001121
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001128 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel6e22c652007-12-04 22:23:35 +00001129 // And the arguments passed on the stack
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001130 SmallVector<SDValue, 8> MemOpChains;
Scott Michel6e22c652007-12-04 22:23:35 +00001131
1132 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohmand3fe1742008-09-13 01:54:27 +00001133 SDValue Arg = TheCall->getArg(i);
Scott Michelfe095082008-07-16 17:17:29 +00001134
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001137 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Dale Johannesen021052a2009-02-04 20:06:27 +00001138 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
Scott Michel6e22c652007-12-04 22:23:35 +00001139
Duncan Sands13237ac2008-06-06 12:08:01 +00001140 switch (Arg.getValueType().getSimpleVT()) {
Torok Edwinfbcc6632009-07-14 16:55:14 +00001141 default: llvm_unreachable("Unexpected ValueType for argument!");
Scott Michel6887caf2009-01-06 03:36:14 +00001142 case MVT::i8:
1143 case MVT::i16:
Scott Michel6e22c652007-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 Johannesen021052a2009-02-04 20:06:27 +00001150 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001151 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-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 Johannesen021052a2009-02-04 20:06:27 +00001159 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001160 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-12-04 22:23:35 +00001161 }
1162 break;
Scott Michelea3c49d2008-12-04 21:01:44 +00001163 case MVT::v2i64:
1164 case MVT::v2f64:
Scott Michel6e22c652007-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 Johannesen021052a2009-02-04 20:06:27 +00001172 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michelbb713ae2008-01-30 02:55:46 +00001173 ArgOffset += StackSlotSize;
Scott Michel6e22c652007-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 Lattner27539552008-10-11 22:08:30 +00001181 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1182 true));
Scott Michel6e22c652007-12-04 22:23:35 +00001183
1184 if (!MemOpChains.empty()) {
1185 // Adjust the stack pointer for the stack arguments.
Dale Johannesen021052a2009-02-04 20:06:27 +00001186 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Scott Michel6e22c652007-12-04 22:23:35 +00001187 &MemOpChains[0], MemOpChains.size());
1188 }
Scott Michelfe095082008-07-16 17:17:29 +00001189
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001192 SDValue InFlag;
Scott Michel6e22c652007-12-04 22:23:35 +00001193 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
Scott Micheld1db1ab2009-03-16 18:47:25 +00001194 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
Dale Johannesen021052a2009-02-04 20:06:27 +00001195 RegsToPass[i].second, InFlag);
Scott Michel6e22c652007-12-04 22:23:35 +00001196 InFlag = Chain.getValue(1);
1197 }
Scott Michelfe095082008-07-16 17:17:29 +00001198
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001199 SmallVector<SDValue, 8> Ops;
Scott Michel6e22c652007-12-04 22:23:35 +00001200 unsigned CallOpc = SPUISD::CALL;
Scott Michelfe095082008-07-16 17:17:29 +00001201
Bill Wendling24c79f22008-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 Michelaab89ca2008-11-11 03:06:06 +00001205 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001206 GlobalValue *GV = G->getGlobal();
Duncan Sands13237ac2008-06-06 12:08:01 +00001207 MVT CalleeVT = Callee.getValueType();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001208 SDValue Zero = DAG.getConstant(0, PtrVT);
1209 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel6e22c652007-12-04 22:23:35 +00001210
Scott Michel8d5841a2008-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 Johannesen400dc2e2009-02-06 21:50:26 +00001221 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero);
Scott Michel8d5841a2008-01-11 02:53:15 +00001222 } else {
Dale Johannesen400dc2e2009-02-06 21:50:26 +00001223 Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero);
Scott Michel8d5841a2008-01-11 02:53:15 +00001224 }
Scott Michel6e22c652007-12-04 22:23:35 +00001225 } else {
Scott Michel8d5841a2008-01-11 02:53:15 +00001226 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1227 // address pairs:
Dale Johannesen400dc2e2009-02-06 21:50:26 +00001228 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero);
Scott Michel6e22c652007-12-04 22:23:35 +00001229 }
Scott Michelb8ee30d2008-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 Johannesen400dc2e2009-02-06 21:50:26 +00001237 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero);
Scott Michelb8ee30d2008-12-29 03:23:36 +00001238 } else {
Dale Johannesen400dc2e2009-02-06 21:50:26 +00001239 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero);
Scott Michelb8ee30d2008-12-29 03:23:36 +00001240 }
1241 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001244 Callee = SDValue(Dest, 0);
Scott Michel8d5841a2008-01-11 02:53:15 +00001245 }
Scott Michel6e22c652007-12-04 22:23:35 +00001246
1247 Ops.push_back(Chain);
1248 Ops.push_back(Callee);
Scott Michelfe095082008-07-16 17:17:29 +00001249
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00001253 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel6e22c652007-12-04 22:23:35 +00001254 RegsToPass[i].second.getValueType()));
Scott Michelfe095082008-07-16 17:17:29 +00001255
Gabor Greiff304a7a2008-08-28 21:40:38 +00001256 if (InFlag.getNode())
Scott Michel6e22c652007-12-04 22:23:35 +00001257 Ops.push_back(InFlag);
Duncan Sands739a0542008-07-02 17:40:58 +00001258 // Returns a chain and a flag for retval copy to use.
Dale Johannesen021052a2009-02-04 20:06:27 +00001259 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag),
Duncan Sands739a0542008-07-02 17:40:58 +00001260 &Ops[0], Ops.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001261 InFlag = Chain.getValue(1);
1262
Chris Lattner27539552008-10-11 22:08:30 +00001263 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1264 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohmand3fe1742008-09-13 01:54:27 +00001265 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng0f329162008-02-05 22:44:06 +00001266 InFlag = Chain.getValue(1);
1267
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001268 SDValue ResultVals[3];
Scott Michel6e22c652007-12-04 22:23:35 +00001269 unsigned NumResults = 0;
Scott Michelfe095082008-07-16 17:17:29 +00001270
Scott Michel6e22c652007-12-04 22:23:35 +00001271 // If the call has results, copy the values out of the ret val registers.
Dan Gohmand3fe1742008-09-13 01:54:27 +00001272 switch (TheCall->getValueType(0).getSimpleVT()) {
Torok Edwinfbcc6632009-07-14 16:55:14 +00001273 default: llvm_unreachable("Unexpected ret value!");
Scott Michel6e22c652007-12-04 22:23:35 +00001274 case MVT::Other: break;
1275 case MVT::i32:
Dan Gohmand3fe1742008-09-13 01:54:27 +00001276 if (TheCall->getValueType(1) == MVT::i32) {
Scott Micheld1db1ab2009-03-16 18:47:25 +00001277 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4,
Dale Johannesen021052a2009-02-04 20:06:27 +00001278 MVT::i32, InFlag).getValue(1);
Scott Michel6e22c652007-12-04 22:23:35 +00001279 ResultVals[0] = Chain.getValue(0);
Dale Johannesen021052a2009-02-04 20:06:27 +00001280 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Scott Michel6e22c652007-12-04 22:23:35 +00001281 Chain.getValue(2)).getValue(1);
1282 ResultVals[1] = Chain.getValue(0);
1283 NumResults = 2;
Scott Michel6e22c652007-12-04 22:23:35 +00001284 } else {
Scott Micheld1db1ab2009-03-16 18:47:25 +00001285 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Dale Johannesen021052a2009-02-04 20:06:27 +00001286 InFlag).getValue(1);
Scott Michel6e22c652007-12-04 22:23:35 +00001287 ResultVals[0] = Chain.getValue(0);
1288 NumResults = 1;
1289 }
Scott Michel6e22c652007-12-04 22:23:35 +00001290 break;
1291 case MVT::i64:
Scott Micheld1db1ab2009-03-16 18:47:25 +00001292 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64,
Dale Johannesen021052a2009-02-04 20:06:27 +00001293 InFlag).getValue(1);
Scott Michel6e22c652007-12-04 22:23:35 +00001294 ResultVals[0] = Chain.getValue(0);
1295 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001296 break;
Scott Michel6887caf2009-01-06 03:36:14 +00001297 case MVT::i128:
Scott Micheld1db1ab2009-03-16 18:47:25 +00001298 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128,
Dale Johannesen021052a2009-02-04 20:06:27 +00001299 InFlag).getValue(1);
Scott Michel6887caf2009-01-06 03:36:14 +00001300 ResultVals[0] = Chain.getValue(0);
1301 NumResults = 1;
1302 break;
Scott Michel6e22c652007-12-04 22:23:35 +00001303 case MVT::f32:
1304 case MVT::f64:
Dale Johannesen021052a2009-02-04 20:06:27 +00001305 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel6e22c652007-12-04 22:23:35 +00001306 InFlag).getValue(1);
1307 ResultVals[0] = Chain.getValue(0);
1308 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001309 break;
1310 case MVT::v2f64:
Scott Michelea3c49d2008-12-04 21:01:44 +00001311 case MVT::v2i64:
Scott Michel6e22c652007-12-04 22:23:35 +00001312 case MVT::v4f32:
1313 case MVT::v4i32:
1314 case MVT::v8i16:
1315 case MVT::v16i8:
Dale Johannesen021052a2009-02-04 20:06:27 +00001316 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel6e22c652007-12-04 22:23:35 +00001317 InFlag).getValue(1);
1318 ResultVals[0] = Chain.getValue(0);
1319 NumResults = 1;
Scott Michel6e22c652007-12-04 22:23:35 +00001320 break;
1321 }
Duncan Sands739a0542008-07-02 17:40:58 +00001322
Scott Michel6e22c652007-12-04 22:23:35 +00001323 // If the function returns void, just return the chain.
1324 if (NumResults == 0)
1325 return Chain;
Scott Michelfe095082008-07-16 17:17:29 +00001326
Scott Michel6e22c652007-12-04 22:23:35 +00001327 // Otherwise, merge everything together with a MERGE_VALUES node.
1328 ResultVals[NumResults++] = Chain;
Dale Johannesen021052a2009-02-04 20:06:27 +00001329 SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl);
Gabor Greifabfdf922008-08-26 22:36:50 +00001330 return Res.getValue(Op.getResNo());
Scott Michel6e22c652007-12-04 22:23:35 +00001331}
1332
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001333static SDValue
1334LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel6e22c652007-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 Johannesenf08a47b2009-02-04 23:02:30 +00001338 DebugLoc dl = Op.getDebugLoc();
Owen Anderson0504e0a2009-07-09 17:57:24 +00001339 CCState CCInfo(CC, isVarArg, TM, RVLocs, DAG.getContext());
Gabor Greiff304a7a2008-08-28 21:40:38 +00001340 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michelfe095082008-07-16 17:17:29 +00001341
Scott Michel6e22c652007-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 Lattnera10fff52007-12-31 04:13:23 +00001344 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel6e22c652007-12-04 22:23:35 +00001345 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattnera10fff52007-12-31 04:13:23 +00001346 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel6e22c652007-12-04 22:23:35 +00001347 }
1348
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001349 SDValue Chain = Op.getOperand(0);
1350 SDValue Flag;
Scott Michelfe095082008-07-16 17:17:29 +00001351
Scott Michel6e22c652007-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 Johannesenf08a47b2009-02-04 23:02:30 +00001356 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
1357 Op.getOperand(i*2+1), Flag);
Scott Michel6e22c652007-12-04 22:23:35 +00001358 Flag = Chain.getValue(1);
1359 }
1360
Gabor Greiff304a7a2008-08-28 21:40:38 +00001361 if (Flag.getNode())
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001362 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
Scott Michel6e22c652007-12-04 22:23:35 +00001363 else
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001364 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain);
Scott Michel6e22c652007-12-04 22:23:35 +00001365}
1366
1367
1368//===----------------------------------------------------------------------===//
1369// Vector related lowering:
1370//===----------------------------------------------------------------------===//
1371
1372static ConstantSDNode *
1373getVecImm(SDNode *N) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001374 SDValue OpVal(0, 0);
Scott Michelfe095082008-07-16 17:17:29 +00001375
Scott Michel6e22c652007-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 Greiff304a7a2008-08-28 21:40:38 +00001379 if (OpVal.getNode() == 0)
Scott Michel6e22c652007-12-04 22:23:35 +00001380 OpVal = N->getOperand(i);
1381 else if (OpVal != N->getOperand(i))
1382 return 0;
1383 }
Scott Michelfe095082008-07-16 17:17:29 +00001384
Gabor Greiff304a7a2008-08-28 21:40:38 +00001385 if (OpVal.getNode() != 0) {
Scott Michelaab89ca2008-11-11 03:06:06 +00001386 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel6e22c652007-12-04 22:23:35 +00001387 return CN;
1388 }
1389 }
1390
Scott Michel839ad0a2009-03-17 01:15:45 +00001391 return 0;
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001397SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001398 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001399 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001400 uint64_t Value = CN->getZExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001401 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001402 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001406 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001407 Value = Value >> 32;
1408 }
Scott Michel6e22c652007-12-04 22:23:35 +00001409 if (Value <= 0x3ffff)
Dan Gohmanfd820522008-11-05 02:06:09 +00001410 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001411 }
1412
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001413 return SDValue();
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001419SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001420 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001421 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman6e054832008-09-26 21:54:37 +00001422 int64_t Value = CN->getSExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001423 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001424 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001428 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001429 Value = Value >> 32;
1430 }
Scott Michel42f56b42008-03-05 23:02:02 +00001431 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001432 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001433 }
1434 }
1435
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001436 return SDValue();
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001442SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001443 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001444 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman6e054832008-09-26 21:54:37 +00001445 int64_t Value = CN->getSExtValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001446 if (ValueType == MVT::i64) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001447 uint64_t UValue = CN->getZExtValue();
Scott Michele9b690b2008-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001451 return SDValue();
Scott Michele9b690b2008-03-06 04:02:54 +00001452 Value = Value >> 32;
1453 }
Scott Michel42f56b42008-03-05 23:02:02 +00001454 if (isS10Constant(Value))
Dan Gohmanfd820522008-11-05 02:06:09 +00001455 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001456 }
1457
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001458 return SDValue();
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001468SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001469 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001470 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001471 int Value = (int) CN->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001472 if (ValueType == MVT::i16
Scott Michelbb713ae2008-01-30 02:55:46 +00001473 && Value <= 0xffff /* truncated from uint64_t */
1474 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfd820522008-11-05 02:06:09 +00001475 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001476 else if (ValueType == MVT::i8
Scott Michelbb713ae2008-01-30 02:55:46 +00001477 && (Value & 0xff) == Value)
Dan Gohmanfd820522008-11-05 02:06:09 +00001478 return DAG.getTargetConstant(Value, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001479 }
1480
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001481 return SDValue();
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001487SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands13237ac2008-06-06 12:08:01 +00001488 MVT ValueType) {
Scott Michel6e22c652007-12-04 22:23:35 +00001489 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmaneffb8942008-09-12 16:56:44 +00001490 uint64_t Value = CN->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001491 if ((ValueType == MVT::i32
Scott Michelbb713ae2008-01-30 02:55:46 +00001492 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1493 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfd820522008-11-05 02:06:09 +00001494 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel6e22c652007-12-04 22:23:35 +00001495 }
1496
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001497 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001498}
1499
1500/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001501SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel6e22c652007-12-04 22:23:35 +00001502 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001503 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00001504 }
1505
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001506 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001507}
1508
1509/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001510SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel6e22c652007-12-04 22:23:35 +00001511 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfd820522008-11-05 02:06:09 +00001512 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel6e22c652007-12-04 22:23:35 +00001513 }
1514
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001515 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001516}
1517
Scott Micheled7d79f2009-01-21 04:58:48 +00001518//! Lower a BUILD_VECTOR instruction creatively:
1519SDValue
Scott Michel9e3e4a92009-01-26 03:31:40 +00001520LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00001521 MVT VT = Op.getValueType();
Scott Michel839ad0a2009-03-17 01:15:45 +00001522 MVT EltVT = VT.getVectorElementType();
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001523 DebugLoc dl = Op.getDebugLoc();
Scott Michel839ad0a2009-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 Michelfe095082008-07-16 17:17:29 +00001541
Duncan Sands13237ac2008-06-06 12:08:01 +00001542 switch (VT.getSimpleVT()) {
Torok Edwinfb8d6d52009-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 Micheled7d79f2009-01-21 04:58:48 +00001549 /*NOTREACHED*/
Torok Edwinfb8d6d52009-07-08 20:53:28 +00001550 }
Scott Michel6e22c652007-12-04 22:23:35 +00001551 case MVT::v4f32: {
Scott Michel9e3e4a92009-01-26 03:31:40 +00001552 uint32_t Value32 = uint32_t(SplatBits);
Chris Lattner78b7cbe2009-03-26 05:29:34 +00001553 assert(SplatBitSize == 32
Scott Michelbb713ae2008-01-30 02:55:46 +00001554 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel6e22c652007-12-04 22:23:35 +00001555 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001556 SDValue T = DAG.getConstant(Value32, MVT::i32);
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001557 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4f32,
Chris Lattner78b7cbe2009-03-26 05:29:34 +00001558 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T));
Scott Michel6e22c652007-12-04 22:23:35 +00001559 break;
1560 }
1561 case MVT::v2f64: {
Scott Michel9e3e4a92009-01-26 03:31:40 +00001562 uint64_t f64val = uint64_t(SplatBits);
Chris Lattner78b7cbe2009-03-26 05:29:34 +00001563 assert(SplatBitSize == 64
Scott Michelefc8c7a2008-11-24 17:11:17 +00001564 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel6e22c652007-12-04 22:23:35 +00001565 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001566 SDValue T = DAG.getConstant(f64val, MVT::i64);
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001567 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64,
Evan Chenga49de9d2009-02-25 22:49:59 +00001568 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T));
Scott Michel6e22c652007-12-04 22:23:35 +00001569 break;
1570 }
1571 case MVT::v16i8: {
1572 // 8-bit constants have to be expanded to 16-bits
Scott Michel839ad0a2009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001577 return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
Scott Michel839ad0a2009-03-17 01:15:45 +00001578 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size()));
Scott Michel6e22c652007-12-04 22:23:35 +00001579 }
1580 case MVT::v8i16: {
Scott Michel839ad0a2009-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 Michel6e22c652007-12-04 22:23:35 +00001587 }
1588 case MVT::v4i32: {
Scott Michel839ad0a2009-03-17 01:15:45 +00001589 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga49de9d2009-02-25 22:49:59 +00001590 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
Scott Michel6e22c652007-12-04 22:23:35 +00001591 }
Scott Michel494daa72009-01-06 23:10:38 +00001592 case MVT::v2i32: {
Scott Michel839ad0a2009-03-17 01:15:45 +00001593 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Chenga49de9d2009-02-25 22:49:59 +00001594 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T);
Scott Michel494daa72009-01-06 23:10:38 +00001595 }
Scott Michel6e22c652007-12-04 22:23:35 +00001596 case MVT::v2i64: {
Scott Michel839ad0a2009-03-17 01:15:45 +00001597 return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
Scott Michel6e22c652007-12-04 22:23:35 +00001598 }
1599 }
Scott Michelfe095082008-07-16 17:17:29 +00001600
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001601 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001602}
1603
Scott Michel839ad0a2009-03-17 01:15:45 +00001604/*!
1605 */
Scott Michel9e3e4a92009-01-26 03:31:40 +00001606SDValue
Scott Michel839ad0a2009-03-17 01:15:45 +00001607SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal,
1608 DebugLoc dl) {
Scott Michel9e3e4a92009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001615 return DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga49de9d2009-02-25 22:49:59 +00001616 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1617 Val, Val, Val, Val));
Scott Michel9e3e4a92009-01-26 03:31:40 +00001618 } else {
Scott Michel9e3e4a92009-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 Michel839ad0a2009-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 Michel9e3e4a92009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001644 LO32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga49de9d2009-02-25 22:49:59 +00001645 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1646 LO32C, LO32C, LO32C, LO32C));
Scott Michel9e3e4a92009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001652 HI32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Chenga49de9d2009-02-25 22:49:59 +00001653 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1654 HI32C, HI32C, HI32C, HI32C));
Scott Michel9e3e4a92009-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 Michel9e3e4a92009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001690 return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32,
Evan Chenga49de9d2009-02-25 22:49:59 +00001691 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1692 &ShufBytes[0], ShufBytes.size()));
Scott Michel9e3e4a92009-01-26 03:31:40 +00001693 }
1694}
1695
Scott Michel6e22c652007-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 Michel0be03392008-11-22 23:50:42 +00001700/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel6e22c652007-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 Michel0be03392008-11-22 23:50:42 +00001704/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00001709static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
Nate Begeman8d6d4b92009-04-27 18:41:29 +00001710 const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001711 SDValue V1 = Op.getOperand(0);
1712 SDValue V2 = Op.getOperand(1);
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001713 DebugLoc dl = Op.getDebugLoc();
Scott Michelfe095082008-07-16 17:17:29 +00001714
Scott Michel6e22c652007-12-04 22:23:35 +00001715 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michelfe095082008-07-16 17:17:29 +00001716
Scott Michel6e22c652007-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 Michelea3c49d2008-12-04 21:01:44 +00001720 MVT VecVT = V1.getValueType();
1721 MVT EltVT = VecVT.getVectorElementType();
Scott Michel6e22c652007-12-04 22:23:35 +00001722 unsigned EltsFromV2 = 0;
1723 unsigned V2Elt = 0;
1724 unsigned V2EltIdx0 = 0;
1725 unsigned CurrElt = 0;
Scott Michelea3c49d2008-12-04 21:01:44 +00001726 unsigned MaxElts = VecVT.getVectorNumElements();
1727 unsigned PrevElt = 0;
1728 unsigned V0Elt = 0;
Scott Michel6e22c652007-12-04 22:23:35 +00001729 bool monotonic = true;
Scott Michelea3c49d2008-12-04 21:01:44 +00001730 bool rotate = true;
1731
1732 if (EltVT == MVT::i8) {
Scott Michel6e22c652007-12-04 22:23:35 +00001733 V2EltIdx0 = 16;
Scott Michelea3c49d2008-12-04 21:01:44 +00001734 } else if (EltVT == MVT::i16) {
Scott Michel6e22c652007-12-04 22:23:35 +00001735 V2EltIdx0 = 8;
Scott Michelea3c49d2008-12-04 21:01:44 +00001736 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel6e22c652007-12-04 22:23:35 +00001737 V2EltIdx0 = 4;
Scott Michelea3c49d2008-12-04 21:01:44 +00001738 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1739 V2EltIdx0 = 2;
1740 } else
Torok Edwinfbcc6632009-07-14 16:55:14 +00001741 llvm_unreachable("Unhandled vector type in LowerVECTOR_SHUFFLE");
Scott Michel6e22c652007-12-04 22:23:35 +00001742
Nate Begeman8d6d4b92009-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 Michel6e22c652007-12-04 22:23:35 +00001748
Nate Begeman8d6d4b92009-04-27 18:41:29 +00001749 if (monotonic) {
1750 if (SrcElt >= V2EltIdx0) {
1751 if (1 >= (++EltsFromV2)) {
1752 V2Elt = (V2EltIdx0 - SrcElt) << 2;
Scott Michelea3c49d2008-12-04 21:01:44 +00001753 }
Nate Begeman8d6d4b92009-04-27 18:41:29 +00001754 } else if (CurrElt != SrcElt) {
1755 monotonic = false;
Scott Michelea3c49d2008-12-04 21:01:44 +00001756 }
1757
Nate Begeman8d6d4b92009-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 Michelea3c49d2008-12-04 21:01:44 +00001765 PrevElt = SrcElt;
Nate Begeman8d6d4b92009-04-27 18:41:29 +00001766 if (SrcElt == 0)
1767 V0Elt = i;
Scott Michelea3c49d2008-12-04 21:01:44 +00001768 } else {
Scott Michelea3c49d2008-12-04 21:01:44 +00001769 rotate = false;
1770 }
Nate Begeman8d6d4b92009-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 Michelea3c49d2008-12-04 21:01:44 +00001777 }
Scott Michel6e22c652007-12-04 22:23:35 +00001778 }
Scott Michel6e22c652007-12-04 22:23:35 +00001779 }
1780
1781 if (EltsFromV2 == 1 && monotonic) {
1782 // Compute mask and shuffle
1783 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00001784 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1785 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands13237ac2008-06-06 12:08:01 +00001786 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6e22c652007-12-04 22:23:35 +00001787 // Initialize temporary register to 0
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001788 SDValue InitTempReg =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001789 DAG.getCopyToReg(DAG.getEntryNode(), dl, VReg, DAG.getConstant(0, PtrVT));
Scott Michel0be03392008-11-22 23:50:42 +00001790 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001791 SDValue ShufMaskOp =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001792 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, MVT::v4i32,
Scott Michelbb713ae2008-01-30 02:55:46 +00001793 DAG.getTargetConstant(V2Elt, MVT::i32),
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001794 DAG.getCopyFromReg(InitTempReg, dl, VReg, PtrVT));
Scott Michel6e22c652007-12-04 22:23:35 +00001795 // Use shuffle mask in SHUFB synthetic instruction:
Scott Micheld1db1ab2009-03-16 18:47:25 +00001796 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1,
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001797 ShufMaskOp);
Scott Michelea3c49d2008-12-04 21:01:44 +00001798 } else if (rotate) {
1799 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelb8ee30d2008-12-29 03:23:36 +00001800
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001801 return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(),
Scott Michelea3c49d2008-12-04 21:01:44 +00001802 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel6e22c652007-12-04 22:23:35 +00001803 } else {
Gabor Greif81d6a382008-08-31 15:37:04 +00001804 // Convert the SHUFFLE_VECTOR mask's input element units to the
1805 // actual bytes.
Duncan Sands13237ac2008-06-06 12:08:01 +00001806 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michelfe095082008-07-16 17:17:29 +00001807
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001808 SmallVector<SDValue, 16> ResultMask;
Nate Begeman8d6d4b92009-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 Michelfe095082008-07-16 17:17:29 +00001811
Nate Begeman8d6d4b92009-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 Michel6e22c652007-12-04 22:23:35 +00001814 }
Scott Michelfe095082008-07-16 17:17:29 +00001815
Evan Chenga49de9d2009-02-25 22:49:59 +00001816 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
1817 &ResultMask[0], ResultMask.size());
Dale Johannesenf08a47b2009-02-04 23:02:30 +00001818 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
Scott Michel6e22c652007-12-04 22:23:35 +00001819 }
1820}
1821
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001822static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1823 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001824 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +00001825
Gabor Greiff304a7a2008-08-28 21:40:38 +00001826 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel6e22c652007-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 Greiff304a7a2008-08-28 21:40:38 +00001830 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001831 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands13237ac2008-06-06 12:08:01 +00001832 MVT VT;
Scott Michel6e22c652007-12-04 22:23:35 +00001833 size_t n_copies;
1834
1835 // Create a constant vector:
Duncan Sands13237ac2008-06-06 12:08:01 +00001836 switch (Op.getValueType().getSimpleVT()) {
Torok Edwinfbcc6632009-07-14 16:55:14 +00001837 default: llvm_unreachable("Unexpected constant value type in "
Torok Edwin6cdb8972009-07-14 12:22:58 +00001838 "LowerSCALAR_TO_VECTOR");
Scott Michel6e22c652007-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 Gohmaneffb8942008-09-12 16:56:44 +00001847 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel6e22c652007-12-04 22:23:35 +00001848 for (size_t j = 0; j < n_copies; ++j)
1849 ConstVecValues.push_back(CValue);
1850
Evan Chenga49de9d2009-02-25 22:49:59 +00001851 return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(),
1852 &ConstVecValues[0], ConstVecValues.size());
Scott Michel6e22c652007-12-04 22:23:35 +00001853 } else {
1854 // Otherwise, copy the value from one register to another:
Duncan Sands13237ac2008-06-06 12:08:01 +00001855 switch (Op0.getValueType().getSimpleVT()) {
Torok Edwinfbcc6632009-07-14 16:55:14 +00001856 default: llvm_unreachable("Unexpected value type in LowerSCALAR_TO_VECTOR");
Scott Michel6e22c652007-12-04 22:23:35 +00001857 case MVT::i8:
1858 case MVT::i16:
1859 case MVT::i32:
1860 case MVT::i64:
1861 case MVT::f32:
1862 case MVT::f64:
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001863 return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0);
Scott Michel6e22c652007-12-04 22:23:35 +00001864 }
1865 }
1866
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001867 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001868}
1869
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001870static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00001871 MVT VT = Op.getValueType();
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00001872 SDValue N = Op.getOperand(0);
1873 SDValue Elt = Op.getOperand(1);
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001874 DebugLoc dl = Op.getDebugLoc();
Scott Michel0be03392008-11-22 23:50:42 +00001875 SDValue retval;
Scott Michel6e22c652007-12-04 22:23:35 +00001876
Scott Michel0be03392008-11-22 23:50:42 +00001877 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1878 // Constant argument:
1879 int EltNo = (int) C->getZExtValue();
Scott Michel6e22c652007-12-04 22:23:35 +00001880
Scott Michel0be03392008-11-22 23:50:42 +00001881 // sanity checks:
1882 if (VT == MVT::i8 && EltNo >= 16)
Torok Edwinfbcc6632009-07-14 16:55:14 +00001883 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
Scott Michel0be03392008-11-22 23:50:42 +00001884 else if (VT == MVT::i16 && EltNo >= 8)
Torok Edwinfbcc6632009-07-14 16:55:14 +00001885 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
Scott Michel0be03392008-11-22 23:50:42 +00001886 else if (VT == MVT::i32 && EltNo >= 4)
Torok Edwinfbcc6632009-07-14 16:55:14 +00001887 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
Scott Michel0be03392008-11-22 23:50:42 +00001888 else if (VT == MVT::i64 && EltNo >= 2)
Torok Edwinfbcc6632009-07-14 16:55:14 +00001889 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel6e22c652007-12-04 22:23:35 +00001890
Scott Michel0be03392008-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001893 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N);
Scott Michel0be03392008-11-22 23:50:42 +00001894 }
Scott Michel6e22c652007-12-04 22:23:35 +00001895
Scott Michel0be03392008-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 Michelea3c49d2008-12-04 21:01:44 +00001944 unsigned bidx = i * 4;
Scott Michel0be03392008-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 Michel839ad0a2009-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 Michel0be03392008-11-22 23:50:42 +00001955
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001956 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
1957 DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(),
Scott Michel0be03392008-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 Edwinfb8d6d52009-07-08 20:53:28 +00001964 llvm_report_error("LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit"
1965 "vector type!");
Scott Michel0be03392008-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 Johannesen9f3f72f2009-02-06 01:31:28 +00001970 Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt);
Scott Michel0be03392008-11-22 23:50:42 +00001971
1972 // Scale the index to a bit/byte shift quantity
1973 APInt scaleFactor =
Scott Michelefc8c7a2008-11-24 17:11:17 +00001974 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1975 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel0be03392008-11-22 23:50:42 +00001976 SDValue vecShift;
Scott Michel0be03392008-11-22 23:50:42 +00001977
Scott Michelefc8c7a2008-11-24 17:11:17 +00001978 if (scaleShift > 0) {
1979 // Scale the shift factor:
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001980 Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt,
Scott Michel08a4e202008-12-01 17:56:02 +00001981 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel0be03392008-11-22 23:50:42 +00001982 }
1983
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00001984 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, dl, VecVT, N, Elt);
Scott Michelefc8c7a2008-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 Michel0be03392008-11-22 23:50:42 +00001988 SDValue replicate;
1989
1990 switch (VT.getSimpleVT()) {
1991 default:
Torok Edwinfb8d6d52009-07-08 20:53:28 +00001992 llvm_report_error("LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector"
1993 "type");
Scott Michel0be03392008-11-22 23:50:42 +00001994 /*NOTREACHED*/
1995 case MVT::i8: {
Scott Michelefc8c7a2008-11-24 17:11:17 +00001996 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel839ad0a2009-03-17 01:15:45 +00001997 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1998 factor, factor, factor, factor);
Scott Michel0be03392008-11-22 23:50:42 +00001999 break;
2000 }
2001 case MVT::i16: {
Scott Michelefc8c7a2008-11-24 17:11:17 +00002002 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel839ad0a2009-03-17 01:15:45 +00002003 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2004 factor, factor, factor, factor);
Scott Michel0be03392008-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 Michel839ad0a2009-03-17 01:15:45 +00002010 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2011 factor, factor, factor, factor);
Scott Michel0be03392008-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 Michel839ad0a2009-03-17 01:15:45 +00002018 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
Evan Chenga49de9d2009-02-25 22:49:59 +00002019 loFactor, hiFactor, loFactor, hiFactor);
Scott Michel0be03392008-11-22 23:50:42 +00002020 break;
2021 }
2022 }
2023
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002024 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
2025 DAG.getNode(SPUISD::SHUFB, dl, VecVT,
Scott Michel08a4e202008-12-01 17:56:02 +00002026 vecShift, vecShift, replicate));
Scott Michel6e22c652007-12-04 22:23:35 +00002027 }
2028
Scott Michel0be03392008-11-22 23:50:42 +00002029 return retval;
Scott Michel6e22c652007-12-04 22:23:35 +00002030}
2031
Dan Gohman2ce6f2a2008-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 Johannesen9f3f72f2009-02-06 01:31:28 +00002036 DebugLoc dl = Op.getDebugLoc();
Duncan Sands13237ac2008-06-06 12:08:01 +00002037 MVT VT = Op.getValueType();
Scott Michel6e22c652007-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 Sands13237ac2008-06-06 12:08:01 +00002042 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel08a4e202008-12-01 17:56:02 +00002043 // Use $sp ($1) because it's always 16-byte aligned and it's available:
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002044 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel08a4e202008-12-01 17:56:02 +00002045 DAG.getRegister(SPU::R1, PtrVT),
2046 DAG.getConstant(CN->getSExtValue(), PtrVT));
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002047 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, VT, Pointer);
Scott Michel6e22c652007-12-04 22:23:35 +00002048
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002049 SDValue result =
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002050 DAG.getNode(SPUISD::SHUFB, dl, VT,
2051 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp),
Scott Michelb8ee30d2008-12-29 03:23:36 +00002052 VecOp,
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002053 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, ShufMask));
Scott Michel6e22c652007-12-04 22:23:35 +00002054
2055 return result;
2056}
2057
Scott Michel82335272008-12-27 04:51:36 +00002058static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2059 const TargetLowering &TLI)
Scott Michel7d5eaec2008-02-23 18:41:37 +00002060{
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002061 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002062 DebugLoc dl = Op.getDebugLoc();
Scott Michel82335272008-12-27 04:51:36 +00002063 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel6e22c652007-12-04 22:23:35 +00002064
2065 assert(Op.getValueType() == MVT::i8);
2066 switch (Opc) {
2067 default:
Torok Edwinfbcc6632009-07-14 16:55:14 +00002068 llvm_unreachable("Unhandled i8 math operator");
Scott Michel6e22c652007-12-04 22:23:35 +00002069 /*NOTREACHED*/
2070 break;
Scott Michel41236c02008-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 Johannesen9f3f72f2009-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 Michel41236c02008-12-30 23:28:25 +00002079
2080 }
2081
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002085 SDValue N1 = Op.getOperand(1);
Dale Johannesen9f3f72f2009-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 Michelfe095082008-07-16 17:17:29 +00002090 }
Scott Michel6e22c652007-12-04 22:23:35 +00002091 case ISD::ROTR:
2092 case ISD::ROTL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002093 SDValue N1 = Op.getOperand(1);
Scott Michel839ad0a2009-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002105 SDValue ExpandArg =
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002106 DAG.getNode(ISD::OR, dl, MVT::i16, N0,
2107 DAG.getNode(ISD::SHL, dl, MVT::i16,
Duncan Sands0852f482008-10-30 19:24:28 +00002108 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel839ad0a2009-03-17 01:15:45 +00002109
2110 // Truncate back down to i8
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002111 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2112 DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1));
Scott Michel6e22c652007-12-04 22:23:35 +00002113 }
2114 case ISD::SRL:
2115 case ISD::SHL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002116 SDValue N1 = Op.getOperand(1);
Scott Michel839ad0a2009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00002129 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2130 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel6e22c652007-12-04 22:23:35 +00002131 }
2132 case ISD::SRA: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002133 SDValue N1 = Op.getOperand(1);
Scott Michel839ad0a2009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00002145 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2146 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel6e22c652007-12-04 22:23:35 +00002147 }
2148 case ISD::MUL: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002149 SDValue N1 = Op.getOperand(1);
Scott Michel839ad0a2009-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 Johannesen9f3f72f2009-02-06 01:31:28 +00002153 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2154 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel6e22c652007-12-04 22:23:35 +00002155 break;
2156 }
2157 }
2158
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002159 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002160}
2161
2162//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002163static SDValue
2164LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2165 SDValue ConstVec;
2166 SDValue Arg;
Duncan Sands13237ac2008-06-06 12:08:01 +00002167 MVT VT = Op.getValueType();
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002168 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +00002169
2170 ConstVec = Op.getOperand(0);
2171 Arg = Op.getOperand(1);
Gabor Greiff304a7a2008-08-28 21:40:38 +00002172 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2173 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel6e22c652007-12-04 22:23:35 +00002174 ConstVec = ConstVec.getOperand(0);
2175 } else {
2176 ConstVec = Op.getOperand(1);
2177 Arg = Op.getOperand(0);
Gabor Greiff304a7a2008-08-28 21:40:38 +00002178 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michelbb713ae2008-01-30 02:55:46 +00002179 ConstVec = ConstVec.getOperand(0);
Scott Michel6e22c652007-12-04 22:23:35 +00002180 }
2181 }
2182 }
2183
Gabor Greiff304a7a2008-08-28 21:40:38 +00002184 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel839ad0a2009-03-17 01:15:45 +00002185 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode());
2186 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed");
Scott Michel6e22c652007-12-04 22:23:35 +00002187
Scott Michel839ad0a2009-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002197 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel6e22c652007-12-04 22:23:35 +00002198
Scott Michel839ad0a2009-03-17 01:15:45 +00002199 SmallVector<SDValue, 16> tcVec;
2200 tcVec.assign(16, tc);
Dale Johannesen9f3f72f2009-02-06 01:31:28 +00002201 return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg,
Scott Michel839ad0a2009-03-17 01:15:45 +00002202 DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size()));
Scott Michel6e22c652007-12-04 22:23:35 +00002203 }
2204 }
Scott Michel49483182009-01-26 22:33:37 +00002205
Nate Begeman82f19252008-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 Michel6e22c652007-12-04 22:23:35 +00002209}
2210
Scott Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002217static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands13237ac2008-06-06 12:08:01 +00002218 MVT VT = Op.getValueType();
2219 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002220 DebugLoc dl = Op.getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +00002221
Duncan Sands13237ac2008-06-06 12:08:01 +00002222 switch (VT.getSimpleVT()) {
2223 default:
2224 assert(false && "Invalid value type!");
Scott Michel6e22c652007-12-04 22:23:35 +00002225 case MVT::i8: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002226 SDValue N = Op.getOperand(0);
2227 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00002228
Dale Johannesenf08a47b2009-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 Michel6e22c652007-12-04 22:23:35 +00002231
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002232 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0);
Scott Michel6e22c652007-12-04 22:23:35 +00002233 }
2234
2235 case MVT::i16: {
2236 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00002237 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel6e22c652007-12-04 22:23:35 +00002238
Chris Lattnera10fff52007-12-31 04:13:23 +00002239 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel6e22c652007-12-04 22:23:35 +00002240
Dan Gohman2ce6f2a2008-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 Sands0852f482008-10-30 19:24:28 +00002244 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel6e22c652007-12-04 22:23:35 +00002245
Dale Johannesenf08a47b2009-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 Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002251 SDValue CNTB_result =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002252 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0);
Scott Michelfe095082008-07-16 17:17:29 +00002253
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002254 SDValue CNTB_rescopy =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002255 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel6e22c652007-12-04 22:23:35 +00002256
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002257 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16);
Scott Michel6e22c652007-12-04 22:23:35 +00002258
Dale Johannesenf08a47b2009-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 Michelbb713ae2008-01-30 02:55:46 +00002262 Tmp1, Shift1),
2263 Tmp1),
2264 Mask0);
Scott Michel6e22c652007-12-04 22:23:35 +00002265 }
2266
2267 case MVT::i32: {
2268 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattnera10fff52007-12-31 04:13:23 +00002269 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel6e22c652007-12-04 22:23:35 +00002270
Chris Lattnera10fff52007-12-31 04:13:23 +00002271 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2272 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel6e22c652007-12-04 22:23:35 +00002273
Dan Gohman2ce6f2a2008-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 Michel6e22c652007-12-04 22:23:35 +00002279
Dale Johannesenf08a47b2009-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 Michel6e22c652007-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002285 SDValue CNTB_result =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002286 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0);
Scott Michelfe095082008-07-16 17:17:29 +00002287
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002288 SDValue CNTB_rescopy =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002289 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel6e22c652007-12-04 22:23:35 +00002290
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002291 SDValue Comp1 =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002292 DAG.getNode(ISD::SRL, dl, MVT::i32,
Scott Micheld1db1ab2009-03-16 18:47:25 +00002293 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32),
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002294 Shift1);
Scott Michel6e22c652007-12-04 22:23:35 +00002295
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002296 SDValue Sum1 =
Dale Johannesenf08a47b2009-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 Michel6e22c652007-12-04 22:23:35 +00002299
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002300 SDValue Sum1_rescopy =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002301 DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1);
Scott Michel6e22c652007-12-04 22:23:35 +00002302
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002303 SDValue Comp2 =
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002304 DAG.getNode(ISD::SRL, dl, MVT::i32,
2305 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32),
Scott Michelbb713ae2008-01-30 02:55:46 +00002306 Shift2);
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002307 SDValue Sum2 =
Dale Johannesenf08a47b2009-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 Michel6e22c652007-12-04 22:23:35 +00002310
Dale Johannesenf08a47b2009-02-04 23:02:30 +00002311 return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0);
Scott Michel6e22c652007-12-04 22:23:35 +00002312 }
2313
2314 case MVT::i64:
2315 break;
2316 }
2317
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002318 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002319}
2320
Scott Michel9e3e4a92009-01-26 03:31:40 +00002321//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Micheled7d79f2009-01-21 04:58:48 +00002322/*!
Scott Michel9e3e4a92009-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 Micheled7d79f2009-01-21 04:58:48 +00002325 */
Scott Michel9e3e4a92009-01-26 03:31:40 +00002326static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2327 SPUTargetLowering &TLI) {
Scott Micheled7d79f2009-01-21 04:58:48 +00002328 MVT OpVT = Op.getValueType();
Scott Micheled7d79f2009-01-21 04:58:48 +00002329 SDValue Op0 = Op.getOperand(0);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002330 MVT Op0VT = Op0.getValueType();
Scott Micheled7d79f2009-01-21 04:58:48 +00002331
Scott Michel9e3e4a92009-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 Micheled7d79f2009-01-21 04:58:48 +00002343
Eli Friedmanacb851a2009-05-27 00:47:34 +00002344 return Op;
Scott Michel9e3e4a92009-01-26 03:31:40 +00002345}
Scott Micheled7d79f2009-01-21 04:58:48 +00002346
Scott Michel9e3e4a92009-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 Friedmanacb851a2009-05-27 00:47:34 +00002370 return Op;
Scott Micheled7d79f2009-01-21 04:58:48 +00002371}
2372
2373//! Lower ISD::SETCC
2374/*!
2375 This handles MVT::f64 (double floating point) condition lowering
2376 */
Scott Micheled7d79f2009-01-21 04:58:48 +00002377static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2378 const TargetLowering &TLI) {
Scott Michel9e3e4a92009-01-26 03:31:40 +00002379 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen9c310712009-02-07 19:59:05 +00002380 DebugLoc dl = Op.getDebugLoc();
Scott Michel9e3e4a92009-01-26 03:31:40 +00002381 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2382
Scott Micheled7d79f2009-01-21 04:58:48 +00002383 SDValue lhs = Op.getOperand(0);
2384 SDValue rhs = Op.getOperand(1);
Scott Micheled7d79f2009-01-21 04:58:48 +00002385 MVT lhsVT = lhs.getValueType();
Scott Micheled7d79f2009-01-21 04:58:48 +00002386 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2387
Scott Michel9e3e4a92009-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 Johannesenf2bb6f02009-02-04 01:48:28 +00002394 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002395 SDValue lhsHi32 =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002396 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2397 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002398 i64lhs, DAG.getConstant(32, MVT::i32)));
2399 SDValue lhsHi32abs =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002400 DAG.getNode(ISD::AND, dl, MVT::i32,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002401 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2402 SDValue lhsLo32 =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002403 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
Scott Michel9e3e4a92009-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 Johannesenf2bb6f02009-02-04 01:48:28 +00002410 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2411 DAG.getSetCC(dl, ccResultVT,
Scott Michel9e3e4a92009-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 Johannesenf2bb6f02009-02-04 01:48:28 +00002417 return DAG.getNode(ISD::AND, dl, ccResultVT,
2418 DAG.getSetCC(dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002419 lhsHi32abs,
2420 DAG.getConstant(0x7ff00000, MVT::i32),
2421 ISD::SETGE),
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002422 DAG.getSetCC(dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002423 lhsLo32,
2424 DAG.getConstant(0, MVT::i32),
2425 ISD::SETGT));
2426 }
2427
Dale Johannesen62fd95d2009-02-07 00:55:49 +00002428 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, rhs);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002429 SDValue rhsHi32 =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002430 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2431 DAG.getNode(ISD::SRL, dl, IntVT,
Scott Michel9e3e4a92009-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 Johannesenf2bb6f02009-02-04 01:48:28 +00002438 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002439 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002440 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002441 SDValue lhsSelect =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002442 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002443 lhsSelectMask, lhsSignMag2TC, i64lhs);
2444
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002445 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002446 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002447 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002448 SDValue rhsSelect =
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002449 DAG.getNode(ISD::SELECT, dl, IntVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002450 rhsSelectMask, rhsSignMag2TC, i64rhs);
2451
2452 unsigned compareOp;
2453
Scott Micheled7d79f2009-01-21 04:58:48 +00002454 switch (CC->get()) {
2455 case ISD::SETOEQ:
Scott Micheled7d79f2009-01-21 04:58:48 +00002456 case ISD::SETUEQ:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002457 compareOp = ISD::SETEQ; break;
2458 case ISD::SETOGT:
Scott Micheled7d79f2009-01-21 04:58:48 +00002459 case ISD::SETUGT:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002460 compareOp = ISD::SETGT; break;
2461 case ISD::SETOGE:
Scott Micheled7d79f2009-01-21 04:58:48 +00002462 case ISD::SETUGE:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002463 compareOp = ISD::SETGE; break;
2464 case ISD::SETOLT:
Scott Micheled7d79f2009-01-21 04:58:48 +00002465 case ISD::SETULT:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002466 compareOp = ISD::SETLT; break;
2467 case ISD::SETOLE:
Scott Micheled7d79f2009-01-21 04:58:48 +00002468 case ISD::SETULE:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002469 compareOp = ISD::SETLE; break;
Scott Micheled7d79f2009-01-21 04:58:48 +00002470 case ISD::SETUNE:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002471 case ISD::SETONE:
2472 compareOp = ISD::SETNE; break;
Scott Micheled7d79f2009-01-21 04:58:48 +00002473 default:
Torok Edwinfb8d6d52009-07-08 20:53:28 +00002474 llvm_report_error("CellSPU ISel Select: unimplemented f64 condition");
Scott Micheled7d79f2009-01-21 04:58:48 +00002475 }
2476
Scott Michel9e3e4a92009-01-26 03:31:40 +00002477 SDValue result =
Scott Micheld1db1ab2009-03-16 18:47:25 +00002478 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002479 (ISD::CondCode) compareOp);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002480
2481 if ((CC->get() & 0x8) == 0) {
2482 // Ordered comparison:
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002483 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002484 lhs, DAG.getConstantFP(0.0, MVT::f64),
2485 ISD::SETO);
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002486 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
Scott Michel9e3e4a92009-01-26 03:31:40 +00002487 rhs, DAG.getConstantFP(0.0, MVT::f64),
2488 ISD::SETO);
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002489 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002490
Dale Johannesenf2bb6f02009-02-04 01:48:28 +00002491 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
Scott Michel9e3e4a92009-01-26 03:31:40 +00002492 }
2493
2494 return result;
Scott Micheled7d79f2009-01-21 04:58:48 +00002495}
2496
Scott Michel0be03392008-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 Michel82335272008-12-27 04:51:36 +00002509static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2510 const TargetLowering &TLI) {
Scott Michel0be03392008-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 Johannesen400dc2e2009-02-06 21:50:26 +00002517 DebugLoc dl = Op.getDebugLoc();
Scott Michel0be03392008-11-22 23:50:42 +00002518
Scott Michel82335272008-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 Michel0be03392008-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 Johannesen400dc2e2009-02-06 21:50:26 +00002530 SDValue compare = DAG.getNode(ISD::SETCC, dl,
Duncan Sands8feb6942009-01-01 15:52:00 +00002531 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel82335272008-12-27 04:51:36 +00002532 lhs, rhs, condition);
Dale Johannesen400dc2e2009-02-06 21:50:26 +00002533 return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare);
Scott Michel0be03392008-11-22 23:50:42 +00002534}
2535
Scott Michel73640252008-12-02 19:53:53 +00002536//! Custom lower ISD::TRUNCATE
2537static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2538{
Scott Micheld1db1ab2009-03-16 18:47:25 +00002539 // Type to truncate to
Scott Michel73640252008-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 Johannesen400dc2e2009-02-06 21:50:26 +00002543 DebugLoc dl = Op.getDebugLoc();
Scott Michel73640252008-12-02 19:53:53 +00002544
Scott Micheld1db1ab2009-03-16 18:47:25 +00002545 // Type to truncate from
Scott Michel73640252008-12-02 19:53:53 +00002546 SDValue Op0 = Op.getOperand(0);
2547 MVT Op0VT = Op0.getValueType();
Scott Michel73640252008-12-02 19:53:53 +00002548
Scott Michel82335272008-12-27 04:51:36 +00002549 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel6a1f6272009-01-03 00:27:53 +00002550 // Create shuffle mask, least significant doubleword of quadword
Scott Michel82335272008-12-27 04:51:36 +00002551 unsigned maskHigh = 0x08090a0b;
2552 unsigned maskLow = 0x0c0d0e0f;
2553 // Use a shuffle to perform the truncation
Evan Chenga49de9d2009-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 Michel82335272008-12-27 04:51:36 +00002559
Scott Micheld1db1ab2009-03-16 18:47:25 +00002560 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT,
2561 Op0, Op0, shufMask);
Scott Michel82335272008-12-27 04:51:36 +00002562
Scott Micheld1db1ab2009-03-16 18:47:25 +00002563 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle);
Scott Michel73640252008-12-02 19:53:53 +00002564 }
2565
Scott Michel82335272008-12-27 04:51:36 +00002566 return SDValue(); // Leave the truncate unmolested
Scott Michel73640252008-12-02 19:53:53 +00002567}
2568
Scott Michel0be03392008-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 Gohman2ce6f2a2008-07-27 21:46:04 +00002574SDValue
2575SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel6e22c652007-12-04 22:23:35 +00002576{
Scott Michel7d5eaec2008-02-23 18:41:37 +00002577 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands13237ac2008-06-06 12:08:01 +00002578 MVT VT = Op.getValueType();
Scott Michel7d5eaec2008-02-23 18:41:37 +00002579
2580 switch (Opc) {
Scott Michel6e22c652007-12-04 22:23:35 +00002581 default: {
Torok Edwinfb8d6d52009-07-08 20:53:28 +00002582#ifndef NDEBUG
Scott Michel6e22c652007-12-04 22:23:35 +00002583 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel7d5eaec2008-02-23 18:41:37 +00002584 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greiff304a7a2008-08-28 21:40:38 +00002585 cerr << "*Op.getNode():\n";
2586 Op.getNode()->dump();
Torok Edwinfb8d6d52009-07-08 20:53:28 +00002587#endif
Torok Edwinfbcc6632009-07-14 16:55:14 +00002588 llvm_unreachable(0);
Scott Michel6e22c652007-12-04 22:23:35 +00002589 }
2590 case ISD::LOAD:
Scott Michel73640252008-12-02 19:53:53 +00002591 case ISD::EXTLOAD:
Scott Michel6e22c652007-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 Michel6e22c652007-12-04 22:23:35 +00002603 case ISD::ConstantFP:
2604 return LowerConstantFP(Op, DAG);
2605 case ISD::FORMAL_ARGUMENTS:
Scott Michele4d3e3c2008-01-17 20:38:41 +00002606 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel6e22c652007-12-04 22:23:35 +00002607 case ISD::CALL:
Scott Michel8d5841a2008-01-11 02:53:15 +00002608 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel6e22c652007-12-04 22:23:35 +00002609 case ISD::RET:
2610 return LowerRET(Op, DAG, getTargetMachine());
2611
Scott Michel41236c02008-12-30 23:28:25 +00002612 // i8, i64 math ops:
Scott Micheld831cc42008-06-02 22:18:03 +00002613 case ISD::ADD:
Scott Michel6e22c652007-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 Micheld831cc42008-06-02 22:18:03 +00002619 case ISD::SRA: {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002620 if (VT == MVT::i8)
Scott Michel82335272008-12-27 04:51:36 +00002621 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002622 break;
Scott Micheld831cc42008-06-02 22:18:03 +00002623 }
Scott Michel6e22c652007-12-04 22:23:35 +00002624
Scott Michel9e3e4a92009-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 Micheled7d79f2009-01-21 04:58:48 +00002632
Scott Michel6e22c652007-12-04 22:23:35 +00002633 // Vector-related lowering.
2634 case ISD::BUILD_VECTOR:
Scott Michel9e3e4a92009-01-26 03:31:40 +00002635 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel6e22c652007-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 Michel41236c02008-12-30 23:28:25 +00002653 if (VT == MVT::i8)
Scott Michel82335272008-12-27 04:51:36 +00002654 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel6e22c652007-12-04 22:23:35 +00002655
Scott Michel6e22c652007-12-04 22:23:35 +00002656 case ISD::CTPOP:
2657 return LowerCTPOP(Op, DAG);
Scott Michel0be03392008-11-22 23:50:42 +00002658
2659 case ISD::SELECT_CC:
Scott Michel82335272008-12-27 04:51:36 +00002660 return LowerSELECT_CC(Op, DAG, *this);
Scott Michel73640252008-12-02 19:53:53 +00002661
Scott Micheled7d79f2009-01-21 04:58:48 +00002662 case ISD::SETCC:
2663 return LowerSETCC(Op, DAG, *this);
2664
Scott Michel73640252008-12-02 19:53:53 +00002665 case ISD::TRUNCATE:
2666 return LowerTRUNCATE(Op, DAG);
Scott Michel6e22c652007-12-04 22:23:35 +00002667 }
2668
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002669 return SDValue();
Scott Michel6e22c652007-12-04 22:23:35 +00002670}
2671
Duncan Sands6ed40142008-12-01 11:39:25 +00002672void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2673 SmallVectorImpl<SDValue>&Results,
2674 SelectionDAG &DAG)
Scott Michelabad22c2008-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 Michelabad22c2008-11-10 23:43:06 +00002693}
2694
Scott Michel6e22c652007-12-04 22:23:35 +00002695//===----------------------------------------------------------------------===//
Scott Michel6e22c652007-12-04 22:23:35 +00002696// Target Optimization Hooks
2697//===----------------------------------------------------------------------===//
2698
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002699SDValue
Scott Michel6e22c652007-12-04 22:23:35 +00002700SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2701{
2702#if 0
2703 TargetMachine &TM = getTargetMachine();
Scott Michelceae3bb2008-01-29 02:16:57 +00002704#endif
2705 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel6e22c652007-12-04 22:23:35 +00002706 SelectionDAG &DAG = DCI.DAG;
Scott Michel08a4e202008-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 Michel82335272008-12-27 04:51:36 +00002709 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel08a4e202008-12-01 17:56:02 +00002710 SDValue Result; // Initially, empty result
Dale Johannesen400dc2e2009-02-06 21:50:26 +00002711 DebugLoc dl = N->getDebugLoc();
Scott Michel6e22c652007-12-04 22:23:35 +00002712
2713 switch (N->getOpcode()) {
2714 default: break;
Scott Michelceae3bb2008-01-29 02:16:57 +00002715 case ISD::ADD: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002716 SDValue Op1 = N->getOperand(1);
Scott Michelceae3bb2008-01-29 02:16:57 +00002717
Scott Michel82335272008-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 Michelb8ee30d2008-12-29 03:23:36 +00002722
Scott Michel82335272008-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 Michelceae3bb2008-01-29 02:16:57 +00002735
Scott Michel187250b2008-12-04 17:16:59 +00002736#if !defined(NDEBUG)
Scott Michel82335272008-12-27 04:51:36 +00002737 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel40f54d22008-12-04 03:02:42 +00002738 cerr << "\n"
Scott Michel82335272008-12-27 04:51:36 +00002739 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2740 << "With: (SPUindirect <arg>, <arg>)\n";
2741 }
Scott Michel40f54d22008-12-04 03:02:42 +00002742#endif
2743
Scott Michel82335272008-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 Michelceae3bb2008-01-29 02:16:57 +00002751
Scott Michel82335272008-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 Michelceae3bb2008-01-29 02:16:57 +00002761
Dale Johannesen400dc2e2009-02-06 21:50:26 +00002762 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel82335272008-12-27 04:51:36 +00002763 IndirectArg, combinedValue);
2764 }
Scott Michelceae3bb2008-01-29 02:16:57 +00002765 }
2766 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002767 break;
2768 }
2769 case ISD::SIGN_EXTEND:
2770 case ISD::ZERO_EXTEND:
2771 case ISD::ANY_EXTEND: {
Scott Michel08a4e202008-12-01 17:56:02 +00002772 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002773 // (any_extend (SPUextract_elt0 <arg>)) ->
2774 // (SPUextract_elt0 <arg>)
2775 // Types must match, however...
Scott Michel187250b2008-12-04 17:16:59 +00002776#if !defined(NDEBUG)
2777 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel40f54d22008-12-04 03:02:42 +00002778 cerr << "\nReplace: ";
2779 N->dump(&DAG);
2780 cerr << "\nWith: ";
2781 Op0.getNode()->dump(&DAG);
2782 cerr << "\n";
Scott Michel187250b2008-12-04 17:16:59 +00002783 }
Scott Michel40f54d22008-12-04 03:02:42 +00002784#endif
Scott Michel7d5eaec2008-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 Micheled7d79f2009-01-21 04:58:48 +00002792 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2793 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michel7d5eaec2008-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 Greiff304a7a2008-08-28 21:40:38 +00002800 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002801 DEBUG(cerr << "\n");
2802
2803 return Op0;
2804 }
Scott Michel82335272008-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 Johannesen400dc2e2009-02-06 21:50:26 +00002820 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel82335272008-12-27 04:51:36 +00002821 Op0.getOperand(0), Op0.getOperand(1));
2822 }
2823 }
Scott Michel7d5eaec2008-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 Michel82335272008-12-27 04:51:36 +00002832 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002833 SDValue Op1 = N->getOperand(1);
Scott Michel7d5eaec2008-02-23 18:41:37 +00002834
Scott Michel82335272008-12-27 04:51:36 +00002835 // Kill degenerate vector shifts:
2836 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2837 if (CN->isNullValue()) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002838 Result = Op0;
2839 }
2840 }
2841 break;
2842 }
Scott Michel82335272008-12-27 04:51:36 +00002843 case SPUISD::PREFSLOT2VEC: {
Scott Michel7d5eaec2008-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 Michelb8ee30d2008-12-29 03:23:36 +00002850 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel7d5eaec2008-02-23 18:41:37 +00002851 // <arg>
Scott Michelb8ee30d2008-12-29 03:23:36 +00002852 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002853 SDValue Op00 = Op0.getOperand(0);
Scott Michelefc8c7a2008-11-24 17:11:17 +00002854 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002855 SDValue Op000 = Op00.getOperand(0);
Scott Michel08a4e202008-12-01 17:56:02 +00002856 if (Op000.getValueType() == NodeVT) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002857 Result = Op000;
2858 }
2859 }
2860 break;
2861 }
Scott Michelefc8c7a2008-11-24 17:11:17 +00002862 case SPUISD::VEC2PREFSLOT: {
Scott Michelb8ee30d2008-12-29 03:23:36 +00002863 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel7d5eaec2008-02-23 18:41:37 +00002864 // <arg>
2865 Result = Op0.getOperand(0);
2866 break;
Scott Michelfe095082008-07-16 17:17:29 +00002867 }
Scott Michel7d5eaec2008-02-23 18:41:37 +00002868 }
2869 break;
Scott Michelceae3bb2008-01-29 02:16:57 +00002870 }
2871 }
Scott Micheled7d79f2009-01-21 04:58:48 +00002872
Scott Michele4d3e3c2008-01-17 20:38:41 +00002873 // Otherwise, return unchanged.
Scott Michel08a4e202008-12-01 17:56:02 +00002874#ifndef NDEBUG
Gabor Greiff304a7a2008-08-28 21:40:38 +00002875 if (Result.getNode()) {
Scott Michel7d5eaec2008-02-23 18:41:37 +00002876 DEBUG(cerr << "\nReplace.SPU: ");
2877 DEBUG(N->dump(&DAG));
2878 DEBUG(cerr << "\nWith: ");
Gabor Greiff304a7a2008-08-28 21:40:38 +00002879 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel7d5eaec2008-02-23 18:41:37 +00002880 DEBUG(cerr << "\n");
2881 }
2882#endif
2883
2884 return Result;
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00002893SPUTargetLowering::ConstraintType
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00002904 }
Scott Michel6e22c652007-12-04 22:23:35 +00002905 }
2906 return TargetLowering::getConstraintType(ConstraintLetter);
2907}
2908
Scott Michelfe095082008-07-16 17:17:29 +00002909std::pair<unsigned, const TargetRegisterClass*>
Scott Michel6e22c652007-12-04 22:23:35 +00002910SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands13237ac2008-06-06 12:08:01 +00002911 MVT VT) const
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00002927 case 'v':
Scott Michel6e22c652007-12-04 22:23:35 +00002928 return std::make_pair(0U, SPU::GPRCRegisterClass);
2929 }
2930 }
Scott Michelfe095082008-07-16 17:17:29 +00002931
Scott Michel6e22c652007-12-04 22:23:35 +00002932 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2933}
2934
Scott Michel7d5eaec2008-02-23 18:41:37 +00002935//! Compute used/known bits for a SPU operand
Scott Michel6e22c652007-12-04 22:23:35 +00002936void
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002937SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmane1d9ee62008-02-13 22:28:48 +00002938 const APInt &Mask,
Scott Michelfe095082008-07-16 17:17:29 +00002939 APInt &KnownZero,
Dan Gohmanf990faf2008-02-13 00:35:47 +00002940 APInt &KnownOne,
Scott Michelbb713ae2008-01-30 02:55:46 +00002941 const SelectionDAG &DAG,
2942 unsigned Depth ) const {
Scott Michelc3a19102008-04-30 00:30:08 +00002943#if 0
Dan Gohmancff69532009-04-01 18:45:54 +00002944 const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT;
Scott Michel7d5eaec2008-02-23 18:41:37 +00002945
2946 switch (Op.getOpcode()) {
2947 default:
2948 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2949 break;
Scott Michel7d5eaec2008-02-23 18:41:37 +00002950 case CALL:
2951 case SHUFB:
Scott Michel0be03392008-11-22 23:50:42 +00002952 case SHUFFLE_MASK:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002953 case CNTB:
Scott Micheled7d79f2009-01-21 04:58:48 +00002954 case SPUISD::PREFSLOT2VEC:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002955 case SPUISD::LDRESULT:
Scott Micheled7d79f2009-01-21 04:58:48 +00002956 case SPUISD::VEC2PREFSLOT:
Scott Michelc3a19102008-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 Michelc3a19102008-04-30 00:30:08 +00002964 case SPUISD::ROTBYTES_LEFT:
Scott Micheld831cc42008-06-02 22:18:03 +00002965 case SPUISD::SELECT_MASK:
2966 case SPUISD::SELB:
Scott Michel7d5eaec2008-02-23 18:41:37 +00002967 }
Scott Micheled7d79f2009-01-21 04:58:48 +00002968#endif
Scott Michel6e22c652007-12-04 22:23:35 +00002969}
Scott Michel41236c02008-12-30 23:28:25 +00002970
Scott Michel82335272008-12-27 04:51:36 +00002971unsigned
2972SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2973 unsigned Depth) const {
2974 switch (Op.getOpcode()) {
2975 default:
2976 return 1;
Scott Michel6e22c652007-12-04 22:23:35 +00002977
Scott Michel82335272008-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 Michelb8ee30d2008-12-29 03:23:36 +00002988
Scott Michelc3a19102008-04-30 00:30:08 +00002989// LowerAsmOperandForConstraint
2990void
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002991SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelc3a19102008-04-30 00:30:08 +00002992 char ConstraintLetter,
Evan Chenge0add202008-09-24 00:05:32 +00002993 bool hasMemory,
Dan Gohman2ce6f2a2008-07-27 21:46:04 +00002994 std::vector<SDValue> &Ops,
Scott Michelc3a19102008-04-30 00:30:08 +00002995 SelectionDAG &DAG) const {
2996 // Default, for the time being, to the base class handler
Evan Chenge0add202008-09-24 00:05:32 +00002997 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2998 Ops, DAG);
Scott Michelc3a19102008-04-30 00:30:08 +00002999}
3000
Scott Michel6e22c652007-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 Greif81d6a382008-08-31 15:37:04 +00003003bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3004 const Type *Ty) const {
Scott Michel6e22c652007-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 Michelfe095082008-07-16 17:17:29 +00003010 return false;
Scott Michel6e22c652007-12-04 22:23:35 +00003011}
Dan Gohman2fe6bee2008-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}