blob: 2042a93e919be6d3fee017c320deedd8f36bb60d [file] [log] [blame]
Scott Michel8efdca42007-12-04 22:23:35 +00001//
Scott Michel0d5eae02009-03-17 01:15:45 +00002//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
Scott Michel8efdca42007-12-04 22:23:35 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel8efdca42007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michelbc5fbc12008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel06eabde2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel8efdca42007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
pingbak2f387e82009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel8efdca42007-12-04 22:23:35 +000021#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner1b989192007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel8efdca42007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel8efdca42007-12-04 22:23:35 +000027#include "llvm/Constants.h"
28#include "llvm/Function.h"
29#include "llvm/Intrinsics.h"
30#include "llvm/Support/Debug.h"
Edwin Török4d9756a2009-07-08 20:53:28 +000031#include "llvm/Support/ErrorHandling.h"
Scott Michel8efdca42007-12-04 22:23:35 +000032#include "llvm/Support/MathExtras.h"
Edwin Török4d9756a2009-07-08 20:53:28 +000033#include "llvm/Support/raw_ostream.h"
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000044 //! MVT mapping to useful data for Cell SPU
Scott Michel8efdca42007-12-04 22:23:35 +000045 struct valtype_map_s {
Scott Michel56a125e2008-11-22 23:50:42 +000046 const MVT valtype;
47 const int prefslot_byte;
Scott Michel8efdca42007-12-04 22:23:35 +000048 };
Scott Michel4ec722e2008-07-16 17:17:29 +000049
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +000063 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel8efdca42007-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 Michel5a6f17b2008-01-30 02:55:46 +000068 retval = valtype_map + i;
69 break;
Scott Michel8efdca42007-12-04 22:23:35 +000070 }
71 }
72
73#ifndef NDEBUG
74 if (retval == 0) {
Edwin Török4d9756a2009-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 Michel8efdca42007-12-04 22:23:35 +000080 }
81#endif
82
83 return retval;
84 }
Scott Michel750b93f2009-01-15 04:41:47 +000085
pingbak2f387e82009-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 Andersona0167022009-07-09 17:57:24 +0000105 const Type *ArgTy = ArgVT.getTypeForMVT(*DAG.getContext());
pingbak2f387e82009-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 Andersona0167022009-07-09 17:57:24 +0000116 const Type *RetTy =
117 Op.getNode()->getValueType(0).getTypeForMVT(*DAG.getContext());
pingbak2f387e82009-01-26 03:31:40 +0000118 std::pair<SDValue, SDValue> CallInfo =
119 TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
Tilmann Scheller71c69732009-07-03 06:44:53 +0000120 0, CallingConv::C, false, Callee, Args, DAG,
Dale Johannesen2dbdb0e2009-02-07 19:59:05 +0000121 Op.getDebugLoc());
pingbak2f387e82009-01-26 03:31:40 +0000122
123 return CallInfo.first;
124 }
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000137
Scott Michel8c67fa42009-01-21 04:58:48 +0000138 // Set RTLIB libcall names as used by SPU:
139 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
140
Scott Michel8efdca42007-12-04 22:23:35 +0000141 // Set up the SPU's register classes:
Scott Michel438be252007-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 Michel8efdca42007-12-04 22:23:35 +0000148 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel4ec722e2008-07-16 17:17:29 +0000149
Scott Michel8efdca42007-12-04 22:23:35 +0000150 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng08c171a2008-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 Michel8efdca42007-12-04 22:23:35 +0000154
Scott Michel06eabde2008-12-27 04:51:36 +0000155 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
156 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelec8c82e2008-12-02 19:53:53 +0000157
Scott Michel8efdca42007-12-04 22:23:35 +0000158 // SPU constant load actions are custom lowered:
Nate Begeman78125042008-02-14 18:43:04 +0000159 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-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 Michel2ef773a2009-01-06 03:36:14 +0000163 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel8efdca42007-12-04 22:23:35 +0000164 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000165 MVT VT = (MVT::SimpleValueType)sctype;
166
Scott Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000177 }
178
Scott Michel06eabde2008-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 Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000195
196 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel4ec722e2008-07-16 17:17:29 +0000197 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel56a125e2008-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 Michel8efdca42007-12-04 22:23:35 +0000202
203 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000204 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
205
Scott Michel06eabde2008-12-27 04:51:36 +0000206 // SPU has no SREM/UREM instructions
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000211
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000219
pingbak2f387e82009-01-26 03:31:40 +0000220 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
221 // for f32!)
Scott Michel8efdca42007-12-04 22:23:35 +0000222 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
223 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000224
Scott Michel8efdca42007-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 Wendling965299c2008-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 Michel8efdca42007-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 Michelabb8ca12008-11-20 16:36:33 +0000240
Scott Michel8efdca42007-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 Michel33d73eb2008-11-21 02:56:16 +0000245
Scott Michel4d07fb72008-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 Michel8efdca42007-12-04 22:23:35 +0000250
Scott Michel4ec722e2008-07-16 17:17:29 +0000251 // Custom lower i8, i32 and i64 multiplications
252 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelae5cbf52008-12-29 03:23:36 +0000253 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel750b93f2009-01-15 04:41:47 +0000254 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel33d73eb2008-11-21 02:56:16 +0000255
Eli Friedman35be0012009-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 Michel67224b22008-06-02 22:18:03 +0000275 // Need to custom handle (some) common i8, i64 math ops
Scott Michel4d07fb72008-12-30 23:28:25 +0000276 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000277 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000278 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000279 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000280
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000295
Scott Michel67224b22008-06-02 22:18:03 +0000296 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel978b96f2008-03-10 23:49:09 +0000297 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000298 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000299 setOperationAction(ISD::SELECT, MVT::i16, Legal);
300 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel06eabde2008-12-27 04:51:36 +0000301 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000302
Scott Michel53ab7792008-03-10 16:58:52 +0000303 setOperationAction(ISD::SETCC, MVT::i8, Legal);
304 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000305 setOperationAction(ISD::SETCC, MVT::i32, Legal);
306 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel8c67fa42009-01-21 04:58:48 +0000307 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michel6baba072008-03-05 23:02:02 +0000308
Scott Michel06eabde2008-12-27 04:51:36 +0000309 // Custom lower i128 -> i64 truncates
Scott Michelec8c82e2008-12-02 19:53:53 +0000310 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
311
pingbak2f387e82009-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 Michel8efdca42007-12-04 22:23:35 +0000316
317 // FDIV on SPU requires custom lowering
pingbak2f387e82009-01-26 03:31:40 +0000318 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel8efdca42007-12-04 22:23:35 +0000319
Scott Michelc899a122009-01-26 22:33:37 +0000320 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
pingbak2f387e82009-01-26 03:31:40 +0000321 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000322 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000323 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
324 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000325 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000326 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel8efdca42007-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 Michel754d8662007-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 Michel8efdca42007-12-04 22:23:35 +0000334
335 // We cannot sextinreg(i1). Expand to shifts.
336 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000337
Scott Michel8efdca42007-12-04 22:23:35 +0000338 // Support label based line numbers.
Dan Gohman472d12c2008-06-30 20:59:49 +0000339 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000340 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000341
342 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel8efdca42007-12-04 22:23:35 +0000343 // appropriate instructions to materialize the address.
Scott Michel33d73eb2008-11-21 02:56:16 +0000344 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelf9f42e62008-01-29 02:16:57 +0000345 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000346 MVT VT = (MVT::SimpleValueType)sctype;
347
Scott Michelae5cbf52008-12-29 03:23:36 +0000348 setOperationAction(ISD::GlobalAddress, VT, Custom);
349 setOperationAction(ISD::ConstantPool, VT, Custom);
350 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelf9f42e62008-01-29 02:16:57 +0000351 }
Scott Michel8efdca42007-12-04 22:23:35 +0000352
353 // RET must be custom lowered, to meet ABI requirements
354 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000355
Scott Michel8efdca42007-12-04 22:23:35 +0000356 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
357 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000358
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000363 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +0000371
Scott Michel8efdca42007-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 Michel70741542009-01-06 23:10:38 +0000387 // "Odd size" vector classes that we're willing to support:
388 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
389
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000393
Duncan Sands92c43912008-06-06 12:08:01 +0000394 // add/sub are legal for all supported vector VT's.
pingbak2f387e82009-01-26 03:31:40 +0000395 setOperationAction(ISD::ADD, VT, Legal);
396 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000397 // mul has to be custom lowered.
pingbak2f387e82009-01-26 03:31:40 +0000398 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000399
pingbak2f387e82009-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 Michel4ec722e2008-07-16 17:17:29 +0000406
Scott Michel8efdca42007-12-04 22:23:35 +0000407 // These operations need to be expanded:
pingbak2f387e82009-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 Michel8efdca42007-12-04 22:23:35 +0000412
413 // Custom lower build_vector, constant pool spills, insert and
414 // extract vector elements:
Duncan Sands92c43912008-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 Michel8efdca42007-12-04 22:23:35 +0000421 }
422
Scott Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000427
Scott Michel4d07fb72008-12-30 23:28:25 +0000428 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000429
Scott Michel8efdca42007-12-04 22:23:35 +0000430 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000431 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000432
Scott Michel8efdca42007-12-04 22:23:35 +0000433 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000434
Scott Michel8efdca42007-12-04 22:23:35 +0000435 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000436 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000437 setTargetDAGCombine(ISD::ZERO_EXTEND);
438 setTargetDAGCombine(ISD::SIGN_EXTEND);
439 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000440
Scott Michel8efdca42007-12-04 22:23:35 +0000441 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000442
Scott Michel2c261072008-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 Michel8efdca42007-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 Micheldbac4cf2008-01-11 02:53:15 +0000457 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000458 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +0000462 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000463 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000464 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000465 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-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 Michel8efdca42007-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 Michel8c67fa42009-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 Michel67224b22008-06-02 22:18:03 +0000476 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000477 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel750b93f2009-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 Michel8efdca42007-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 Wendling045f2632009-07-01 18:50:55 +0000488/// getFunctionAlignment - Return the Log2 alignment of this function.
Bill Wendling25a8ae32009-06-30 22:38:32 +0000489unsigned SPUTargetLowering::getFunctionAlignment(const Function *) const {
490 return 3;
491}
492
Scott Michel06eabde2008-12-27 04:51:36 +0000493//===----------------------------------------------------------------------===//
494// Return the Cell SPU's SETCC result type
495//===----------------------------------------------------------------------===//
496
Duncan Sands4a361272009-01-01 15:52:00 +0000497MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-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 Michel53ab7792008-03-10 16:58:52 +0000500}
501
Scott Michel8efdca42007-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 Michel6ccefab2008-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 Michelae5cbf52008-12-29 03:23:36 +0000521%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000522%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000523%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000524%4 f32 = vec2perfslot %3
525%5 f64 = fp_extend %4
526\endverbatim
527*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000528static SDValue
529LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000530 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000531 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000532 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000533 MVT InVT = LN->getMemoryVT();
534 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000535 ISD::LoadExtType ExtType = LN->getExtensionType();
536 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000537 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Dale Johannesenea996922009-02-04 20:06:27 +0000538 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000539
Scott Michel8efdca42007-12-04 22:23:35 +0000540 switch (LN->getAddressingMode()) {
541 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000542 SDValue result;
543 SDValue basePtr = LN->getBasePtr();
544 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000545
Scott Michel06eabde2008-12-27 04:51:36 +0000546 if (alignment == 16) {
547 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000548
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000556
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000565 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000579 } else {
Scott Michel06eabde2008-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 Johannesenea996922009-02-04 20:06:27 +0000585 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000586 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000587 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000588 }
Scott Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000596
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000604 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesenea996922009-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 Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000610 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel06eabde2008-12-27 04:51:36 +0000611 }
612 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000613 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-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 Johannesenea996922009-02-04 20:06:27 +0000620 rotate = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000621 basePtr,
622 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +0000623 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000624
Scott Michel06eabde2008-12-27 04:51:36 +0000625 // Re-emit as a v16i8 vector load
Dale Johannesenea996922009-02-04 20:06:27 +0000626 result = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel06eabde2008-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 Johannesenea996922009-02-04 20:06:27 +0000634 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, MVT::v16i8,
Scott Michel06eabde2008-12-27 04:51:36 +0000635 result.getValue(0), rotate);
636
Scott Michel6ccefab2008-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 Johannesenea996922009-02-04 20:06:27 +0000640 result = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, InVT,
641 DAG.getNode(ISD::BIT_CONVERT, dl, vecVT, result));
Scott Michel4ec722e2008-07-16 17:17:29 +0000642
Scott Michel6ccefab2008-12-04 03:02:42 +0000643 // Handle extending loads by extending the scalar result:
644 if (ExtType == ISD::SEXTLOAD) {
Dale Johannesenea996922009-02-04 20:06:27 +0000645 result = DAG.getNode(ISD::SIGN_EXTEND, dl, OutVT, result);
Scott Michel6ccefab2008-12-04 03:02:42 +0000646 } else if (ExtType == ISD::ZEXTLOAD) {
Dale Johannesenea996922009-02-04 20:06:27 +0000647 result = DAG.getNode(ISD::ZERO_EXTEND, dl, OutVT, result);
Scott Michel6ccefab2008-12-04 03:02:42 +0000648 } else if (ExtType == ISD::EXTLOAD) {
649 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000650
Scott Michel6ccefab2008-12-04 03:02:42 +0000651 if (OutVT.isFloatingPoint())
pingbakb8913342009-01-26 03:37:41 +0000652 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000653
Dale Johannesenea996922009-02-04 20:06:27 +0000654 result = DAG.getNode(NewOpc, dl, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000655 }
656
Scott Michel6ccefab2008-12-04 03:02:42 +0000657 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000658 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000659 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000660 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000661 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000662
Dale Johannesenea996922009-02-04 20:06:27 +0000663 result = DAG.getNode(SPUISD::LDRESULT, dl, retvts,
Scott Michel394e26d2008-01-17 20:38:41 +0000664 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000665 return result;
Scott Michel8efdca42007-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:
Edwin Török4d9756a2009-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 Michel8efdca42007-12-04 22:23:35 +0000676 "UNINDEXED\n";
Edwin Török4d9756a2009-07-08 20:53:28 +0000677 Msg << (unsigned) LN->getAddressingMode();
678 llvm_report_error(Msg.str());
679 /*NOTREACHED*/
680 }
Scott Michel8efdca42007-12-04 22:23:35 +0000681 }
682
Dan Gohman8181bd12008-07-27 21:46:04 +0000683 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +0000692static SDValue
693LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000694 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000695 SDValue Value = SN->getValue();
Duncan Sands92c43912008-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 Johannesenea996922009-02-04 20:06:27 +0000699 DebugLoc dl = Op.getDebugLoc();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000700 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000701
702 switch (SN->getAddressingMode()) {
703 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000704 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000705 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
706 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000707
Scott Michel06eabde2008-12-27 04:51:36 +0000708 SDValue alignLoadVec;
709 SDValue basePtr = SN->getBasePtr();
710 SDValue the_chain = SN->getChain();
711 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000712
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000725 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000726 basePtr,
727 DAG.getConstant((offset & 0xf), PtrVT));
728
729 if ((offset & ~0xf) > 0) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000730 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000736 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000755 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Dale Johannesenea996922009-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 Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +0000761 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Op0, Op1);
Scott Michel06eabde2008-12-27 04:51:36 +0000762 }
763 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000764 basePtr = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel06eabde2008-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 Johannesenea996922009-02-04 20:06:27 +0000770 insertEltOffs = DAG.getNode(ISD::ADD, dl, PtrVT,
Scott Michel06eabde2008-12-27 04:51:36 +0000771 basePtr,
772 DAG.getConstant(0, PtrVT));
773 }
774
775 // Re-emit as a v16i8 vector load
Dale Johannesenea996922009-02-04 20:06:27 +0000776 alignLoadVec = DAG.getLoad(MVT::v16i8, dl, the_chain, basePtr,
Scott Michel06eabde2008-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 Michel8efdca42007-12-04 22:23:35 +0000782
Scott Micheldbac4cf2008-01-11 02:53:15 +0000783 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000784 SDValue theValue = SN->getValue();
785 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000786
787 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000788 && (theValue.getOpcode() == ISD::AssertZext
789 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000790 // Drill down and get the value for zero- and sign-extended
791 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000792 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000793 }
794
Scott Micheldbac4cf2008-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 Michel06eabde2008-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 Micheldbac4cf2008-01-11 02:53:15 +0000806
Scott Michelf65c8f02008-11-19 15:24:16 +0000807 SDValue insertEltOp =
Dale Johannesenea996922009-02-04 20:06:27 +0000808 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000809 SDValue vectorizeOp =
Dale Johannesenea996922009-02-04 20:06:27 +0000810 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000811
Dale Johannesenea996922009-02-04 20:06:27 +0000812 result = DAG.getNode(SPUISD::SHUFB, dl, vecVT,
pingbakb8913342009-01-26 03:37:41 +0000813 vectorizeOp, alignLoadVec,
Scott Michel34712c32009-03-16 18:47:25 +0000814 DAG.getNode(ISD::BIT_CONVERT, dl,
Dale Johannesenea996922009-02-04 20:06:27 +0000815 MVT::v4i32, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000816
Dale Johannesenea996922009-02-04 20:06:27 +0000817 result = DAG.getStore(the_chain, dl, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000818 LN->getSrcValue(), LN->getSrcValueOffset(),
819 LN->isVolatile(), LN->getAlignment());
820
Scott Michel8c2746e2008-12-04 17:16:59 +0000821#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-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 Michelec8c82e2008-12-02 19:53:53 +0000832
Scott Michel8efdca42007-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:
Edwin Török4d9756a2009-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 Michel8efdca42007-12-04 22:23:35 +0000845 "UNINDEXED\n";
Edwin Török4d9756a2009-07-08 20:53:28 +0000846 Msg << (unsigned) SN->getAddressingMode();
847 llvm_report_error(Msg.str());
848 /*NOTREACHED*/
849 }
Scott Michel8efdca42007-12-04 22:23:35 +0000850 }
851
Dan Gohman8181bd12008-07-27 21:46:04 +0000852 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000853}
854
Scott Michel750b93f2009-01-15 04:41:47 +0000855//! Generate the address of a constant pool entry.
856SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000857LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000858 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000859 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
860 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000861 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
862 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000863 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000864 // FIXME there is no actual debug info here
865 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000866
867 if (TM.getRelocationModel() == Reloc::Static) {
868 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000869 // Just return the SDValue with the constant pool address in it.
Dale Johannesen175fdef2009-02-06 21:50:26 +0000870 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000871 } else {
Dale Johannesen175fdef2009-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 Michel8efdca42007-12-04 22:23:35 +0000875 }
876 }
877
Edwin Törökbd448e32009-07-14 16:55:14 +0000878 llvm_unreachable("LowerConstantPool: Relocation model other than static"
Edwin Törökb2de05e2009-07-14 12:22:58 +0000879 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000880 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000881}
882
Scott Michel750b93f2009-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 Gohman8181bd12008-07-27 21:46:04 +0000889static SDValue
890LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000891 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000892 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000893 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
894 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000895 const TargetMachine &TM = DAG.getTarget();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000896 // FIXME there is no actual debug info here
897 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000898
899 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000900 if (!ST->usingLargeMem()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000901 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, JTI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000902 } else {
Dale Johannesen175fdef2009-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 Michel97872d32008-02-23 18:41:37 +0000906 }
Scott Michel8efdca42007-12-04 22:23:35 +0000907 }
908
Edwin Törökbd448e32009-07-14 16:55:14 +0000909 llvm_unreachable("LowerJumpTable: Relocation model other than static"
Edwin Törökb2de05e2009-07-14 12:22:58 +0000910 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000911 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000912}
913
Dan Gohman8181bd12008-07-27 21:46:04 +0000914static SDValue
915LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000916 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000917 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
918 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000919 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000920 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000921 SDValue Zero = DAG.getConstant(0, PtrVT);
Dale Johannesen175fdef2009-02-06 21:50:26 +0000922 // FIXME there is no actual debug info here
923 DebugLoc dl = Op.getDebugLoc();
Scott Michel4ec722e2008-07-16 17:17:29 +0000924
Scott Michel8efdca42007-12-04 22:23:35 +0000925 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000926 if (!ST->usingLargeMem()) {
Dale Johannesen175fdef2009-02-06 21:50:26 +0000927 return DAG.getNode(SPUISD::AFormAddr, dl, PtrVT, GA, Zero);
Scott Michelf9f42e62008-01-29 02:16:57 +0000928 } else {
Dale Johannesen175fdef2009-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 Michelf9f42e62008-01-29 02:16:57 +0000932 }
Scott Michel8efdca42007-12-04 22:23:35 +0000933 } else {
Edwin Török4d9756a2009-07-08 20:53:28 +0000934 llvm_report_error("LowerGlobalAddress: Relocation model other than static"
935 "not supported.");
Scott Michel8efdca42007-12-04 22:23:35 +0000936 /*NOTREACHED*/
937 }
938
Dan Gohman8181bd12008-07-27 21:46:04 +0000939 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000940}
941
Nate Begeman78125042008-02-14 18:43:04 +0000942//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000943static SDValue
944LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000945 MVT VT = Op.getValueType();
Dale Johannesen175fdef2009-02-06 21:50:26 +0000946 // FIXME there is no actual debug info here
947 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000948
Nate Begeman78125042008-02-14 18:43:04 +0000949 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000950 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
951
952 assert((FP != 0) &&
953 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000954
Scott Michel11e88bb2007-12-19 20:15:47 +0000955 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-12-01 17:56:02 +0000956 SDValue T = DAG.getConstant(dbits, MVT::i64);
Evan Cheng907a2d22009-02-25 22:49:59 +0000957 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T);
Dale Johannesen175fdef2009-02-06 21:50:26 +0000958 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
Dale Johannesen24dd9a52009-02-07 00:55:49 +0000959 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, Tvec));
Scott Michel8efdca42007-12-04 22:23:35 +0000960 }
961
Dan Gohman8181bd12008-07-27 21:46:04 +0000962 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000963}
964
Dan Gohman8181bd12008-07-27 21:46:04 +0000965static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000966LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000967{
968 MachineFunction &MF = DAG.getMachineFunction();
969 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000970 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000971 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000972 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000973 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Dale Johannesenea996922009-02-04 20:06:27 +0000974 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +0000975
976 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
977 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000978
Scott Michel8efdca42007-12-04 22:23:35 +0000979 unsigned ArgOffset = SPUFrameInfo::minStackSize();
980 unsigned ArgRegIdx = 0;
981 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000982
Duncan Sands92c43912008-06-06 12:08:01 +0000983 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000984
Scott Michel8efdca42007-12-04 22:23:35 +0000985 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000986 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
987 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000988 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
989 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000990 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000991
Scott Michela313fb02008-10-30 01:51:48 +0000992 if (ArgRegIdx < NumArgRegs) {
993 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000994
Scott Michela313fb02008-10-30 01:51:48 +0000995 switch (ObjectVT.getSimpleVT()) {
996 default: {
Edwin Török4d9756a2009-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 Michela313fb02008-10-30 01:51:48 +00001002 }
1003 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +00001004 ArgRegClass = &SPU::R8CRegClass;
1005 break;
Scott Michela313fb02008-10-30 01:51:48 +00001006 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +00001007 ArgRegClass = &SPU::R16CRegClass;
1008 break;
Scott Michela313fb02008-10-30 01:51:48 +00001009 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +00001010 ArgRegClass = &SPU::R32CRegClass;
1011 break;
Scott Michela313fb02008-10-30 01:51:48 +00001012 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +00001013 ArgRegClass = &SPU::R64CRegClass;
1014 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001015 case MVT::i128:
1016 ArgRegClass = &SPU::GPRCRegClass;
1017 break;
Scott Michela313fb02008-10-30 01:51:48 +00001018 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +00001019 ArgRegClass = &SPU::R32FPRegClass;
1020 break;
Scott Michela313fb02008-10-30 01:51:48 +00001021 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +00001022 ArgRegClass = &SPU::R64FPRegClass;
1023 break;
Scott Michela313fb02008-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 Michel33d73eb2008-11-21 02:56:16 +00001030 ArgRegClass = &SPU::VECREGRegClass;
1031 break;
Scott Michela313fb02008-10-30 01:51:48 +00001032 }
1033
1034 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
1035 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
Dale Johannesenea996922009-02-04 20:06:27 +00001036 ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT);
Scott Michela313fb02008-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 Lattner60069452008-02-13 07:35:30 +00001042 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +00001043 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Dale Johannesenea996922009-02-04 20:06:27 +00001044 ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +00001045 ArgOffset += StackSlotSize;
1046 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001047
Scott Michel8efdca42007-12-04 22:23:35 +00001048 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +00001049 // Update the chain
1050 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001051 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001052
Scott Michela313fb02008-10-30 01:51:48 +00001053 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +00001054 if (isVarArg) {
Scott Michela313fb02008-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 Michel8efdca42007-12-04 22:23:35 +00001061 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-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 Johannesenea996922009-02-04 20:06:27 +00001065 SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0);
Scott Michela313fb02008-10-30 01:51:48 +00001066 Root = Store.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001067 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001068
1069 // Increment address by stack slot size for the next stored argument
1070 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001071 }
1072 if (!MemOps.empty())
Scott Michel34712c32009-03-16 18:47:25 +00001073 Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Dale Johannesenea996922009-02-04 20:06:27 +00001074 &MemOps[0], MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001075 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001076
Scott Michel8efdca42007-12-04 22:23:35 +00001077 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001078
Scott Michel8efdca42007-12-04 22:23:35 +00001079 // Return the new list of results.
Dale Johannesenea996922009-02-04 20:06:27 +00001080 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
Duncan Sands42d7bb82008-12-01 11:41:29 +00001081 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001086static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001087 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001088 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001089
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001090 int Addr = C->getZExtValue();
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001094
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001095 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001096}
1097
Scott Michel70741542009-01-06 23:10:38 +00001098static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +00001099LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001100 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1101 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001102 SDValue Callee = TheCall->getCallee();
1103 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-12-04 22:23:35 +00001104 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1105 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1106 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Dale Johannesenea996922009-02-04 20:06:27 +00001107 DebugLoc dl = TheCall->getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00001108
1109 // Handy pointer type
Duncan Sands92c43912008-06-06 12:08:01 +00001110 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001111
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001116
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001120 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001121
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001128 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001129 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001130 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001131
1132 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001133 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001134
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001137 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Dale Johannesenea996922009-02-04 20:06:27 +00001138 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
Scott Michel8efdca42007-12-04 22:23:35 +00001139
Duncan Sands92c43912008-06-06 12:08:01 +00001140 switch (Arg.getValueType().getSimpleVT()) {
Edwin Törökbd448e32009-07-14 16:55:14 +00001141 default: llvm_unreachable("Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001142 case MVT::i8:
1143 case MVT::i16:
Scott Michel8efdca42007-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 Johannesenea996922009-02-04 20:06:27 +00001150 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001151 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-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 Johannesenea996922009-02-04 20:06:27 +00001159 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001160 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001161 }
1162 break;
Scott Michele2641a12008-12-04 21:01:44 +00001163 case MVT::v2i64:
1164 case MVT::v2f64:
Scott Michel8efdca42007-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 Johannesenea996922009-02-04 20:06:27 +00001172 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001173 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-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 Lattnerfe5d4022008-10-11 22:08:30 +00001181 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1182 true));
Scott Michel8efdca42007-12-04 22:23:35 +00001183
1184 if (!MemOpChains.empty()) {
1185 // Adjust the stack pointer for the stack arguments.
Dale Johannesenea996922009-02-04 20:06:27 +00001186 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
Scott Michel8efdca42007-12-04 22:23:35 +00001187 &MemOpChains[0], MemOpChains.size());
1188 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001189
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001192 SDValue InFlag;
Scott Michel8efdca42007-12-04 22:23:35 +00001193 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
Scott Michel34712c32009-03-16 18:47:25 +00001194 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
Dale Johannesenea996922009-02-04 20:06:27 +00001195 RegsToPass[i].second, InFlag);
Scott Michel8efdca42007-12-04 22:23:35 +00001196 InFlag = Chain.getValue(1);
1197 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001198
Dan Gohman8181bd12008-07-27 21:46:04 +00001199 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001200 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001201
Bill Wendlingfef06052008-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 Michel5974f432008-11-11 03:06:06 +00001205 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001206 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001207 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001208 SDValue Zero = DAG.getConstant(0, PtrVT);
1209 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001210
Scott Micheldbac4cf2008-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 Johannesen175fdef2009-02-06 21:50:26 +00001221 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, GA, Zero);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001222 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001223 Callee = DAG.getNode(SPUISD::PCRelAddr, dl, CalleeVT, GA, Zero);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001224 }
Scott Michel8efdca42007-12-04 22:23:35 +00001225 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001226 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1227 // address pairs:
Dale Johannesen175fdef2009-02-06 21:50:26 +00001228 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001229 }
Scott Michelae5cbf52008-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 Johannesen175fdef2009-02-06 21:50:26 +00001237 Callee = DAG.getNode(SPUISD::AFormAddr, dl, CalleeVT, ExtSym, Zero);
Scott Michelae5cbf52008-12-29 03:23:36 +00001238 } else {
Dale Johannesen175fdef2009-02-06 21:50:26 +00001239 Callee = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, ExtSym, Zero);
Scott Michelae5cbf52008-12-29 03:23:36 +00001240 }
1241 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001244 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001245 }
Scott Michel8efdca42007-12-04 22:23:35 +00001246
1247 Ops.push_back(Chain);
1248 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001249
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00001253 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001254 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001255
Gabor Greif1c80d112008-08-28 21:40:38 +00001256 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001257 Ops.push_back(InFlag);
Duncan Sands698842f2008-07-02 17:40:58 +00001258 // Returns a chain and a flag for retval copy to use.
Dale Johannesenea996922009-02-04 20:06:27 +00001259 Chain = DAG.getNode(CallOpc, dl, DAG.getVTList(MVT::Other, MVT::Flag),
Duncan Sands698842f2008-07-02 17:40:58 +00001260 &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001261 InFlag = Chain.getValue(1);
1262
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001263 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1264 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001265 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001266 InFlag = Chain.getValue(1);
1267
Dan Gohman8181bd12008-07-27 21:46:04 +00001268 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001269 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001270
Scott Michel8efdca42007-12-04 22:23:35 +00001271 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001272 switch (TheCall->getValueType(0).getSimpleVT()) {
Edwin Törökbd448e32009-07-14 16:55:14 +00001273 default: llvm_unreachable("Unexpected ret value!");
Scott Michel8efdca42007-12-04 22:23:35 +00001274 case MVT::Other: break;
1275 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001276 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel34712c32009-03-16 18:47:25 +00001277 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4,
Dale Johannesenea996922009-02-04 20:06:27 +00001278 MVT::i32, InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001279 ResultVals[0] = Chain.getValue(0);
Dale Johannesenea996922009-02-04 20:06:27 +00001280 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Scott Michel8efdca42007-12-04 22:23:35 +00001281 Chain.getValue(2)).getValue(1);
1282 ResultVals[1] = Chain.getValue(0);
1283 NumResults = 2;
Scott Michel8efdca42007-12-04 22:23:35 +00001284 } else {
Scott Michel34712c32009-03-16 18:47:25 +00001285 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32,
Dale Johannesenea996922009-02-04 20:06:27 +00001286 InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001287 ResultVals[0] = Chain.getValue(0);
1288 NumResults = 1;
1289 }
Scott Michel8efdca42007-12-04 22:23:35 +00001290 break;
1291 case MVT::i64:
Scott Michel34712c32009-03-16 18:47:25 +00001292 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64,
Dale Johannesenea996922009-02-04 20:06:27 +00001293 InFlag).getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +00001294 ResultVals[0] = Chain.getValue(0);
1295 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001296 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001297 case MVT::i128:
Scott Michel34712c32009-03-16 18:47:25 +00001298 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128,
Dale Johannesenea996922009-02-04 20:06:27 +00001299 InFlag).getValue(1);
Scott Michel2ef773a2009-01-06 03:36:14 +00001300 ResultVals[0] = Chain.getValue(0);
1301 NumResults = 1;
1302 break;
Scott Michel8efdca42007-12-04 22:23:35 +00001303 case MVT::f32:
1304 case MVT::f64:
Dale Johannesenea996922009-02-04 20:06:27 +00001305 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001306 InFlag).getValue(1);
1307 ResultVals[0] = Chain.getValue(0);
1308 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001309 break;
1310 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001311 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001312 case MVT::v4f32:
1313 case MVT::v4i32:
1314 case MVT::v8i16:
1315 case MVT::v16i8:
Dale Johannesenea996922009-02-04 20:06:27 +00001316 Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001317 InFlag).getValue(1);
1318 ResultVals[0] = Chain.getValue(0);
1319 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001320 break;
1321 }
Duncan Sands698842f2008-07-02 17:40:58 +00001322
Scott Michel8efdca42007-12-04 22:23:35 +00001323 // If the function returns void, just return the chain.
1324 if (NumResults == 0)
1325 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001326
Scott Michel8efdca42007-12-04 22:23:35 +00001327 // Otherwise, merge everything together with a MERGE_VALUES node.
1328 ResultVals[NumResults++] = Chain;
Dale Johannesenea996922009-02-04 20:06:27 +00001329 SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl);
Gabor Greif46bf5472008-08-26 22:36:50 +00001330 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001331}
1332
Dan Gohman8181bd12008-07-27 21:46:04 +00001333static SDValue
1334LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-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 Johannesenb03cc3f2009-02-04 23:02:30 +00001338 DebugLoc dl = Op.getDebugLoc();
Owen Andersona0167022009-07-09 17:57:24 +00001339 CCState CCInfo(CC, isVarArg, TM, RVLocs, DAG.getContext());
Gabor Greif1c80d112008-08-28 21:40:38 +00001340 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001341
Scott Michel8efdca42007-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 Lattner1b989192007-12-31 04:13:23 +00001344 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001345 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001346 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001347 }
1348
Dan Gohman8181bd12008-07-27 21:46:04 +00001349 SDValue Chain = Op.getOperand(0);
1350 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001351
Scott Michel8efdca42007-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 Johannesenb03cc3f2009-02-04 23:02:30 +00001356 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
1357 Op.getOperand(i*2+1), Flag);
Scott Michel8efdca42007-12-04 22:23:35 +00001358 Flag = Chain.getValue(1);
1359 }
1360
Gabor Greif1c80d112008-08-28 21:40:38 +00001361 if (Flag.getNode())
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001362 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
Scott Michel8efdca42007-12-04 22:23:35 +00001363 else
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001364 return DAG.getNode(SPUISD::RET_FLAG, dl, MVT::Other, Chain);
Scott Michel8efdca42007-12-04 22:23:35 +00001365}
1366
1367
1368//===----------------------------------------------------------------------===//
1369// Vector related lowering:
1370//===----------------------------------------------------------------------===//
1371
1372static ConstantSDNode *
1373getVecImm(SDNode *N) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001374 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001375
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001379 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001380 OpVal = N->getOperand(i);
1381 else if (OpVal != N->getOperand(i))
1382 return 0;
1383 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001384
Gabor Greif1c80d112008-08-28 21:40:38 +00001385 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001386 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001387 return CN;
1388 }
1389 }
1390
Scott Michel0d5eae02009-03-17 01:15:45 +00001391 return 0;
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001397SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001398 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001399 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001400 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001401 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001402 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001406 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001407 Value = Value >> 32;
1408 }
Scott Michel8efdca42007-12-04 22:23:35 +00001409 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001410 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001411 }
1412
Dan Gohman8181bd12008-07-27 21:46:04 +00001413 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001419SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001420 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001421 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001422 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001423 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001424 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001428 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001429 Value = Value >> 32;
1430 }
Scott Michel6baba072008-03-05 23:02:02 +00001431 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001432 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001433 }
1434 }
1435
Dan Gohman8181bd12008-07-27 21:46:04 +00001436 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001442SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001443 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001444 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001445 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001446 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001447 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-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 Gohman8181bd12008-07-27 21:46:04 +00001451 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001452 Value = Value >> 32;
1453 }
Scott Michel6baba072008-03-05 23:02:02 +00001454 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001455 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001456 }
1457
Dan Gohman8181bd12008-07-27 21:46:04 +00001458 return SDValue();
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001468SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001469 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001470 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001471 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001472 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001473 && Value <= 0xffff /* truncated from uint64_t */
1474 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001475 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001476 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001477 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001478 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001479 }
1480
Dan Gohman8181bd12008-07-27 21:46:04 +00001481 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001482}
1483
1484/// get_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 Gohman8181bd12008-07-27 21:46:04 +00001487SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001488 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001489 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001490 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001491 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001492 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1493 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001494 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001495 }
1496
Dan Gohman8181bd12008-07-27 21:46:04 +00001497 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001498}
1499
1500/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001501SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001502 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001503 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001504 }
1505
Dan Gohman8181bd12008-07-27 21:46:04 +00001506 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001507}
1508
1509/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001510SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001511 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001512 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001513 }
1514
Dan Gohman8181bd12008-07-27 21:46:04 +00001515 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001516}
1517
Scott Michel8c67fa42009-01-21 04:58:48 +00001518//! Lower a BUILD_VECTOR instruction creatively:
1519SDValue
pingbak2f387e82009-01-26 03:31:40 +00001520LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001521 MVT VT = Op.getValueType();
Scott Michel0d5eae02009-03-17 01:15:45 +00001522 MVT EltVT = VT.getVectorElementType();
Dale Johannesen913ba762009-02-06 01:31:28 +00001523 DebugLoc dl = Op.getDebugLoc();
Scott Michel0d5eae02009-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 Michel4ec722e2008-07-16 17:17:29 +00001541
Duncan Sands92c43912008-06-06 12:08:01 +00001542 switch (VT.getSimpleVT()) {
Edwin Török4d9756a2009-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 Michel8c67fa42009-01-21 04:58:48 +00001549 /*NOTREACHED*/
Edwin Török4d9756a2009-07-08 20:53:28 +00001550 }
Scott Michel8efdca42007-12-04 22:23:35 +00001551 case MVT::v4f32: {
pingbak2f387e82009-01-26 03:31:40 +00001552 uint32_t Value32 = uint32_t(SplatBits);
Chris Lattner8579bab2009-03-26 05:29:34 +00001553 assert(SplatBitSize == 32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001554 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001555 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001556 SDValue T = DAG.getConstant(Value32, MVT::i32);
Dale Johannesen913ba762009-02-06 01:31:28 +00001557 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4f32,
Chris Lattner8579bab2009-03-26 05:29:34 +00001558 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, T,T,T,T));
Scott Michel8efdca42007-12-04 22:23:35 +00001559 break;
1560 }
1561 case MVT::v2f64: {
pingbak2f387e82009-01-26 03:31:40 +00001562 uint64_t f64val = uint64_t(SplatBits);
Chris Lattner8579bab2009-03-26 05:29:34 +00001563 assert(SplatBitSize == 64
Scott Michelc630c412008-11-24 17:11:17 +00001564 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001565 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001566 SDValue T = DAG.getConstant(f64val, MVT::i64);
Dale Johannesen913ba762009-02-06 01:31:28 +00001567 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64,
Evan Cheng907a2d22009-02-25 22:49:59 +00001568 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001569 break;
1570 }
1571 case MVT::v16i8: {
1572 // 8-bit constants have to be expanded to 16-bits
Scott Michel0d5eae02009-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 Johannesen913ba762009-02-06 01:31:28 +00001577 return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
Scott Michel0d5eae02009-03-17 01:15:45 +00001578 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v8i16, &Ops[0], Ops.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00001579 }
1580 case MVT::v8i16: {
Scott Michel0d5eae02009-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 Michel8efdca42007-12-04 22:23:35 +00001587 }
1588 case MVT::v4i32: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001589 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Cheng907a2d22009-02-25 22:49:59 +00001590 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
Scott Michel8efdca42007-12-04 22:23:35 +00001591 }
Scott Michel70741542009-01-06 23:10:38 +00001592 case MVT::v2i32: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001593 SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
Evan Cheng907a2d22009-02-25 22:49:59 +00001594 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T);
Scott Michel70741542009-01-06 23:10:38 +00001595 }
Scott Michel8efdca42007-12-04 22:23:35 +00001596 case MVT::v2i64: {
Scott Michel0d5eae02009-03-17 01:15:45 +00001597 return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
Scott Michel8efdca42007-12-04 22:23:35 +00001598 }
1599 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001600
Dan Gohman8181bd12008-07-27 21:46:04 +00001601 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001602}
1603
Scott Michel0d5eae02009-03-17 01:15:45 +00001604/*!
1605 */
pingbak2f387e82009-01-26 03:31:40 +00001606SDValue
Scott Michel0d5eae02009-03-17 01:15:45 +00001607SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal,
1608 DebugLoc dl) {
pingbak2f387e82009-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 Johannesen913ba762009-02-06 01:31:28 +00001615 return DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001616 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1617 Val, Val, Val, Val));
pingbak2f387e82009-01-26 03:31:40 +00001618 } else {
pingbak2f387e82009-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 Michel0d5eae02009-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
pingbak2f387e82009-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 Johannesen913ba762009-02-06 01:31:28 +00001644 LO32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001645 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1646 LO32C, LO32C, LO32C, LO32C));
pingbak2f387e82009-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 Johannesen913ba762009-02-06 01:31:28 +00001652 HI32 = DAG.getNode(ISD::BIT_CONVERT, dl, OpVT,
Evan Cheng907a2d22009-02-25 22:49:59 +00001653 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1654 HI32C, HI32C, HI32C, HI32C));
pingbak2f387e82009-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;
pingbak2f387e82009-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 Johannesen913ba762009-02-06 01:31:28 +00001690 return DAG.getNode(SPUISD::SHUFB, dl, OpVT, HI32, LO32,
Evan Cheng907a2d22009-02-25 22:49:59 +00001691 DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1692 &ShufBytes[0], ShufBytes.size()));
pingbak2f387e82009-01-26 03:31:40 +00001693 }
1694}
1695
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +00001700/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-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 Michel56a125e2008-11-22 23:50:42 +00001704/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00001709static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
Nate Begeman543d2142009-04-27 18:41:29 +00001710 const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +00001711 SDValue V1 = Op.getOperand(0);
1712 SDValue V2 = Op.getOperand(1);
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001713 DebugLoc dl = Op.getDebugLoc();
Scott Michel4ec722e2008-07-16 17:17:29 +00001714
Scott Michel8efdca42007-12-04 22:23:35 +00001715 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001716
Scott Michel8efdca42007-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 Michele2641a12008-12-04 21:01:44 +00001720 MVT VecVT = V1.getValueType();
1721 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001722 unsigned EltsFromV2 = 0;
1723 unsigned V2Elt = 0;
1724 unsigned V2EltIdx0 = 0;
1725 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001726 unsigned MaxElts = VecVT.getVectorNumElements();
1727 unsigned PrevElt = 0;
1728 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001729 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001730 bool rotate = true;
1731
1732 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001733 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001734 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001735 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001736 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001737 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001738 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1739 V2EltIdx0 = 2;
1740 } else
Edwin Törökbd448e32009-07-14 16:55:14 +00001741 llvm_unreachable("Unhandled vector type in LowerVECTOR_SHUFFLE");
Scott Michel8efdca42007-12-04 22:23:35 +00001742
Nate Begeman543d2142009-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 Michel8efdca42007-12-04 22:23:35 +00001748
Nate Begeman543d2142009-04-27 18:41:29 +00001749 if (monotonic) {
1750 if (SrcElt >= V2EltIdx0) {
1751 if (1 >= (++EltsFromV2)) {
1752 V2Elt = (V2EltIdx0 - SrcElt) << 2;
Scott Michele2641a12008-12-04 21:01:44 +00001753 }
Nate Begeman543d2142009-04-27 18:41:29 +00001754 } else if (CurrElt != SrcElt) {
1755 monotonic = false;
Scott Michele2641a12008-12-04 21:01:44 +00001756 }
1757
Nate Begeman543d2142009-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 Michele2641a12008-12-04 21:01:44 +00001765 PrevElt = SrcElt;
Nate Begeman543d2142009-04-27 18:41:29 +00001766 if (SrcElt == 0)
1767 V0Elt = i;
Scott Michele2641a12008-12-04 21:01:44 +00001768 } else {
Scott Michele2641a12008-12-04 21:01:44 +00001769 rotate = false;
1770 }
Nate Begeman543d2142009-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 Michele2641a12008-12-04 21:01:44 +00001777 }
Scott Michel8efdca42007-12-04 22:23:35 +00001778 }
Scott Michel8efdca42007-12-04 22:23:35 +00001779 }
1780
1781 if (EltsFromV2 == 1 && monotonic) {
1782 // Compute mask and shuffle
1783 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001784 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1785 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001786 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001787 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001788 SDValue InitTempReg =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001789 DAG.getCopyToReg(DAG.getEntryNode(), dl, VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001790 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001791 SDValue ShufMaskOp =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001792 DAG.getNode(SPUISD::SHUFFLE_MASK, dl, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001793 DAG.getTargetConstant(V2Elt, MVT::i32),
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001794 DAG.getCopyFromReg(InitTempReg, dl, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001795 // Use shuffle mask in SHUFB synthetic instruction:
Scott Michel34712c32009-03-16 18:47:25 +00001796 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1,
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001797 ShufMaskOp);
Scott Michele2641a12008-12-04 21:01:44 +00001798 } else if (rotate) {
1799 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001800
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001801 return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(),
Scott Michele2641a12008-12-04 21:01:44 +00001802 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001803 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001804 // Convert the SHUFFLE_VECTOR mask's input element units to the
1805 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001806 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001807
Dan Gohman8181bd12008-07-27 21:46:04 +00001808 SmallVector<SDValue, 16> ResultMask;
Nate Begeman543d2142009-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 Michel4ec722e2008-07-16 17:17:29 +00001811
Nate Begeman543d2142009-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 Michel8efdca42007-12-04 22:23:35 +00001814 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001815
Evan Cheng907a2d22009-02-25 22:49:59 +00001816 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
1817 &ResultMask[0], ResultMask.size());
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00001818 return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
Scott Michel8efdca42007-12-04 22:23:35 +00001819 }
1820}
1821
Dan Gohman8181bd12008-07-27 21:46:04 +00001822static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1823 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Dale Johannesen913ba762009-02-06 01:31:28 +00001824 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00001825
Gabor Greif1c80d112008-08-28 21:40:38 +00001826 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-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 Greif1c80d112008-08-28 21:40:38 +00001830 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001831 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001832 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001833 size_t n_copies;
1834
1835 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001836 switch (Op.getValueType().getSimpleVT()) {
Edwin Törökbd448e32009-07-14 16:55:14 +00001837 default: llvm_unreachable("Unexpected constant value type in "
Edwin Törökb2de05e2009-07-14 12:22:58 +00001838 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-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 Gohmanfaeb4a32008-09-12 16:56:44 +00001847 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-12-04 22:23:35 +00001848 for (size_t j = 0; j < n_copies; ++j)
1849 ConstVecValues.push_back(CValue);
1850
Evan Cheng907a2d22009-02-25 22:49:59 +00001851 return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(),
1852 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001853 } else {
1854 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001855 switch (Op0.getValueType().getSimpleVT()) {
Edwin Törökbd448e32009-07-14 16:55:14 +00001856 default: llvm_unreachable("Unexpected value type in LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-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 Johannesen913ba762009-02-06 01:31:28 +00001863 return DAG.getNode(SPUISD::PREFSLOT2VEC, dl, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001864 }
1865 }
1866
Dan Gohman8181bd12008-07-27 21:46:04 +00001867 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001868}
1869
Dan Gohman8181bd12008-07-27 21:46:04 +00001870static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001871 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001872 SDValue N = Op.getOperand(0);
1873 SDValue Elt = Op.getOperand(1);
Dale Johannesen913ba762009-02-06 01:31:28 +00001874 DebugLoc dl = Op.getDebugLoc();
Scott Michel56a125e2008-11-22 23:50:42 +00001875 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001876
Scott Michel56a125e2008-11-22 23:50:42 +00001877 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1878 // Constant argument:
1879 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001880
Scott Michel56a125e2008-11-22 23:50:42 +00001881 // sanity checks:
1882 if (VT == MVT::i8 && EltNo >= 16)
Edwin Törökbd448e32009-07-14 16:55:14 +00001883 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
Scott Michel56a125e2008-11-22 23:50:42 +00001884 else if (VT == MVT::i16 && EltNo >= 8)
Edwin Törökbd448e32009-07-14 16:55:14 +00001885 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
Scott Michel56a125e2008-11-22 23:50:42 +00001886 else if (VT == MVT::i32 && EltNo >= 4)
Edwin Törökbd448e32009-07-14 16:55:14 +00001887 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
Scott Michel56a125e2008-11-22 23:50:42 +00001888 else if (VT == MVT::i64 && EltNo >= 2)
Edwin Törökbd448e32009-07-14 16:55:14 +00001889 llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel8efdca42007-12-04 22:23:35 +00001890
Scott Michel56a125e2008-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 Johannesen913ba762009-02-06 01:31:28 +00001893 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001894 }
Scott Michel8efdca42007-12-04 22:23:35 +00001895
Scott Michel56a125e2008-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 Michele2641a12008-12-04 21:01:44 +00001944 unsigned bidx = i * 4;
Scott Michel56a125e2008-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 Michel0d5eae02009-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 Michel56a125e2008-11-22 23:50:42 +00001955
Dale Johannesen913ba762009-02-06 01:31:28 +00001956 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
1957 DAG.getNode(SPUISD::SHUFB, dl, N.getValueType(),
Scott Michel56a125e2008-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()) {
Edwin Török4d9756a2009-07-08 20:53:28 +00001964 llvm_report_error("LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit"
1965 "vector type!");
Scott Michel56a125e2008-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 Johannesen913ba762009-02-06 01:31:28 +00001970 Elt = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Elt);
Scott Michel56a125e2008-11-22 23:50:42 +00001971
1972 // Scale the index to a bit/byte shift quantity
1973 APInt scaleFactor =
Scott Michelc630c412008-11-24 17:11:17 +00001974 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
1975 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00001976 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00001977
Scott Michelc630c412008-11-24 17:11:17 +00001978 if (scaleShift > 0) {
1979 // Scale the shift factor:
Dale Johannesen913ba762009-02-06 01:31:28 +00001980 Elt = DAG.getNode(ISD::SHL, dl, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00001981 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00001982 }
1983
Dale Johannesen913ba762009-02-06 01:31:28 +00001984 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, dl, VecVT, N, Elt);
Scott Michelc630c412008-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 Michel56a125e2008-11-22 23:50:42 +00001988 SDValue replicate;
1989
1990 switch (VT.getSimpleVT()) {
1991 default:
Edwin Török4d9756a2009-07-08 20:53:28 +00001992 llvm_report_error("LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector"
1993 "type");
Scott Michel56a125e2008-11-22 23:50:42 +00001994 /*NOTREACHED*/
1995 case MVT::i8: {
Scott Michelc630c412008-11-24 17:11:17 +00001996 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00001997 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1998 factor, factor, factor, factor);
Scott Michel56a125e2008-11-22 23:50:42 +00001999 break;
2000 }
2001 case MVT::i16: {
Scott Michelc630c412008-11-24 17:11:17 +00002002 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel0d5eae02009-03-17 01:15:45 +00002003 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2004 factor, factor, factor, factor);
Scott Michel56a125e2008-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 Michel0d5eae02009-03-17 01:15:45 +00002010 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2011 factor, factor, factor, factor);
Scott Michel56a125e2008-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 Michel0d5eae02009-03-17 01:15:45 +00002018 replicate = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
Evan Cheng907a2d22009-02-25 22:49:59 +00002019 loFactor, hiFactor, loFactor, hiFactor);
Scott Michel56a125e2008-11-22 23:50:42 +00002020 break;
2021 }
2022 }
2023
Dale Johannesen913ba762009-02-06 01:31:28 +00002024 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT,
2025 DAG.getNode(SPUISD::SHUFB, dl, VecVT,
Scott Michel0718cd82008-12-01 17:56:02 +00002026 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002027 }
2028
Scott Michel56a125e2008-11-22 23:50:42 +00002029 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002030}
2031
Dan Gohman8181bd12008-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 Johannesen913ba762009-02-06 01:31:28 +00002036 DebugLoc dl = Op.getDebugLoc();
Duncan Sands92c43912008-06-06 12:08:01 +00002037 MVT VT = Op.getValueType();
Scott Michel8efdca42007-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 Sands92c43912008-06-06 12:08:01 +00002042 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-12-01 17:56:02 +00002043 // Use $sp ($1) because it's always 16-byte aligned and it's available:
Dale Johannesen913ba762009-02-06 01:31:28 +00002044 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT,
Scott Michel0718cd82008-12-01 17:56:02 +00002045 DAG.getRegister(SPU::R1, PtrVT),
2046 DAG.getConstant(CN->getSExtValue(), PtrVT));
Dale Johannesen913ba762009-02-06 01:31:28 +00002047 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, dl, VT, Pointer);
Scott Michel8efdca42007-12-04 22:23:35 +00002048
Dan Gohman8181bd12008-07-27 21:46:04 +00002049 SDValue result =
Dale Johannesen913ba762009-02-06 01:31:28 +00002050 DAG.getNode(SPUISD::SHUFB, dl, VT,
2051 DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002052 VecOp,
Dale Johannesen913ba762009-02-06 01:31:28 +00002053 DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002054
2055 return result;
2056}
2057
Scott Michel06eabde2008-12-27 04:51:36 +00002058static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2059 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002060{
Dan Gohman8181bd12008-07-27 21:46:04 +00002061 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Dale Johannesen913ba762009-02-06 01:31:28 +00002062 DebugLoc dl = Op.getDebugLoc();
Scott Michel06eabde2008-12-27 04:51:36 +00002063 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-12-04 22:23:35 +00002064
2065 assert(Op.getValueType() == MVT::i8);
2066 switch (Opc) {
2067 default:
Edwin Törökbd448e32009-07-14 16:55:14 +00002068 llvm_unreachable("Unhandled i8 math operator");
Scott Michel8efdca42007-12-04 22:23:35 +00002069 /*NOTREACHED*/
2070 break;
Scott Michel4d07fb72008-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 Johannesen913ba762009-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 Michel4d07fb72008-12-30 23:28:25 +00002079
2080 }
2081
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002085 SDValue N1 = Op.getOperand(1);
Dale Johannesen913ba762009-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 Michel4ec722e2008-07-16 17:17:29 +00002090 }
Scott Michel8efdca42007-12-04 22:23:35 +00002091 case ISD::ROTR:
2092 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002093 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-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 Gohman8181bd12008-07-27 21:46:04 +00002105 SDValue ExpandArg =
Dale Johannesen913ba762009-02-06 01:31:28 +00002106 DAG.getNode(ISD::OR, dl, MVT::i16, N0,
2107 DAG.getNode(ISD::SHL, dl, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002108 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel0d5eae02009-03-17 01:15:45 +00002109
2110 // Truncate back down to i8
Dale Johannesen913ba762009-02-06 01:31:28 +00002111 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2112 DAG.getNode(Opc, dl, MVT::i16, ExpandArg, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002113 }
2114 case ISD::SRL:
2115 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002116 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-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 Johannesen913ba762009-02-06 01:31:28 +00002129 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2130 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002131 }
2132 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002133 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-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 Johannesen913ba762009-02-06 01:31:28 +00002145 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2146 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002147 }
2148 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002149 SDValue N1 = Op.getOperand(1);
Scott Michel0d5eae02009-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 Johannesen913ba762009-02-06 01:31:28 +00002153 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8,
2154 DAG.getNode(Opc, dl, MVT::i16, N0, N1));
Scott Michel8efdca42007-12-04 22:23:35 +00002155 break;
2156 }
2157 }
2158
Dan Gohman8181bd12008-07-27 21:46:04 +00002159 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002160}
2161
2162//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002163static SDValue
2164LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2165 SDValue ConstVec;
2166 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002167 MVT VT = Op.getValueType();
Dale Johannesen913ba762009-02-06 01:31:28 +00002168 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002169
2170 ConstVec = Op.getOperand(0);
2171 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002172 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2173 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002174 ConstVec = ConstVec.getOperand(0);
2175 } else {
2176 ConstVec = Op.getOperand(1);
2177 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002178 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002179 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002180 }
2181 }
2182 }
2183
Gabor Greif1c80d112008-08-28 21:40:38 +00002184 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel0d5eae02009-03-17 01:15:45 +00002185 BuildVectorSDNode *BCN = dyn_cast<BuildVectorSDNode>(ConstVec.getNode());
2186 assert(BCN != 0 && "Expected BuildVectorSDNode in SPU LowerByteImmed");
Scott Michel8efdca42007-12-04 22:23:35 +00002187
Scott Michel0d5eae02009-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 Gohman8181bd12008-07-27 21:46:04 +00002197 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002198
Scott Michel0d5eae02009-03-17 01:15:45 +00002199 SmallVector<SDValue, 16> tcVec;
2200 tcVec.assign(16, tc);
Dale Johannesen913ba762009-02-06 01:31:28 +00002201 return DAG.getNode(Op.getNode()->getOpcode(), dl, VT, Arg,
Scott Michel0d5eae02009-03-17 01:15:45 +00002202 DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &tcVec[0], tcVec.size()));
Scott Michel8efdca42007-12-04 22:23:35 +00002203 }
2204 }
Scott Michelc899a122009-01-26 22:33:37 +00002205
Nate Begeman7569e762008-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 Michel8efdca42007-12-04 22:23:35 +00002209}
2210
Scott Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002217static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002218 MVT VT = Op.getValueType();
2219 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002220 DebugLoc dl = Op.getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002221
Duncan Sands92c43912008-06-06 12:08:01 +00002222 switch (VT.getSimpleVT()) {
2223 default:
2224 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002225 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002226 SDValue N = Op.getOperand(0);
2227 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002228
Dale Johannesenb03cc3f2009-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 Michel8efdca42007-12-04 22:23:35 +00002231
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002232 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i8, CNTB, Elt0);
Scott Michel8efdca42007-12-04 22:23:35 +00002233 }
2234
2235 case MVT::i16: {
2236 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002237 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002238
Chris Lattner1b989192007-12-31 04:13:23 +00002239 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002240
Dan Gohman8181bd12008-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 Sands7aef60d2008-10-30 19:24:28 +00002244 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002245
Dale Johannesenb03cc3f2009-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 Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002251 SDValue CNTB_result =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002252 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002253
Dan Gohman8181bd12008-07-27 21:46:04 +00002254 SDValue CNTB_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002255 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel8efdca42007-12-04 22:23:35 +00002256
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002257 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002258
Dale Johannesenb03cc3f2009-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 Michel5a6f17b2008-01-30 02:55:46 +00002262 Tmp1, Shift1),
2263 Tmp1),
2264 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002265 }
2266
2267 case MVT::i32: {
2268 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002269 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002270
Chris Lattner1b989192007-12-31 04:13:23 +00002271 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2272 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002273
Dan Gohman8181bd12008-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 Michel8efdca42007-12-04 22:23:35 +00002279
Dale Johannesenb03cc3f2009-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 Michel8efdca42007-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 Gohman8181bd12008-07-27 21:46:04 +00002285 SDValue CNTB_result =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002286 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002287
Dan Gohman8181bd12008-07-27 21:46:04 +00002288 SDValue CNTB_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002289 DAG.getCopyToReg(CNTB_result, dl, CNTB_reg, CNTB_result);
Scott Michel8efdca42007-12-04 22:23:35 +00002290
Dan Gohman8181bd12008-07-27 21:46:04 +00002291 SDValue Comp1 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002292 DAG.getNode(ISD::SRL, dl, MVT::i32,
Scott Michel34712c32009-03-16 18:47:25 +00002293 DAG.getCopyFromReg(CNTB_rescopy, dl, CNTB_reg, MVT::i32),
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002294 Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002295
Dan Gohman8181bd12008-07-27 21:46:04 +00002296 SDValue Sum1 =
Dale Johannesenb03cc3f2009-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 Michel8efdca42007-12-04 22:23:35 +00002299
Dan Gohman8181bd12008-07-27 21:46:04 +00002300 SDValue Sum1_rescopy =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002301 DAG.getCopyToReg(CNTB_result, dl, SUM1_reg, Sum1);
Scott Michel8efdca42007-12-04 22:23:35 +00002302
Dan Gohman8181bd12008-07-27 21:46:04 +00002303 SDValue Comp2 =
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002304 DAG.getNode(ISD::SRL, dl, MVT::i32,
2305 DAG.getCopyFromReg(Sum1_rescopy, dl, SUM1_reg, MVT::i32),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002306 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002307 SDValue Sum2 =
Dale Johannesenb03cc3f2009-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 Michel8efdca42007-12-04 22:23:35 +00002310
Dale Johannesenb03cc3f2009-02-04 23:02:30 +00002311 return DAG.getNode(ISD::AND, dl, MVT::i32, Sum2, Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002312 }
2313
2314 case MVT::i64:
2315 break;
2316 }
2317
Dan Gohman8181bd12008-07-27 21:46:04 +00002318 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002319}
2320
pingbak2f387e82009-01-26 03:31:40 +00002321//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Michel8c67fa42009-01-21 04:58:48 +00002322/*!
pingbak2f387e82009-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 Michel8c67fa42009-01-21 04:58:48 +00002325 */
pingbak2f387e82009-01-26 03:31:40 +00002326static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2327 SPUTargetLowering &TLI) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002328 MVT OpVT = Op.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002329 SDValue Op0 = Op.getOperand(0);
pingbak2f387e82009-01-26 03:31:40 +00002330 MVT Op0VT = Op0.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002331
pingbak2f387e82009-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 Michel8c67fa42009-01-21 04:58:48 +00002343
Eli Friedman9d77ac32009-05-27 00:47:34 +00002344 return Op;
pingbak2f387e82009-01-26 03:31:40 +00002345}
Scott Michel8c67fa42009-01-21 04:58:48 +00002346
pingbak2f387e82009-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 Friedman9d77ac32009-05-27 00:47:34 +00002370 return Op;
Scott Michel8c67fa42009-01-21 04:58:48 +00002371}
2372
2373//! Lower ISD::SETCC
2374/*!
2375 This handles MVT::f64 (double floating point) condition lowering
2376 */
Scott Michel8c67fa42009-01-21 04:58:48 +00002377static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2378 const TargetLowering &TLI) {
pingbak2f387e82009-01-26 03:31:40 +00002379 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen2dbdb0e2009-02-07 19:59:05 +00002380 DebugLoc dl = Op.getDebugLoc();
pingbak2f387e82009-01-26 03:31:40 +00002381 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2382
Scott Michel8c67fa42009-01-21 04:58:48 +00002383 SDValue lhs = Op.getOperand(0);
2384 SDValue rhs = Op.getOperand(1);
Scott Michel8c67fa42009-01-21 04:58:48 +00002385 MVT lhsVT = lhs.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002386 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2387
pingbak2f387e82009-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 Johannesen85fc0932009-02-04 01:48:28 +00002394 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
pingbak2f387e82009-01-26 03:31:40 +00002395 SDValue lhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002396 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2397 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002398 i64lhs, DAG.getConstant(32, MVT::i32)));
2399 SDValue lhsHi32abs =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002400 DAG.getNode(ISD::AND, dl, MVT::i32,
pingbak2f387e82009-01-26 03:31:40 +00002401 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2402 SDValue lhsLo32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002403 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
pingbak2f387e82009-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 Johannesen85fc0932009-02-04 01:48:28 +00002410 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2411 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-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 Johannesen85fc0932009-02-04 01:48:28 +00002417 return DAG.getNode(ISD::AND, dl, ccResultVT,
2418 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002419 lhsHi32abs,
2420 DAG.getConstant(0x7ff00000, MVT::i32),
2421 ISD::SETGE),
Dale Johannesen85fc0932009-02-04 01:48:28 +00002422 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002423 lhsLo32,
2424 DAG.getConstant(0, MVT::i32),
2425 ISD::SETGT));
2426 }
2427
Dale Johannesen24dd9a52009-02-07 00:55:49 +00002428 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, rhs);
pingbak2f387e82009-01-26 03:31:40 +00002429 SDValue rhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002430 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2431 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-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 Johannesen85fc0932009-02-04 01:48:28 +00002438 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002439 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002440 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
pingbak2f387e82009-01-26 03:31:40 +00002441 SDValue lhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002442 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002443 lhsSelectMask, lhsSignMag2TC, i64lhs);
2444
Dale Johannesen85fc0932009-02-04 01:48:28 +00002445 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002446 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002447 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
pingbak2f387e82009-01-26 03:31:40 +00002448 SDValue rhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002449 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002450 rhsSelectMask, rhsSignMag2TC, i64rhs);
2451
2452 unsigned compareOp;
2453
Scott Michel8c67fa42009-01-21 04:58:48 +00002454 switch (CC->get()) {
2455 case ISD::SETOEQ:
Scott Michel8c67fa42009-01-21 04:58:48 +00002456 case ISD::SETUEQ:
pingbak2f387e82009-01-26 03:31:40 +00002457 compareOp = ISD::SETEQ; break;
2458 case ISD::SETOGT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002459 case ISD::SETUGT:
pingbak2f387e82009-01-26 03:31:40 +00002460 compareOp = ISD::SETGT; break;
2461 case ISD::SETOGE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002462 case ISD::SETUGE:
pingbak2f387e82009-01-26 03:31:40 +00002463 compareOp = ISD::SETGE; break;
2464 case ISD::SETOLT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002465 case ISD::SETULT:
pingbak2f387e82009-01-26 03:31:40 +00002466 compareOp = ISD::SETLT; break;
2467 case ISD::SETOLE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002468 case ISD::SETULE:
pingbak2f387e82009-01-26 03:31:40 +00002469 compareOp = ISD::SETLE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002470 case ISD::SETUNE:
pingbak2f387e82009-01-26 03:31:40 +00002471 case ISD::SETONE:
2472 compareOp = ISD::SETNE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002473 default:
Edwin Török4d9756a2009-07-08 20:53:28 +00002474 llvm_report_error("CellSPU ISel Select: unimplemented f64 condition");
Scott Michel8c67fa42009-01-21 04:58:48 +00002475 }
2476
pingbak2f387e82009-01-26 03:31:40 +00002477 SDValue result =
Scott Michel34712c32009-03-16 18:47:25 +00002478 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
Dale Johannesen85fc0932009-02-04 01:48:28 +00002479 (ISD::CondCode) compareOp);
pingbak2f387e82009-01-26 03:31:40 +00002480
2481 if ((CC->get() & 0x8) == 0) {
2482 // Ordered comparison:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002483 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002484 lhs, DAG.getConstantFP(0.0, MVT::f64),
2485 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002486 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002487 rhs, DAG.getConstantFP(0.0, MVT::f64),
2488 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002489 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
pingbak2f387e82009-01-26 03:31:40 +00002490
Dale Johannesen85fc0932009-02-04 01:48:28 +00002491 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
pingbak2f387e82009-01-26 03:31:40 +00002492 }
2493
2494 return result;
Scott Michel8c67fa42009-01-21 04:58:48 +00002495}
2496
Scott Michel56a125e2008-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 Michel06eabde2008-12-27 04:51:36 +00002509static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2510 const TargetLowering &TLI) {
Scott Michel56a125e2008-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 Johannesen175fdef2009-02-06 21:50:26 +00002517 DebugLoc dl = Op.getDebugLoc();
Scott Michel56a125e2008-11-22 23:50:42 +00002518
Scott Michel06eabde2008-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 Michel56a125e2008-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 Johannesen175fdef2009-02-06 21:50:26 +00002530 SDValue compare = DAG.getNode(ISD::SETCC, dl,
Duncan Sands4a361272009-01-01 15:52:00 +00002531 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002532 lhs, rhs, condition);
Dale Johannesen175fdef2009-02-06 21:50:26 +00002533 return DAG.getNode(SPUISD::SELB, dl, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002534}
2535
Scott Michelec8c82e2008-12-02 19:53:53 +00002536//! Custom lower ISD::TRUNCATE
2537static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2538{
Scott Michel34712c32009-03-16 18:47:25 +00002539 // Type to truncate to
Scott Michelec8c82e2008-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 Johannesen175fdef2009-02-06 21:50:26 +00002543 DebugLoc dl = Op.getDebugLoc();
Scott Michelec8c82e2008-12-02 19:53:53 +00002544
Scott Michel34712c32009-03-16 18:47:25 +00002545 // Type to truncate from
Scott Michelec8c82e2008-12-02 19:53:53 +00002546 SDValue Op0 = Op.getOperand(0);
2547 MVT Op0VT = Op0.getValueType();
Scott Michelec8c82e2008-12-02 19:53:53 +00002548
Scott Michel06eabde2008-12-27 04:51:36 +00002549 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002550 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-12-27 04:51:36 +00002551 unsigned maskHigh = 0x08090a0b;
2552 unsigned maskLow = 0x0c0d0e0f;
2553 // Use a shuffle to perform the truncation
Evan Cheng907a2d22009-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 Michel06eabde2008-12-27 04:51:36 +00002559
Scott Michel34712c32009-03-16 18:47:25 +00002560 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, dl, VecVT,
2561 Op0, Op0, shufMask);
Scott Michel06eabde2008-12-27 04:51:36 +00002562
Scott Michel34712c32009-03-16 18:47:25 +00002563 return DAG.getNode(SPUISD::VEC2PREFSLOT, dl, VT, truncShuffle);
Scott Michelec8c82e2008-12-02 19:53:53 +00002564 }
2565
Scott Michel06eabde2008-12-27 04:51:36 +00002566 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002567}
2568
Scott Michel56a125e2008-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 Gohman8181bd12008-07-27 21:46:04 +00002574SDValue
2575SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002576{
Scott Michel97872d32008-02-23 18:41:37 +00002577 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002578 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002579
2580 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002581 default: {
Edwin Török4d9756a2009-07-08 20:53:28 +00002582#ifndef NDEBUG
Scott Michel8efdca42007-12-04 22:23:35 +00002583 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002584 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002585 cerr << "*Op.getNode():\n";
2586 Op.getNode()->dump();
Edwin Török4d9756a2009-07-08 20:53:28 +00002587#endif
Edwin Törökbd448e32009-07-14 16:55:14 +00002588 llvm_unreachable(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002589 }
2590 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002591 case ISD::EXTLOAD:
Scott Michel8efdca42007-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 Michel8efdca42007-12-04 22:23:35 +00002603 case ISD::ConstantFP:
2604 return LowerConstantFP(Op, DAG);
2605 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002606 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002607 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002608 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002609 case ISD::RET:
2610 return LowerRET(Op, DAG, getTargetMachine());
2611
Scott Michel4d07fb72008-12-30 23:28:25 +00002612 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002613 case ISD::ADD:
Scott Michel8efdca42007-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 Michel67224b22008-06-02 22:18:03 +00002619 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002620 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002621 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002622 break;
Scott Michel67224b22008-06-02 22:18:03 +00002623 }
Scott Michel8efdca42007-12-04 22:23:35 +00002624
pingbak2f387e82009-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 Michel8c67fa42009-01-21 04:58:48 +00002632
Scott Michel8efdca42007-12-04 22:23:35 +00002633 // Vector-related lowering.
2634 case ISD::BUILD_VECTOR:
pingbak2f387e82009-01-26 03:31:40 +00002635 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel8efdca42007-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 Michel4d07fb72008-12-30 23:28:25 +00002653 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002654 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002655
Scott Michel8efdca42007-12-04 22:23:35 +00002656 case ISD::CTPOP:
2657 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002658
2659 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002660 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002661
Scott Michel8c67fa42009-01-21 04:58:48 +00002662 case ISD::SETCC:
2663 return LowerSETCC(Op, DAG, *this);
2664
Scott Michelec8c82e2008-12-02 19:53:53 +00002665 case ISD::TRUNCATE:
2666 return LowerTRUNCATE(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002667 }
2668
Dan Gohman8181bd12008-07-27 21:46:04 +00002669 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002670}
2671
Duncan Sands7d9834b2008-12-01 11:39:25 +00002672void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2673 SmallVectorImpl<SDValue>&Results,
2674 SelectionDAG &DAG)
Scott Michel6e2d68b2008-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 Michel6e2d68b2008-11-10 23:43:06 +00002693}
2694
Scott Michel8efdca42007-12-04 22:23:35 +00002695//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002696// Target Optimization Hooks
2697//===----------------------------------------------------------------------===//
2698
Dan Gohman8181bd12008-07-27 21:46:04 +00002699SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002700SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2701{
2702#if 0
2703 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002704#endif
2705 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002706 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-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 Michel06eabde2008-12-27 04:51:36 +00002709 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002710 SDValue Result; // Initially, empty result
Dale Johannesen175fdef2009-02-06 21:50:26 +00002711 DebugLoc dl = N->getDebugLoc();
Scott Michel8efdca42007-12-04 22:23:35 +00002712
2713 switch (N->getOpcode()) {
2714 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002715 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002716 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002717
Scott Michel06eabde2008-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 Michelae5cbf52008-12-29 03:23:36 +00002722
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002735
Scott Michel8c2746e2008-12-04 17:16:59 +00002736#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002737 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002738 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002739 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2740 << "With: (SPUindirect <arg>, <arg>)\n";
2741 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002742#endif
2743
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002751
Scott Michel06eabde2008-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 Michelf9f42e62008-01-29 02:16:57 +00002761
Dale Johannesen175fdef2009-02-06 21:50:26 +00002762 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel06eabde2008-12-27 04:51:36 +00002763 IndirectArg, combinedValue);
2764 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002765 }
2766 }
Scott Michel97872d32008-02-23 18:41:37 +00002767 break;
2768 }
2769 case ISD::SIGN_EXTEND:
2770 case ISD::ZERO_EXTEND:
2771 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002772 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002773 // (any_extend (SPUextract_elt0 <arg>)) ->
2774 // (SPUextract_elt0 <arg>)
2775 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002776#if !defined(NDEBUG)
2777 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002778 cerr << "\nReplace: ";
2779 N->dump(&DAG);
2780 cerr << "\nWith: ";
2781 Op0.getNode()->dump(&DAG);
2782 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002783 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002784#endif
Scott Michel97872d32008-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 Michel8c67fa42009-01-21 04:58:48 +00002792 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2793 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michel97872d32008-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 Greif1c80d112008-08-28 21:40:38 +00002800 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002801 DEBUG(cerr << "\n");
2802
2803 return Op0;
2804 }
Scott Michel06eabde2008-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 Johannesen175fdef2009-02-06 21:50:26 +00002820 return DAG.getNode(SPUISD::IndirectAddr, dl, Op0VT,
Scott Michel06eabde2008-12-27 04:51:36 +00002821 Op0.getOperand(0), Op0.getOperand(1));
2822 }
2823 }
Scott Michel97872d32008-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 Michel06eabde2008-12-27 04:51:36 +00002832 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002833 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002834
Scott Michel06eabde2008-12-27 04:51:36 +00002835 // Kill degenerate vector shifts:
2836 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2837 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002838 Result = Op0;
2839 }
2840 }
2841 break;
2842 }
Scott Michel06eabde2008-12-27 04:51:36 +00002843 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-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 Michelae5cbf52008-12-29 03:23:36 +00002850 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002851 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002852 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002853 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002854 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002855 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002856 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002857 Result = Op000;
2858 }
2859 }
2860 break;
2861 }
Scott Michelc630c412008-11-24 17:11:17 +00002862 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002863 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002864 // <arg>
2865 Result = Op0.getOperand(0);
2866 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002867 }
Scott Michel97872d32008-02-23 18:41:37 +00002868 }
2869 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002870 }
2871 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002872
Scott Michel394e26d2008-01-17 20:38:41 +00002873 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002874#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002875 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002876 DEBUG(cerr << "\nReplace.SPU: ");
2877 DEBUG(N->dump(&DAG));
2878 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002879 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002880 DEBUG(cerr << "\n");
2881 }
2882#endif
2883
2884 return Result;
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002893SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002904 }
Scott Michel8efdca42007-12-04 22:23:35 +00002905 }
2906 return TargetLowering::getConstraintType(ConstraintLetter);
2907}
2908
Scott Michel4ec722e2008-07-16 17:17:29 +00002909std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002910SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002911 MVT VT) const
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00002927 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00002928 return std::make_pair(0U, SPU::GPRCRegisterClass);
2929 }
2930 }
Scott Michel4ec722e2008-07-16 17:17:29 +00002931
Scott Michel8efdca42007-12-04 22:23:35 +00002932 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
2933}
2934
Scott Michel97872d32008-02-23 18:41:37 +00002935//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00002936void
Dan Gohman8181bd12008-07-27 21:46:04 +00002937SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00002938 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00002939 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00002940 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002941 const SelectionDAG &DAG,
2942 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00002943#if 0
Dan Gohmand06cad62009-04-01 18:45:54 +00002944 const uint64_t uint64_sizebits = sizeof(uint64_t) * CHAR_BIT;
Scott Michel97872d32008-02-23 18:41:37 +00002945
2946 switch (Op.getOpcode()) {
2947 default:
2948 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
2949 break;
Scott Michel97872d32008-02-23 18:41:37 +00002950 case CALL:
2951 case SHUFB:
Scott Michel56a125e2008-11-22 23:50:42 +00002952 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00002953 case CNTB:
Scott Michel8c67fa42009-01-21 04:58:48 +00002954 case SPUISD::PREFSLOT2VEC:
Scott Michel97872d32008-02-23 18:41:37 +00002955 case SPUISD::LDRESULT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002956 case SPUISD::VEC2PREFSLOT:
Scott Michelbc5fbc12008-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 Michelbc5fbc12008-04-30 00:30:08 +00002964 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00002965 case SPUISD::SELECT_MASK:
2966 case SPUISD::SELB:
Scott Michel97872d32008-02-23 18:41:37 +00002967 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002968#endif
Scott Michel8efdca42007-12-04 22:23:35 +00002969}
Scott Michel4d07fb72008-12-30 23:28:25 +00002970
Scott Michel06eabde2008-12-27 04:51:36 +00002971unsigned
2972SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
2973 unsigned Depth) const {
2974 switch (Op.getOpcode()) {
2975 default:
2976 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00002977
Scott Michel06eabde2008-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 Michelae5cbf52008-12-29 03:23:36 +00002988
Scott Michelbc5fbc12008-04-30 00:30:08 +00002989// LowerAsmOperandForConstraint
2990void
Dan Gohman8181bd12008-07-27 21:46:04 +00002991SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002992 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00002993 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00002994 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00002995 SelectionDAG &DAG) const {
2996 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00002997 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
2998 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00002999}
3000
Scott Michel8efdca42007-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 Greife9f7f582008-08-31 15:37:04 +00003003bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3004 const Type *Ty) const {
Scott Michel8efdca42007-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 Michel4ec722e2008-07-16 17:17:29 +00003010 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00003011}
Dan Gohman36322c72008-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}