blob: 9e48962cce7850c7435968263fdae729ed7e9248 [file] [log] [blame]
Scott Michel8efdca42007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel8efdca42007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michelbc5fbc12008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michel06eabde2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel8efdca42007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
pingbak2f387e82009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel8efdca42007-12-04 22:23:35 +000021#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner1b989192007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel8efdca42007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel8efdca42007-12-04 22:23:35 +000027#include "llvm/Constants.h"
28#include "llvm/Function.h"
29#include "llvm/Intrinsics.h"
30#include "llvm/Support/Debug.h"
31#include "llvm/Support/MathExtras.h"
32#include "llvm/Target/TargetOptions.h"
33
34#include <map>
35
36using namespace llvm;
37
38// Used in getTargetNodeName() below
39namespace {
40 std::map<unsigned, const char *> node_names;
41
Duncan Sands92c43912008-06-06 12:08:01 +000042 //! MVT mapping to useful data for Cell SPU
Scott Michel8efdca42007-12-04 22:23:35 +000043 struct valtype_map_s {
Scott Michel56a125e2008-11-22 23:50:42 +000044 const MVT valtype;
45 const int prefslot_byte;
Scott Michel8efdca42007-12-04 22:23:35 +000046 };
Scott Michel4ec722e2008-07-16 17:17:29 +000047
Scott Michel8efdca42007-12-04 22:23:35 +000048 const valtype_map_s valtype_map[] = {
49 { MVT::i1, 3 },
50 { MVT::i8, 3 },
51 { MVT::i16, 2 },
52 { MVT::i32, 0 },
53 { MVT::f32, 0 },
54 { MVT::i64, 0 },
55 { MVT::f64, 0 },
56 { MVT::i128, 0 }
57 };
58
59 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
60
Duncan Sands92c43912008-06-06 12:08:01 +000061 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel8efdca42007-12-04 22:23:35 +000062 const valtype_map_s *retval = 0;
63
64 for (size_t i = 0; i < n_valtype_map; ++i) {
65 if (valtype_map[i].valtype == VT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +000066 retval = valtype_map + i;
67 break;
Scott Michel8efdca42007-12-04 22:23:35 +000068 }
69 }
70
71#ifndef NDEBUG
72 if (retval == 0) {
73 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands92c43912008-06-06 12:08:01 +000074 << VT.getMVTString()
Scott Michel5a6f17b2008-01-30 02:55:46 +000075 << "\n";
Scott Michel8efdca42007-12-04 22:23:35 +000076 abort();
77 }
78#endif
79
80 return retval;
81 }
Scott Michel750b93f2009-01-15 04:41:47 +000082
pingbak2f387e82009-01-26 03:31:40 +000083 //! Expand a library call into an actual call DAG node
84 /*!
85 \note
86 This code is taken from SelectionDAGLegalize, since it is not exposed as
87 part of the LLVM SelectionDAG API.
88 */
89
90 SDValue
91 ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG,
92 bool isSigned, SDValue &Hi, SPUTargetLowering &TLI) {
93 // The input chain to this libcall is the entry node of the function.
94 // Legalizing the call will automatically add the previous call to the
95 // dependence.
96 SDValue InChain = DAG.getEntryNode();
97
98 TargetLowering::ArgListTy Args;
99 TargetLowering::ArgListEntry Entry;
100 for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
101 MVT ArgVT = Op.getOperand(i).getValueType();
102 const Type *ArgTy = ArgVT.getTypeForMVT();
103 Entry.Node = Op.getOperand(i);
104 Entry.Ty = ArgTy;
105 Entry.isSExt = isSigned;
106 Entry.isZExt = !isSigned;
107 Args.push_back(Entry);
108 }
109 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
110 TLI.getPointerTy());
111
112 // Splice the libcall in wherever FindInputOutputChains tells us to.
113 const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
114 std::pair<SDValue, SDValue> CallInfo =
115 TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
Dale Johannesenca6237b2009-01-30 23:10:59 +0000116 CallingConv::C, false, Callee, Args, DAG,
117 Op.getNode()->getDebugLoc());
pingbak2f387e82009-01-26 03:31:40 +0000118
119 return CallInfo.first;
120 }
Scott Michel8efdca42007-12-04 22:23:35 +0000121}
122
123SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
124 : TargetLowering(TM),
125 SPUTM(TM)
126{
127 // Fold away setcc operations if possible.
128 setPow2DivIsCheap();
129
130 // Use _setjmp/_longjmp instead of setjmp/longjmp.
131 setUseUnderscoreSetJmp(true);
132 setUseUnderscoreLongJmp(true);
Scott Michel4ec722e2008-07-16 17:17:29 +0000133
Scott Michel8c67fa42009-01-21 04:58:48 +0000134 // Set RTLIB libcall names as used by SPU:
135 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
136
Scott Michel8efdca42007-12-04 22:23:35 +0000137 // Set up the SPU's register classes:
Scott Michel438be252007-12-17 22:32:34 +0000138 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
139 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
140 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
141 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
142 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
143 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel8efdca42007-12-04 22:23:35 +0000144 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel4ec722e2008-07-16 17:17:29 +0000145
Scott Michel8efdca42007-12-04 22:23:35 +0000146 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng08c171a2008-10-14 21:26:46 +0000147 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
148 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
149 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +0000150
Scott Michel06eabde2008-12-27 04:51:36 +0000151 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
152 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelec8c82e2008-12-02 19:53:53 +0000153
Scott Michel8efdca42007-12-04 22:23:35 +0000154 // SPU constant load actions are custom lowered:
Nate Begeman78125042008-02-14 18:43:04 +0000155 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000156 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
157
158 // SPU's loads and stores have to be custom lowered:
Scott Michel2ef773a2009-01-06 03:36:14 +0000159 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel8efdca42007-12-04 22:23:35 +0000160 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000161 MVT VT = (MVT::SimpleValueType)sctype;
162
Scott Michel06eabde2008-12-27 04:51:36 +0000163 setOperationAction(ISD::LOAD, VT, Custom);
164 setOperationAction(ISD::STORE, VT, Custom);
165 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
166 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
167 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
168
169 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
170 MVT StoreVT = (MVT::SimpleValueType) stype;
171 setTruncStoreAction(VT, StoreVT, Expand);
172 }
Scott Michel8efdca42007-12-04 22:23:35 +0000173 }
174
Scott Michel06eabde2008-12-27 04:51:36 +0000175 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
176 ++sctype) {
177 MVT VT = (MVT::SimpleValueType) sctype;
178
179 setOperationAction(ISD::LOAD, VT, Custom);
180 setOperationAction(ISD::STORE, VT, Custom);
181
182 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
183 MVT StoreVT = (MVT::SimpleValueType) stype;
184 setTruncStoreAction(VT, StoreVT, Expand);
185 }
186 }
187
Scott Michel8efdca42007-12-04 22:23:35 +0000188 // Expand the jumptable branches
189 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
190 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel56a125e2008-11-22 23:50:42 +0000191
192 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel4ec722e2008-07-16 17:17:29 +0000193 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel56a125e2008-11-22 23:50:42 +0000194 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
195 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
196 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
197 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000198
199 // SPU has no intrinsics for these particular operations:
Andrew Lenharth0531ec52008-02-16 14:46:26 +0000200 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
201
Scott Michel06eabde2008-12-27 04:51:36 +0000202 // SPU has no SREM/UREM instructions
Scott Michel8efdca42007-12-04 22:23:35 +0000203 setOperationAction(ISD::SREM, MVT::i32, Expand);
204 setOperationAction(ISD::UREM, MVT::i32, Expand);
205 setOperationAction(ISD::SREM, MVT::i64, Expand);
206 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000207
Scott Michel8efdca42007-12-04 22:23:35 +0000208 // We don't support sin/cos/sqrt/fmod
209 setOperationAction(ISD::FSIN , MVT::f64, Expand);
210 setOperationAction(ISD::FCOS , MVT::f64, Expand);
211 setOperationAction(ISD::FREM , MVT::f64, Expand);
212 setOperationAction(ISD::FSIN , MVT::f32, Expand);
213 setOperationAction(ISD::FCOS , MVT::f32, Expand);
214 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000215
pingbak2f387e82009-01-26 03:31:40 +0000216 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
217 // for f32!)
Scott Michel8efdca42007-12-04 22:23:35 +0000218 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
219 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000220
Scott Michel8efdca42007-12-04 22:23:35 +0000221 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
222 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
223
224 // SPU can do rotate right and left, so legalize it... but customize for i8
225 // because instructions don't exist.
Bill Wendling965299c2008-08-31 02:59:23 +0000226
227 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
228 // .td files.
229 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
230 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
231 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
232
Scott Michel8efdca42007-12-04 22:23:35 +0000233 setOperationAction(ISD::ROTL, MVT::i32, Legal);
234 setOperationAction(ISD::ROTL, MVT::i16, Legal);
235 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Michelabb8ca12008-11-20 16:36:33 +0000236
Scott Michel8efdca42007-12-04 22:23:35 +0000237 // SPU has no native version of shift left/right for i8
238 setOperationAction(ISD::SHL, MVT::i8, Custom);
239 setOperationAction(ISD::SRL, MVT::i8, Custom);
240 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel33d73eb2008-11-21 02:56:16 +0000241
Scott Michel4d07fb72008-12-30 23:28:25 +0000242 // Make these operations legal and handle them during instruction selection:
243 setOperationAction(ISD::SHL, MVT::i64, Legal);
244 setOperationAction(ISD::SRL, MVT::i64, Legal);
245 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000246
Scott Michel4ec722e2008-07-16 17:17:29 +0000247 // Custom lower i8, i32 and i64 multiplications
248 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michelae5cbf52008-12-29 03:23:36 +0000249 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel750b93f2009-01-15 04:41:47 +0000250 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel33d73eb2008-11-21 02:56:16 +0000251
Scott Michel67224b22008-06-02 22:18:03 +0000252 // Need to custom handle (some) common i8, i64 math ops
Scott Michel4d07fb72008-12-30 23:28:25 +0000253 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000254 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000255 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel750b93f2009-01-15 04:41:47 +0000256 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000257
Scott Michel8efdca42007-12-04 22:23:35 +0000258 // SPU does not have BSWAP. It does have i32 support CTLZ.
259 // CTPOP has to be custom lowered.
260 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
261 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
262
263 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
264 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
265 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
266 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
267
268 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
269 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
270
271 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000272
Scott Michel67224b22008-06-02 22:18:03 +0000273 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel978b96f2008-03-10 23:49:09 +0000274 // select ought to work:
Scott Michel53ab7792008-03-10 16:58:52 +0000275 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michel6baba072008-03-05 23:02:02 +0000276 setOperationAction(ISD::SELECT, MVT::i16, Legal);
277 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michel06eabde2008-12-27 04:51:36 +0000278 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000279
Scott Michel53ab7792008-03-10 16:58:52 +0000280 setOperationAction(ISD::SETCC, MVT::i8, Legal);
281 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000282 setOperationAction(ISD::SETCC, MVT::i32, Legal);
283 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Michel8c67fa42009-01-21 04:58:48 +0000284 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michel6baba072008-03-05 23:02:02 +0000285
Scott Michel06eabde2008-12-27 04:51:36 +0000286 // Custom lower i128 -> i64 truncates
Scott Michelec8c82e2008-12-02 19:53:53 +0000287 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
288
pingbak2f387e82009-01-26 03:31:40 +0000289 // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
290 // to expand to a libcall, hence the custom lowering:
291 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
292 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000293
294 // FDIV on SPU requires custom lowering
pingbak2f387e82009-01-26 03:31:40 +0000295 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel8efdca42007-12-04 22:23:35 +0000296
Scott Michelc899a122009-01-26 22:33:37 +0000297 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
pingbak2f387e82009-01-26 03:31:40 +0000298 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000299 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000300 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
301 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000302 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
pingbak2f387e82009-01-26 03:31:40 +0000303 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +0000304 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
305 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
306
Scott Michel754d8662007-12-20 00:44:13 +0000307 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
308 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
309 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
310 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel8efdca42007-12-04 22:23:35 +0000311
312 // We cannot sextinreg(i1). Expand to shifts.
313 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000314
Scott Michel8efdca42007-12-04 22:23:35 +0000315 // Support label based line numbers.
Dan Gohman472d12c2008-06-30 20:59:49 +0000316 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000317 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000318
319 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel8efdca42007-12-04 22:23:35 +0000320 // appropriate instructions to materialize the address.
Scott Michel33d73eb2008-11-21 02:56:16 +0000321 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michelf9f42e62008-01-29 02:16:57 +0000322 ++sctype) {
Duncan Sands92c43912008-06-06 12:08:01 +0000323 MVT VT = (MVT::SimpleValueType)sctype;
324
Scott Michelae5cbf52008-12-29 03:23:36 +0000325 setOperationAction(ISD::GlobalAddress, VT, Custom);
326 setOperationAction(ISD::ConstantPool, VT, Custom);
327 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michelf9f42e62008-01-29 02:16:57 +0000328 }
Scott Michel8efdca42007-12-04 22:23:35 +0000329
330 // RET must be custom lowered, to meet ABI requirements
331 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000332
Scott Michel8efdca42007-12-04 22:23:35 +0000333 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
334 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000335
Scott Michel8efdca42007-12-04 22:23:35 +0000336 // Use the default implementation.
337 setOperationAction(ISD::VAARG , MVT::Other, Expand);
338 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
339 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michel4ec722e2008-07-16 17:17:29 +0000340 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000341 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
342 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
343 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
344
345 // Cell SPU has instructions for converting between i64 and fp.
346 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
347 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michel4ec722e2008-07-16 17:17:29 +0000348
Scott Michel8efdca42007-12-04 22:23:35 +0000349 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
350 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
351
352 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
353 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
354
355 // First set operation action for all vector types to expand. Then we
356 // will selectively turn on ones that can be effectively codegen'd.
357 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
358 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
359 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
360 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
361 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
362 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
363
Scott Michel70741542009-01-06 23:10:38 +0000364 // "Odd size" vector classes that we're willing to support:
365 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
366
Duncan Sands92c43912008-06-06 12:08:01 +0000367 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
368 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
369 MVT VT = (MVT::SimpleValueType)i;
Scott Michel8efdca42007-12-04 22:23:35 +0000370
Duncan Sands92c43912008-06-06 12:08:01 +0000371 // add/sub are legal for all supported vector VT's.
pingbak2f387e82009-01-26 03:31:40 +0000372 setOperationAction(ISD::ADD, VT, Legal);
373 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000374 // mul has to be custom lowered.
pingbak2f387e82009-01-26 03:31:40 +0000375 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands92c43912008-06-06 12:08:01 +0000376
pingbak2f387e82009-01-26 03:31:40 +0000377 setOperationAction(ISD::AND, VT, Legal);
378 setOperationAction(ISD::OR, VT, Legal);
379 setOperationAction(ISD::XOR, VT, Legal);
380 setOperationAction(ISD::LOAD, VT, Legal);
381 setOperationAction(ISD::SELECT, VT, Legal);
382 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel4ec722e2008-07-16 17:17:29 +0000383
Scott Michel8efdca42007-12-04 22:23:35 +0000384 // These operations need to be expanded:
pingbak2f387e82009-01-26 03:31:40 +0000385 setOperationAction(ISD::SDIV, VT, Expand);
386 setOperationAction(ISD::SREM, VT, Expand);
387 setOperationAction(ISD::UDIV, VT, Expand);
388 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel8efdca42007-12-04 22:23:35 +0000389
390 // Custom lower build_vector, constant pool spills, insert and
391 // extract vector elements:
Duncan Sands92c43912008-06-06 12:08:01 +0000392 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
393 setOperationAction(ISD::ConstantPool, VT, Custom);
394 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
395 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
396 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
397 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel8efdca42007-12-04 22:23:35 +0000398 }
399
Scott Michel8efdca42007-12-04 22:23:35 +0000400 setOperationAction(ISD::AND, MVT::v16i8, Custom);
401 setOperationAction(ISD::OR, MVT::v16i8, Custom);
402 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
403 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000404
Scott Michel4d07fb72008-12-30 23:28:25 +0000405 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michelae5cbf52008-12-29 03:23:36 +0000406
Scott Michel8efdca42007-12-04 22:23:35 +0000407 setShiftAmountType(MVT::i32);
Scott Michel06eabde2008-12-27 04:51:36 +0000408 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel4ec722e2008-07-16 17:17:29 +0000409
Scott Michel8efdca42007-12-04 22:23:35 +0000410 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel4ec722e2008-07-16 17:17:29 +0000411
Scott Michel8efdca42007-12-04 22:23:35 +0000412 // We have target-specific dag combine patterns for the following nodes:
Scott Michelf9f42e62008-01-29 02:16:57 +0000413 setTargetDAGCombine(ISD::ADD);
Scott Michel97872d32008-02-23 18:41:37 +0000414 setTargetDAGCombine(ISD::ZERO_EXTEND);
415 setTargetDAGCombine(ISD::SIGN_EXTEND);
416 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel4ec722e2008-07-16 17:17:29 +0000417
Scott Michel8efdca42007-12-04 22:23:35 +0000418 computeRegisterProperties();
Scott Michel56a125e2008-11-22 23:50:42 +0000419
Scott Michel2c261072008-12-09 03:37:19 +0000420 // Set pre-RA register scheduler default to BURR, which produces slightly
421 // better code than the default (could also be TDRR, but TargetLowering.h
422 // needs a mod to support that model):
423 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel8efdca42007-12-04 22:23:35 +0000424}
425
426const char *
427SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
428{
429 if (node_names.empty()) {
430 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
431 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
432 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
433 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Micheldbac4cf2008-01-11 02:53:15 +0000434 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michelf9f42e62008-01-29 02:16:57 +0000435 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel8efdca42007-12-04 22:23:35 +0000436 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
437 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
438 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel56a125e2008-11-22 23:50:42 +0000439 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000440 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michelae5cbf52008-12-29 03:23:36 +0000441 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michelc630c412008-11-24 17:11:17 +0000442 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michel97872d32008-02-23 18:41:37 +0000443 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
444 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel8efdca42007-12-04 22:23:35 +0000445 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
446 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
447 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
448 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
449 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Michel8c67fa42009-01-21 04:58:48 +0000450 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
451 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
452 "SPUISD::ROTBYTES_LEFT_BITS";
Scott Michel67224b22008-06-02 22:18:03 +0000453 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel8efdca42007-12-04 22:23:35 +0000454 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel750b93f2009-01-15 04:41:47 +0000455 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
456 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
457 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel8efdca42007-12-04 22:23:35 +0000458 }
459
460 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
461
462 return ((i != node_names.end()) ? i->second : 0);
463}
464
Scott Michel06eabde2008-12-27 04:51:36 +0000465//===----------------------------------------------------------------------===//
466// Return the Cell SPU's SETCC result type
467//===----------------------------------------------------------------------===//
468
Duncan Sands4a361272009-01-01 15:52:00 +0000469MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michel06eabde2008-12-27 04:51:36 +0000470 // i16 and i32 are valid SETCC result types
471 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel53ab7792008-03-10 16:58:52 +0000472}
473
Scott Michel8efdca42007-12-04 22:23:35 +0000474//===----------------------------------------------------------------------===//
475// Calling convention code:
476//===----------------------------------------------------------------------===//
477
478#include "SPUGenCallingConv.inc"
479
480//===----------------------------------------------------------------------===//
481// LowerOperation implementation
482//===----------------------------------------------------------------------===//
483
484/// Custom lower loads for CellSPU
485/*!
486 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
487 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel6ccefab2008-12-04 03:02:42 +0000488
489 For extending loads, we also want to ensure that the following sequence is
490 emitted, e.g. for MVT::f32 extending load to MVT::f64:
491
492\verbatim
Scott Michelae5cbf52008-12-29 03:23:36 +0000493%1 v16i8,ch = load
Scott Michel6ccefab2008-12-04 03:02:42 +0000494%2 v16i8,ch = rotate %1
Scott Michelae5cbf52008-12-29 03:23:36 +0000495%3 v4f8, ch = bitconvert %2
Scott Michel6ccefab2008-12-04 03:02:42 +0000496%4 f32 = vec2perfslot %3
497%5 f64 = fp_extend %4
498\endverbatim
499*/
Dan Gohman8181bd12008-07-27 21:46:04 +0000500static SDValue
501LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000502 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000503 SDValue the_chain = LN->getChain();
Scott Michel06eabde2008-12-27 04:51:36 +0000504 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel6ccefab2008-12-04 03:02:42 +0000505 MVT InVT = LN->getMemoryVT();
506 MVT OutVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000507 ISD::LoadExtType ExtType = LN->getExtensionType();
508 unsigned alignment = LN->getAlignment();
Scott Michel06eabde2008-12-27 04:51:36 +0000509 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000510
Scott Michel8efdca42007-12-04 22:23:35 +0000511 switch (LN->getAddressingMode()) {
512 case ISD::UNINDEXED: {
Scott Michel06eabde2008-12-27 04:51:36 +0000513 SDValue result;
514 SDValue basePtr = LN->getBasePtr();
515 SDValue rotate;
Scott Michel8efdca42007-12-04 22:23:35 +0000516
Scott Michel06eabde2008-12-27 04:51:36 +0000517 if (alignment == 16) {
518 ConstantSDNode *CN;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000519
Scott Michel06eabde2008-12-27 04:51:36 +0000520 // Special cases for a known aligned load to simplify the base pointer
521 // and the rotation amount:
522 if (basePtr.getOpcode() == ISD::ADD
523 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
524 // Known offset into basePtr
525 int64_t offset = CN->getSExtValue();
526 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000527
Scott Michel06eabde2008-12-27 04:51:36 +0000528 if (rotamt < 0)
529 rotamt += 16;
530
531 rotate = DAG.getConstant(rotamt, MVT::i16);
532
533 // Simplify the base pointer for this case:
534 basePtr = basePtr.getOperand(0);
535 if ((offset & ~0xf) > 0) {
536 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
537 basePtr,
538 DAG.getConstant((offset & ~0xf), PtrVT));
539 }
540 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
541 || (basePtr.getOpcode() == SPUISD::IndirectAddr
542 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
543 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
544 // Plain aligned a-form address: rotate into preferred slot
545 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
546 int64_t rotamt = -vtm->prefslot_byte;
547 if (rotamt < 0)
548 rotamt += 16;
549 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000550 } else {
Scott Michel06eabde2008-12-27 04:51:36 +0000551 // Offset the rotate amount by the basePtr and the preferred slot
552 // byte offset
553 int64_t rotamt = -vtm->prefslot_byte;
554 if (rotamt < 0)
555 rotamt += 16;
556 rotate = DAG.getNode(ISD::ADD, PtrVT,
557 basePtr,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000558 DAG.getConstant(rotamt, PtrVT));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000559 }
Scott Michel06eabde2008-12-27 04:51:36 +0000560 } else {
561 // Unaligned load: must be more pessimistic about addressing modes:
562 if (basePtr.getOpcode() == ISD::ADD) {
563 MachineFunction &MF = DAG.getMachineFunction();
564 MachineRegisterInfo &RegInfo = MF.getRegInfo();
565 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
566 SDValue Flag;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000567
Scott Michel06eabde2008-12-27 04:51:36 +0000568 SDValue Op0 = basePtr.getOperand(0);
569 SDValue Op1 = basePtr.getOperand(1);
570
571 if (isa<ConstantSDNode>(Op1)) {
572 // Convert the (add <ptr>, <const>) to an indirect address contained
573 // in a register. Note that this is done because we need to avoid
574 // creating a 0(reg) d-form address due to the SPU's block loads.
575 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
576 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
577 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
578 } else {
579 // Convert the (add <arg1>, <arg2>) to an indirect address, which
580 // will likely be lowered as a reg(reg) x-form address.
581 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
582 }
583 } else {
584 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
585 basePtr,
586 DAG.getConstant(0, PtrVT));
587 }
588
589 // Offset the rotate amount by the basePtr and the preferred slot
590 // byte offset
591 rotate = DAG.getNode(ISD::ADD, PtrVT,
592 basePtr,
593 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +0000594 }
Scott Micheldbac4cf2008-01-11 02:53:15 +0000595
Scott Michel06eabde2008-12-27 04:51:36 +0000596 // Re-emit as a v16i8 vector load
597 result = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
598 LN->getSrcValue(), LN->getSrcValueOffset(),
599 LN->isVolatile(), 16);
600
601 // Update the chain
602 the_chain = result.getValue(1);
603
604 // Rotate into the preferred slot:
605 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8,
606 result.getValue(0), rotate);
607
Scott Michel6ccefab2008-12-04 03:02:42 +0000608 // Convert the loaded v16i8 vector to the appropriate vector type
609 // specified by the operand:
610 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
611 result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
pingbakb8913342009-01-26 03:37:41 +0000612 DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
Scott Michel4ec722e2008-07-16 17:17:29 +0000613
Scott Michel6ccefab2008-12-04 03:02:42 +0000614 // Handle extending loads by extending the scalar result:
615 if (ExtType == ISD::SEXTLOAD) {
616 result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result);
617 } else if (ExtType == ISD::ZEXTLOAD) {
618 result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result);
619 } else if (ExtType == ISD::EXTLOAD) {
620 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000621
Scott Michel6ccefab2008-12-04 03:02:42 +0000622 if (OutVT.isFloatingPoint())
pingbakb8913342009-01-26 03:37:41 +0000623 NewOpc = ISD::FP_EXTEND;
Scott Micheldbac4cf2008-01-11 02:53:15 +0000624
Scott Michel6ccefab2008-12-04 03:02:42 +0000625 result = DAG.getNode(NewOpc, OutVT, result);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000626 }
627
Scott Michel6ccefab2008-12-04 03:02:42 +0000628 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman8181bd12008-07-27 21:46:04 +0000629 SDValue retops[2] = {
Scott Michel394e26d2008-01-17 20:38:41 +0000630 result,
Scott Michel5a6f17b2008-01-30 02:55:46 +0000631 the_chain
Scott Michel394e26d2008-01-17 20:38:41 +0000632 };
Scott Micheldbac4cf2008-01-11 02:53:15 +0000633
Scott Michel394e26d2008-01-17 20:38:41 +0000634 result = DAG.getNode(SPUISD::LDRESULT, retvts,
635 retops, sizeof(retops) / sizeof(retops[0]));
Scott Micheldbac4cf2008-01-11 02:53:15 +0000636 return result;
Scott Michel8efdca42007-12-04 22:23:35 +0000637 }
638 case ISD::PRE_INC:
639 case ISD::PRE_DEC:
640 case ISD::POST_INC:
641 case ISD::POST_DEC:
642 case ISD::LAST_INDEXED_MODE:
643 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
644 "UNINDEXED\n";
645 cerr << (unsigned) LN->getAddressingMode() << "\n";
646 abort();
647 /*NOTREACHED*/
648 }
649
Dan Gohman8181bd12008-07-27 21:46:04 +0000650 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000651}
652
653/// Custom lower stores for CellSPU
654/*!
655 All CellSPU stores are aligned to 16-byte boundaries, so for elements
656 within a 16-byte block, we have to generate a shuffle to insert the
657 requested element into its place, then store the resulting block.
658 */
Dan Gohman8181bd12008-07-27 21:46:04 +0000659static SDValue
660LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel8efdca42007-12-04 22:23:35 +0000661 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000662 SDValue Value = SN->getValue();
Duncan Sands92c43912008-06-06 12:08:01 +0000663 MVT VT = Value.getValueType();
664 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
665 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Micheldbac4cf2008-01-11 02:53:15 +0000666 unsigned alignment = SN->getAlignment();
Scott Michel8efdca42007-12-04 22:23:35 +0000667
668 switch (SN->getAddressingMode()) {
669 case ISD::UNINDEXED: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000670 // The vector type we really want to load from the 16-byte chunk.
Scott Michele1006032008-11-19 17:45:08 +0000671 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
672 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +0000673
Scott Michel06eabde2008-12-27 04:51:36 +0000674 SDValue alignLoadVec;
675 SDValue basePtr = SN->getBasePtr();
676 SDValue the_chain = SN->getChain();
677 SDValue insertEltOffs;
Scott Michel8efdca42007-12-04 22:23:35 +0000678
Scott Michel06eabde2008-12-27 04:51:36 +0000679 if (alignment == 16) {
680 ConstantSDNode *CN;
681
682 // Special cases for a known aligned load to simplify the base pointer
683 // and insertion byte:
684 if (basePtr.getOpcode() == ISD::ADD
685 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
686 // Known offset into basePtr
687 int64_t offset = CN->getSExtValue();
688
689 // Simplify the base pointer for this case:
690 basePtr = basePtr.getOperand(0);
691 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
692 basePtr,
693 DAG.getConstant((offset & 0xf), PtrVT));
694
695 if ((offset & ~0xf) > 0) {
696 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
697 basePtr,
698 DAG.getConstant((offset & ~0xf), PtrVT));
699 }
700 } else {
701 // Otherwise, assume it's at byte 0 of basePtr
702 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
703 basePtr,
704 DAG.getConstant(0, PtrVT));
705 }
706 } else {
707 // Unaligned load: must be more pessimistic about addressing modes:
708 if (basePtr.getOpcode() == ISD::ADD) {
709 MachineFunction &MF = DAG.getMachineFunction();
710 MachineRegisterInfo &RegInfo = MF.getRegInfo();
711 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
712 SDValue Flag;
713
714 SDValue Op0 = basePtr.getOperand(0);
715 SDValue Op1 = basePtr.getOperand(1);
716
717 if (isa<ConstantSDNode>(Op1)) {
718 // Convert the (add <ptr>, <const>) to an indirect address contained
719 // in a register. Note that this is done because we need to avoid
720 // creating a 0(reg) d-form address due to the SPU's block loads.
721 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
722 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
723 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
724 } else {
725 // Convert the (add <arg1>, <arg2>) to an indirect address, which
726 // will likely be lowered as a reg(reg) x-form address.
727 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
728 }
729 } else {
730 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
731 basePtr,
732 DAG.getConstant(0, PtrVT));
733 }
734
735 // Insertion point is solely determined by basePtr's contents
736 insertEltOffs = DAG.getNode(ISD::ADD, PtrVT,
737 basePtr,
738 DAG.getConstant(0, PtrVT));
739 }
740
741 // Re-emit as a v16i8 vector load
742 alignLoadVec = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
743 SN->getSrcValue(), SN->getSrcValueOffset(),
744 SN->isVolatile(), 16);
745
746 // Update the chain
747 the_chain = alignLoadVec.getValue(1);
Scott Michel8efdca42007-12-04 22:23:35 +0000748
Scott Micheldbac4cf2008-01-11 02:53:15 +0000749 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman8181bd12008-07-27 21:46:04 +0000750 SDValue theValue = SN->getValue();
751 SDValue result;
Scott Michel8efdca42007-12-04 22:23:35 +0000752
753 if (StVT != VT
Scott Michel5a6f17b2008-01-30 02:55:46 +0000754 && (theValue.getOpcode() == ISD::AssertZext
755 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel8efdca42007-12-04 22:23:35 +0000756 // Drill down and get the value for zero- and sign-extended
757 // quantities
Scott Michel4ec722e2008-07-16 17:17:29 +0000758 theValue = theValue.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +0000759 }
760
Scott Micheldbac4cf2008-01-11 02:53:15 +0000761 // If the base pointer is already a D-form address, then just create
762 // a new D-form address with a slot offset and the orignal base pointer.
763 // Otherwise generate a D-form address with the slot offset relative
764 // to the stack pointer, which is always aligned.
Scott Michel06eabde2008-12-27 04:51:36 +0000765#if !defined(NDEBUG)
766 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
767 cerr << "CellSPU LowerSTORE: basePtr = ";
768 basePtr.getNode()->dump(&DAG);
769 cerr << "\n";
770 }
771#endif
Scott Micheldbac4cf2008-01-11 02:53:15 +0000772
Scott Michelf65c8f02008-11-19 15:24:16 +0000773 SDValue insertEltOp =
Scott Michel06eabde2008-12-27 04:51:36 +0000774 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michele1006032008-11-19 17:45:08 +0000775 SDValue vectorizeOp =
776 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michelf65c8f02008-11-19 15:24:16 +0000777
Scott Michel0718cd82008-12-01 17:56:02 +0000778 result = DAG.getNode(SPUISD::SHUFB, vecVT,
pingbakb8913342009-01-26 03:37:41 +0000779 vectorizeOp, alignLoadVec,
780 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
Scott Michel8efdca42007-12-04 22:23:35 +0000781
Scott Micheldbac4cf2008-01-11 02:53:15 +0000782 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel8efdca42007-12-04 22:23:35 +0000783 LN->getSrcValue(), LN->getSrcValueOffset(),
784 LN->isVolatile(), LN->getAlignment());
785
Scott Michel8c2746e2008-12-04 17:16:59 +0000786#if 0 && !defined(NDEBUG)
Scott Michelf65c8f02008-11-19 15:24:16 +0000787 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
788 const SDValue &currentRoot = DAG.getRoot();
789
790 DAG.setRoot(result);
791 cerr << "------- CellSPU:LowerStore result:\n";
792 DAG.dump();
793 cerr << "-------\n";
794 DAG.setRoot(currentRoot);
795 }
796#endif
Scott Michelec8c82e2008-12-02 19:53:53 +0000797
Scott Michel8efdca42007-12-04 22:23:35 +0000798 return result;
799 /*UNREACHED*/
800 }
801 case ISD::PRE_INC:
802 case ISD::PRE_DEC:
803 case ISD::POST_INC:
804 case ISD::POST_DEC:
805 case ISD::LAST_INDEXED_MODE:
806 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
807 "UNINDEXED\n";
808 cerr << (unsigned) SN->getAddressingMode() << "\n";
809 abort();
810 /*NOTREACHED*/
811 }
812
Dan Gohman8181bd12008-07-27 21:46:04 +0000813 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000814}
815
Scott Michel750b93f2009-01-15 04:41:47 +0000816//! Generate the address of a constant pool entry.
817SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000818LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000819 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000820 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
821 Constant *C = CP->getConstVal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000822 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
823 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Micheldbac4cf2008-01-11 02:53:15 +0000824 const TargetMachine &TM = DAG.getTarget();
Scott Michel8efdca42007-12-04 22:23:35 +0000825
826 if (TM.getRelocationModel() == Reloc::Static) {
827 if (!ST->usingLargeMem()) {
Dan Gohman8181bd12008-07-27 21:46:04 +0000828 // Just return the SDValue with the constant pool address in it.
Scott Michel394e26d2008-01-17 20:38:41 +0000829 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +0000830 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000831 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
832 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000833 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel8efdca42007-12-04 22:23:35 +0000834 }
835 }
836
837 assert(0 &&
Gabor Greife9f7f582008-08-31 15:37:04 +0000838 "LowerConstantPool: Relocation model other than static"
839 " not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000840 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000841}
842
Scott Michel750b93f2009-01-15 04:41:47 +0000843//! Alternate entry point for generating the address of a constant pool entry
844SDValue
845SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
846 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
847}
848
Dan Gohman8181bd12008-07-27 21:46:04 +0000849static SDValue
850LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000851 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000852 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman8181bd12008-07-27 21:46:04 +0000853 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
854 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel8efdca42007-12-04 22:23:35 +0000855 const TargetMachine &TM = DAG.getTarget();
856
857 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel97872d32008-02-23 18:41:37 +0000858 if (!ST->usingLargeMem()) {
859 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
860 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000861 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
862 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
Scott Michel97872d32008-02-23 18:41:37 +0000863 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
864 }
Scott Michel8efdca42007-12-04 22:23:35 +0000865 }
866
867 assert(0 &&
868 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman8181bd12008-07-27 21:46:04 +0000869 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000870}
871
Dan Gohman8181bd12008-07-27 21:46:04 +0000872static SDValue
873LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands92c43912008-06-06 12:08:01 +0000874 MVT PtrVT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000875 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
876 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman8181bd12008-07-27 21:46:04 +0000877 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel8efdca42007-12-04 22:23:35 +0000878 const TargetMachine &TM = DAG.getTarget();
Dan Gohman8181bd12008-07-27 21:46:04 +0000879 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel4ec722e2008-07-16 17:17:29 +0000880
Scott Michel8efdca42007-12-04 22:23:35 +0000881 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michelf9f42e62008-01-29 02:16:57 +0000882 if (!ST->usingLargeMem()) {
883 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
884 } else {
Dan Gohman8181bd12008-07-27 21:46:04 +0000885 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
886 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
Scott Michelf9f42e62008-01-29 02:16:57 +0000887 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
888 }
Scott Michel8efdca42007-12-04 22:23:35 +0000889 } else {
890 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel5a6f17b2008-01-30 02:55:46 +0000891 << "supported.\n";
Scott Michel8efdca42007-12-04 22:23:35 +0000892 abort();
893 /*NOTREACHED*/
894 }
895
Dan Gohman8181bd12008-07-27 21:46:04 +0000896 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000897}
898
Nate Begeman78125042008-02-14 18:43:04 +0000899//! Custom lower double precision floating point constants
Dan Gohman8181bd12008-07-27 21:46:04 +0000900static SDValue
901LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +0000902 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +0000903
Nate Begeman78125042008-02-14 18:43:04 +0000904 if (VT == MVT::f64) {
Scott Michel0718cd82008-12-01 17:56:02 +0000905 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
906
907 assert((FP != 0) &&
908 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michelae5cbf52008-12-29 03:23:36 +0000909
Scott Michel11e88bb2007-12-19 20:15:47 +0000910 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel0718cd82008-12-01 17:56:02 +0000911 SDValue T = DAG.getConstant(dbits, MVT::i64);
912 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T);
913 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
914 DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec));
Scott Michel8efdca42007-12-04 22:23:35 +0000915 }
916
Dan Gohman8181bd12008-07-27 21:46:04 +0000917 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +0000918}
919
Dan Gohman8181bd12008-07-27 21:46:04 +0000920static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +0000921LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel8efdca42007-12-04 22:23:35 +0000922{
923 MachineFunction &MF = DAG.getMachineFunction();
924 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner1b989192007-12-31 04:13:23 +0000925 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michela313fb02008-10-30 01:51:48 +0000926 SmallVector<SDValue, 48> ArgValues;
Dan Gohman8181bd12008-07-27 21:46:04 +0000927 SDValue Root = Op.getOperand(0);
Dan Gohmanfaeb4a32008-09-12 16:56:44 +0000928 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel8efdca42007-12-04 22:23:35 +0000929
930 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
931 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel4ec722e2008-07-16 17:17:29 +0000932
Scott Michel8efdca42007-12-04 22:23:35 +0000933 unsigned ArgOffset = SPUFrameInfo::minStackSize();
934 unsigned ArgRegIdx = 0;
935 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel4ec722e2008-07-16 17:17:29 +0000936
Duncan Sands92c43912008-06-06 12:08:01 +0000937 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +0000938
Scott Michel8efdca42007-12-04 22:23:35 +0000939 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greife9f7f582008-08-31 15:37:04 +0000940 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
941 ArgNo != e; ++ArgNo) {
Duncan Sands92c43912008-06-06 12:08:01 +0000942 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
943 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Michela313fb02008-10-30 01:51:48 +0000944 SDValue ArgVal;
Scott Michel8efdca42007-12-04 22:23:35 +0000945
Scott Michela313fb02008-10-30 01:51:48 +0000946 if (ArgRegIdx < NumArgRegs) {
947 const TargetRegisterClass *ArgRegClass;
Scott Michel4ec722e2008-07-16 17:17:29 +0000948
Scott Michela313fb02008-10-30 01:51:48 +0000949 switch (ObjectVT.getSimpleVT()) {
950 default: {
Scott Michel33d73eb2008-11-21 02:56:16 +0000951 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
952 << ObjectVT.getMVTString()
953 << "\n";
954 abort();
Scott Michela313fb02008-10-30 01:51:48 +0000955 }
956 case MVT::i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000957 ArgRegClass = &SPU::R8CRegClass;
958 break;
Scott Michela313fb02008-10-30 01:51:48 +0000959 case MVT::i16:
Scott Michel33d73eb2008-11-21 02:56:16 +0000960 ArgRegClass = &SPU::R16CRegClass;
961 break;
Scott Michela313fb02008-10-30 01:51:48 +0000962 case MVT::i32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000963 ArgRegClass = &SPU::R32CRegClass;
964 break;
Scott Michela313fb02008-10-30 01:51:48 +0000965 case MVT::i64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000966 ArgRegClass = &SPU::R64CRegClass;
967 break;
Scott Michel2ef773a2009-01-06 03:36:14 +0000968 case MVT::i128:
969 ArgRegClass = &SPU::GPRCRegClass;
970 break;
Scott Michela313fb02008-10-30 01:51:48 +0000971 case MVT::f32:
Scott Michel33d73eb2008-11-21 02:56:16 +0000972 ArgRegClass = &SPU::R32FPRegClass;
973 break;
Scott Michela313fb02008-10-30 01:51:48 +0000974 case MVT::f64:
Scott Michel33d73eb2008-11-21 02:56:16 +0000975 ArgRegClass = &SPU::R64FPRegClass;
976 break;
Scott Michela313fb02008-10-30 01:51:48 +0000977 case MVT::v2f64:
978 case MVT::v4f32:
979 case MVT::v2i64:
980 case MVT::v4i32:
981 case MVT::v8i16:
982 case MVT::v16i8:
Scott Michel33d73eb2008-11-21 02:56:16 +0000983 ArgRegClass = &SPU::VECREGRegClass;
984 break;
Scott Michela313fb02008-10-30 01:51:48 +0000985 }
986
987 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
988 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
989 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
990 ++ArgRegIdx;
991 } else {
992 // We need to load the argument to a virtual register if we determined
993 // above that we ran out of physical registers of the appropriate type
994 // or we're forced to do vararg
Chris Lattner60069452008-02-13 07:35:30 +0000995 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman8181bd12008-07-27 21:46:04 +0000996 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner60069452008-02-13 07:35:30 +0000997 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel8efdca42007-12-04 22:23:35 +0000998 ArgOffset += StackSlotSize;
999 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001000
Scott Michel8efdca42007-12-04 22:23:35 +00001001 ArgValues.push_back(ArgVal);
Scott Michela313fb02008-10-30 01:51:48 +00001002 // Update the chain
1003 Root = ArgVal.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001004 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001005
Scott Michela313fb02008-10-30 01:51:48 +00001006 // vararg handling:
Scott Michel8efdca42007-12-04 22:23:35 +00001007 if (isVarArg) {
Scott Michela313fb02008-10-30 01:51:48 +00001008 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
1009 // We will spill (79-3)+1 registers to the stack
1010 SmallVector<SDValue, 79-3+1> MemOps;
1011
1012 // Create the frame slot
1013
Scott Michel8efdca42007-12-04 22:23:35 +00001014 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Michela313fb02008-10-30 01:51:48 +00001015 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1016 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1017 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
1018 SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
1019 Root = Store.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00001020 MemOps.push_back(Store);
Scott Michela313fb02008-10-30 01:51:48 +00001021
1022 // Increment address by stack slot size for the next stored argument
1023 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001024 }
1025 if (!MemOps.empty())
Scott Michela313fb02008-10-30 01:51:48 +00001026 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001027 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001028
Scott Michel8efdca42007-12-04 22:23:35 +00001029 ArgValues.push_back(Root);
Scott Michel4ec722e2008-07-16 17:17:29 +00001030
Scott Michel8efdca42007-12-04 22:23:35 +00001031 // Return the new list of results.
Duncan Sands42d7bb82008-12-01 11:41:29 +00001032 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1033 &ArgValues[0], ArgValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001034}
1035
1036/// isLSAAddress - Return the immediate to use if the specified
1037/// value is representable as a LSA address.
Dan Gohman8181bd12008-07-27 21:46:04 +00001038static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel5974f432008-11-11 03:06:06 +00001039 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel8efdca42007-12-04 22:23:35 +00001040 if (!C) return 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001041
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001042 int Addr = C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001043 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1044 (Addr << 14 >> 14) != Addr)
1045 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel4ec722e2008-07-16 17:17:29 +00001046
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001047 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel8efdca42007-12-04 22:23:35 +00001048}
1049
Scott Michel70741542009-01-06 23:10:38 +00001050static SDValue
Dan Gohman8181bd12008-07-27 21:46:04 +00001051LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001052 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1053 SDValue Chain = TheCall->getChain();
Dan Gohman705e3f72008-09-13 01:54:27 +00001054 SDValue Callee = TheCall->getCallee();
1055 unsigned NumOps = TheCall->getNumArgs();
Scott Michel8efdca42007-12-04 22:23:35 +00001056 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1057 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1058 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1059
1060 // Handy pointer type
Duncan Sands92c43912008-06-06 12:08:01 +00001061 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel4ec722e2008-07-16 17:17:29 +00001062
Scott Michel8efdca42007-12-04 22:23:35 +00001063 // Accumulate how many bytes are to be pushed on the stack, including the
1064 // linkage area, and parameter passing area. According to the SPU ABI,
1065 // we minimally need space for [LR] and [SP]
1066 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel4ec722e2008-07-16 17:17:29 +00001067
Scott Michel8efdca42007-12-04 22:23:35 +00001068 // Set up a copy of the stack pointer for use loading and storing any
1069 // arguments that may not fit in the registers available for argument
1070 // passing.
Dan Gohman8181bd12008-07-27 21:46:04 +00001071 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel4ec722e2008-07-16 17:17:29 +00001072
Scott Michel8efdca42007-12-04 22:23:35 +00001073 // Figure out which arguments are going to go in registers, and which in
1074 // memory.
1075 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1076 unsigned ArgRegIdx = 0;
1077
1078 // Keep track of registers passing arguments
Dan Gohman8181bd12008-07-27 21:46:04 +00001079 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel8efdca42007-12-04 22:23:35 +00001080 // And the arguments passed on the stack
Dan Gohman8181bd12008-07-27 21:46:04 +00001081 SmallVector<SDValue, 8> MemOpChains;
Scott Michel8efdca42007-12-04 22:23:35 +00001082
1083 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman705e3f72008-09-13 01:54:27 +00001084 SDValue Arg = TheCall->getArg(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001085
Scott Michel8efdca42007-12-04 22:23:35 +00001086 // PtrOff will be used to store the current argument to the stack if a
1087 // register cannot be found for it.
Dan Gohman8181bd12008-07-27 21:46:04 +00001088 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel8efdca42007-12-04 22:23:35 +00001089 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1090
Duncan Sands92c43912008-06-06 12:08:01 +00001091 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001092 default: assert(0 && "Unexpected ValueType for argument!");
Scott Michel2ef773a2009-01-06 03:36:14 +00001093 case MVT::i8:
1094 case MVT::i16:
Scott Michel8efdca42007-12-04 22:23:35 +00001095 case MVT::i32:
1096 case MVT::i64:
1097 case MVT::i128:
1098 if (ArgRegIdx != NumArgRegs) {
1099 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1100 } else {
1101 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001102 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001103 }
1104 break;
1105 case MVT::f32:
1106 case MVT::f64:
1107 if (ArgRegIdx != NumArgRegs) {
1108 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1109 } else {
1110 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001111 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001112 }
1113 break;
Scott Michele2641a12008-12-04 21:01:44 +00001114 case MVT::v2i64:
1115 case MVT::v2f64:
Scott Michel8efdca42007-12-04 22:23:35 +00001116 case MVT::v4f32:
1117 case MVT::v4i32:
1118 case MVT::v8i16:
1119 case MVT::v16i8:
1120 if (ArgRegIdx != NumArgRegs) {
1121 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1122 } else {
1123 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel5a6f17b2008-01-30 02:55:46 +00001124 ArgOffset += StackSlotSize;
Scott Michel8efdca42007-12-04 22:23:35 +00001125 }
1126 break;
1127 }
1128 }
1129
1130 // Update number of stack bytes actually used, insert a call sequence start
1131 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001132 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1133 true));
Scott Michel8efdca42007-12-04 22:23:35 +00001134
1135 if (!MemOpChains.empty()) {
1136 // Adjust the stack pointer for the stack arguments.
1137 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1138 &MemOpChains[0], MemOpChains.size());
1139 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001140
Scott Michel8efdca42007-12-04 22:23:35 +00001141 // Build a sequence of copy-to-reg nodes chained together with token chain
1142 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman8181bd12008-07-27 21:46:04 +00001143 SDValue InFlag;
Scott Michel8efdca42007-12-04 22:23:35 +00001144 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1145 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1146 InFlag);
1147 InFlag = Chain.getValue(1);
1148 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001149
Dan Gohman8181bd12008-07-27 21:46:04 +00001150 SmallVector<SDValue, 8> Ops;
Scott Michel8efdca42007-12-04 22:23:35 +00001151 unsigned CallOpc = SPUISD::CALL;
Scott Michel4ec722e2008-07-16 17:17:29 +00001152
Bill Wendlingfef06052008-09-16 21:48:12 +00001153 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1154 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1155 // node so that legalize doesn't hack it.
Scott Michel5974f432008-11-11 03:06:06 +00001156 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001157 GlobalValue *GV = G->getGlobal();
Duncan Sands92c43912008-06-06 12:08:01 +00001158 MVT CalleeVT = Callee.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001159 SDValue Zero = DAG.getConstant(0, PtrVT);
1160 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel8efdca42007-12-04 22:23:35 +00001161
Scott Micheldbac4cf2008-01-11 02:53:15 +00001162 if (!ST->usingLargeMem()) {
1163 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1164 // style calls, otherwise, external symbols are BRASL calls. This assumes
1165 // that declared/defined symbols are in the same compilation unit and can
1166 // be reached through PC-relative jumps.
1167 //
1168 // NOTE:
1169 // This may be an unsafe assumption for JIT and really large compilation
1170 // units.
1171 if (GV->isDeclaration()) {
1172 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1173 } else {
1174 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1175 }
Scott Michel8efdca42007-12-04 22:23:35 +00001176 } else {
Scott Micheldbac4cf2008-01-11 02:53:15 +00001177 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1178 // address pairs:
Scott Michelf9f42e62008-01-29 02:16:57 +00001179 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel8efdca42007-12-04 22:23:35 +00001180 }
Scott Michelae5cbf52008-12-29 03:23:36 +00001181 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1182 MVT CalleeVT = Callee.getValueType();
1183 SDValue Zero = DAG.getConstant(0, PtrVT);
1184 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1185 Callee.getValueType());
1186
1187 if (!ST->usingLargeMem()) {
1188 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, ExtSym, Zero);
1189 } else {
1190 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, ExtSym, Zero);
1191 }
1192 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001193 // If this is an absolute destination address that appears to be a legal
1194 // local store address, use the munged value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001195 Callee = SDValue(Dest, 0);
Scott Micheldbac4cf2008-01-11 02:53:15 +00001196 }
Scott Michel8efdca42007-12-04 22:23:35 +00001197
1198 Ops.push_back(Chain);
1199 Ops.push_back(Callee);
Scott Michel4ec722e2008-07-16 17:17:29 +00001200
Scott Michel8efdca42007-12-04 22:23:35 +00001201 // Add argument registers to the end of the list so that they are known live
1202 // into the call.
1203 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel4ec722e2008-07-16 17:17:29 +00001204 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel8efdca42007-12-04 22:23:35 +00001205 RegsToPass[i].second.getValueType()));
Scott Michel4ec722e2008-07-16 17:17:29 +00001206
Gabor Greif1c80d112008-08-28 21:40:38 +00001207 if (InFlag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001208 Ops.push_back(InFlag);
Duncan Sands698842f2008-07-02 17:40:58 +00001209 // Returns a chain and a flag for retval copy to use.
1210 Chain = DAG.getNode(CallOpc, DAG.getVTList(MVT::Other, MVT::Flag),
1211 &Ops[0], Ops.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001212 InFlag = Chain.getValue(1);
1213
Chris Lattnerfe5d4022008-10-11 22:08:30 +00001214 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1215 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman705e3f72008-09-13 01:54:27 +00001216 if (TheCall->getValueType(0) != MVT::Other)
Evan Cheng07322bb2008-02-05 22:44:06 +00001217 InFlag = Chain.getValue(1);
1218
Dan Gohman8181bd12008-07-27 21:46:04 +00001219 SDValue ResultVals[3];
Scott Michel8efdca42007-12-04 22:23:35 +00001220 unsigned NumResults = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001221
Scott Michel8efdca42007-12-04 22:23:35 +00001222 // If the call has results, copy the values out of the ret val registers.
Dan Gohman705e3f72008-09-13 01:54:27 +00001223 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001224 default: assert(0 && "Unexpected ret value!");
1225 case MVT::Other: break;
1226 case MVT::i32:
Dan Gohman705e3f72008-09-13 01:54:27 +00001227 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001228 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1229 ResultVals[0] = Chain.getValue(0);
1230 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1231 Chain.getValue(2)).getValue(1);
1232 ResultVals[1] = Chain.getValue(0);
1233 NumResults = 2;
Scott Michel8efdca42007-12-04 22:23:35 +00001234 } else {
1235 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1236 ResultVals[0] = Chain.getValue(0);
1237 NumResults = 1;
1238 }
Scott Michel8efdca42007-12-04 22:23:35 +00001239 break;
1240 case MVT::i64:
1241 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1242 ResultVals[0] = Chain.getValue(0);
1243 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001244 break;
Scott Michel2ef773a2009-01-06 03:36:14 +00001245 case MVT::i128:
1246 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
1247 ResultVals[0] = Chain.getValue(0);
1248 NumResults = 1;
1249 break;
Scott Michel8efdca42007-12-04 22:23:35 +00001250 case MVT::f32:
1251 case MVT::f64:
Dan Gohman705e3f72008-09-13 01:54:27 +00001252 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001253 InFlag).getValue(1);
1254 ResultVals[0] = Chain.getValue(0);
1255 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001256 break;
1257 case MVT::v2f64:
Scott Michele2641a12008-12-04 21:01:44 +00001258 case MVT::v2i64:
Scott Michel8efdca42007-12-04 22:23:35 +00001259 case MVT::v4f32:
1260 case MVT::v4i32:
1261 case MVT::v8i16:
1262 case MVT::v16i8:
Dan Gohman705e3f72008-09-13 01:54:27 +00001263 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel8efdca42007-12-04 22:23:35 +00001264 InFlag).getValue(1);
1265 ResultVals[0] = Chain.getValue(0);
1266 NumResults = 1;
Scott Michel8efdca42007-12-04 22:23:35 +00001267 break;
1268 }
Duncan Sands698842f2008-07-02 17:40:58 +00001269
Scott Michel8efdca42007-12-04 22:23:35 +00001270 // If the function returns void, just return the chain.
1271 if (NumResults == 0)
1272 return Chain;
Scott Michel4ec722e2008-07-16 17:17:29 +00001273
Scott Michel8efdca42007-12-04 22:23:35 +00001274 // Otherwise, merge everything together with a MERGE_VALUES node.
1275 ResultVals[NumResults++] = Chain;
Dan Gohman8181bd12008-07-27 21:46:04 +00001276 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif46bf5472008-08-26 22:36:50 +00001277 return Res.getValue(Op.getResNo());
Scott Michel8efdca42007-12-04 22:23:35 +00001278}
1279
Dan Gohman8181bd12008-07-27 21:46:04 +00001280static SDValue
1281LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel8efdca42007-12-04 22:23:35 +00001282 SmallVector<CCValAssign, 16> RVLocs;
1283 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1284 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1285 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greif1c80d112008-08-28 21:40:38 +00001286 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel4ec722e2008-07-16 17:17:29 +00001287
Scott Michel8efdca42007-12-04 22:23:35 +00001288 // If this is the first return lowered for this function, add the regs to the
1289 // liveout set for the function.
Chris Lattner1b989192007-12-31 04:13:23 +00001290 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001291 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner1b989192007-12-31 04:13:23 +00001292 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel8efdca42007-12-04 22:23:35 +00001293 }
1294
Dan Gohman8181bd12008-07-27 21:46:04 +00001295 SDValue Chain = Op.getOperand(0);
1296 SDValue Flag;
Scott Michel4ec722e2008-07-16 17:17:29 +00001297
Scott Michel8efdca42007-12-04 22:23:35 +00001298 // Copy the result values into the output registers.
1299 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1300 CCValAssign &VA = RVLocs[i];
1301 assert(VA.isRegLoc() && "Can only return in registers!");
1302 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1303 Flag = Chain.getValue(1);
1304 }
1305
Gabor Greif1c80d112008-08-28 21:40:38 +00001306 if (Flag.getNode())
Scott Michel8efdca42007-12-04 22:23:35 +00001307 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1308 else
1309 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1310}
1311
1312
1313//===----------------------------------------------------------------------===//
1314// Vector related lowering:
1315//===----------------------------------------------------------------------===//
1316
1317static ConstantSDNode *
1318getVecImm(SDNode *N) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001319 SDValue OpVal(0, 0);
Scott Michel4ec722e2008-07-16 17:17:29 +00001320
Scott Michel8efdca42007-12-04 22:23:35 +00001321 // Check to see if this buildvec has a single non-undef value in its elements.
1322 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1323 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greif1c80d112008-08-28 21:40:38 +00001324 if (OpVal.getNode() == 0)
Scott Michel8efdca42007-12-04 22:23:35 +00001325 OpVal = N->getOperand(i);
1326 else if (OpVal != N->getOperand(i))
1327 return 0;
1328 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001329
Gabor Greif1c80d112008-08-28 21:40:38 +00001330 if (OpVal.getNode() != 0) {
Scott Michel5974f432008-11-11 03:06:06 +00001331 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001332 return CN;
1333 }
1334 }
1335
1336 return 0; // All UNDEF: use implicit def.; not Constant node
1337}
1338
1339/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1340/// and the value fits into an unsigned 18-bit constant, and if so, return the
1341/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001342SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001343 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001344 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001345 uint64_t Value = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001346 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001347 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001348 uint32_t upper = uint32_t(UValue >> 32);
1349 uint32_t lower = uint32_t(UValue);
1350 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001351 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001352 Value = Value >> 32;
1353 }
Scott Michel8efdca42007-12-04 22:23:35 +00001354 if (Value <= 0x3ffff)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001355 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001356 }
1357
Dan Gohman8181bd12008-07-27 21:46:04 +00001358 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001359}
1360
1361/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1362/// and the value fits into a signed 16-bit constant, and if so, return the
1363/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001364SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001365 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001366 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001367 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001368 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001369 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001370 uint32_t upper = uint32_t(UValue >> 32);
1371 uint32_t lower = uint32_t(UValue);
1372 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001373 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001374 Value = Value >> 32;
1375 }
Scott Michel6baba072008-03-05 23:02:02 +00001376 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001377 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001378 }
1379 }
1380
Dan Gohman8181bd12008-07-27 21:46:04 +00001381 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001382}
1383
1384/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1385/// and the value fits into a signed 10-bit constant, and if so, return the
1386/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001387SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001388 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001389 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman40686732008-09-26 21:54:37 +00001390 int64_t Value = CN->getSExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001391 if (ValueType == MVT::i64) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001392 uint64_t UValue = CN->getZExtValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001393 uint32_t upper = uint32_t(UValue >> 32);
1394 uint32_t lower = uint32_t(UValue);
1395 if (upper != lower)
Dan Gohman8181bd12008-07-27 21:46:04 +00001396 return SDValue();
Scott Michelbcc7b672008-03-06 04:02:54 +00001397 Value = Value >> 32;
1398 }
Scott Michel6baba072008-03-05 23:02:02 +00001399 if (isS10Constant(Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001400 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001401 }
1402
Dan Gohman8181bd12008-07-27 21:46:04 +00001403 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001404}
1405
1406/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1407/// and the value fits into a signed 8-bit constant, and if so, return the
1408/// constant.
1409///
1410/// @note: The incoming vector is v16i8 because that's the only way we can load
1411/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1412/// same value.
Dan Gohman8181bd12008-07-27 21:46:04 +00001413SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001414 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001415 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001416 int Value = (int) CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001417 if (ValueType == MVT::i16
Scott Michel5a6f17b2008-01-30 02:55:46 +00001418 && Value <= 0xffff /* truncated from uint64_t */
1419 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001420 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001421 else if (ValueType == MVT::i8
Scott Michel5a6f17b2008-01-30 02:55:46 +00001422 && (Value & 0xff) == Value)
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001423 return DAG.getTargetConstant(Value, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001424 }
1425
Dan Gohman8181bd12008-07-27 21:46:04 +00001426 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001427}
1428
1429/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1430/// and the value fits into a signed 16-bit constant, and if so, return the
1431/// constant
Dan Gohman8181bd12008-07-27 21:46:04 +00001432SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands92c43912008-06-06 12:08:01 +00001433 MVT ValueType) {
Scott Michel8efdca42007-12-04 22:23:35 +00001434 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001435 uint64_t Value = CN->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001436 if ((ValueType == MVT::i32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001437 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1438 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001439 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel8efdca42007-12-04 22:23:35 +00001440 }
1441
Dan Gohman8181bd12008-07-27 21:46:04 +00001442 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001443}
1444
1445/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001446SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001447 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001448 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001449 }
1450
Dan Gohman8181bd12008-07-27 21:46:04 +00001451 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001452}
1453
1454/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman8181bd12008-07-27 21:46:04 +00001455SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel8efdca42007-12-04 22:23:35 +00001456 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman57d5d5d2008-11-05 02:06:09 +00001457 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001458 }
1459
Dan Gohman8181bd12008-07-27 21:46:04 +00001460 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001461}
1462
1463// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001464// UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001465// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1466// zero. Return true if this is not an array of constants, false if it is.
1467//
1468static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1469 uint64_t UndefBits[2]) {
1470 // Start with zero'd results.
1471 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001472
Duncan Sands92c43912008-06-06 12:08:01 +00001473 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel8efdca42007-12-04 22:23:35 +00001474 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman8181bd12008-07-27 21:46:04 +00001475 SDValue OpVal = BV->getOperand(i);
Scott Michel4ec722e2008-07-16 17:17:29 +00001476
Scott Michel8efdca42007-12-04 22:23:35 +00001477 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1478 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1479
1480 uint64_t EltBits = 0;
1481 if (OpVal.getOpcode() == ISD::UNDEF) {
1482 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1483 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1484 continue;
Scott Michel5974f432008-11-11 03:06:06 +00001485 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001486 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel5974f432008-11-11 03:06:06 +00001487 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel8efdca42007-12-04 22:23:35 +00001488 const APFloat &apf = CN->getValueAPF();
1489 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel5a6f17b2008-01-30 02:55:46 +00001490 ? FloatToBits(apf.convertToFloat())
1491 : DoubleToBits(apf.convertToDouble()));
Scott Michel8efdca42007-12-04 22:23:35 +00001492 } else {
1493 // Nonconstant element.
1494 return true;
1495 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001496
Scott Michel8efdca42007-12-04 22:23:35 +00001497 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1498 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001499
1500 //printf("%llx %llx %llx %llx\n",
Scott Michel8efdca42007-12-04 22:23:35 +00001501 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1502 return false;
1503}
1504
1505/// If this is a splat (repetition) of a value across the whole vector, return
1506/// the smallest size that splats it. For example, "0x01010101010101..." is a
Scott Michel4ec722e2008-07-16 17:17:29 +00001507/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel8efdca42007-12-04 22:23:35 +00001508/// SplatSize = 1 byte.
Scott Michel4ec722e2008-07-16 17:17:29 +00001509static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel8efdca42007-12-04 22:23:35 +00001510 const uint64_t Undef128[2],
Scott Michel5a6f17b2008-01-30 02:55:46 +00001511 int MinSplatBits,
Scott Michel8efdca42007-12-04 22:23:35 +00001512 uint64_t &SplatBits, uint64_t &SplatUndef,
1513 int &SplatSize) {
1514 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1515 // the same as the lower 64-bits, ignoring undefs.
1516 uint64_t Bits64 = Bits128[0] | Bits128[1];
1517 uint64_t Undef64 = Undef128[0] & Undef128[1];
1518 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1519 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1520 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1521 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1522
1523 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1524 if (MinSplatBits < 64) {
Scott Michel4ec722e2008-07-16 17:17:29 +00001525
Scott Michel8efdca42007-12-04 22:23:35 +00001526 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1527 // undefs.
1528 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001529 if (MinSplatBits < 32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001530
Scott Michel5a6f17b2008-01-30 02:55:46 +00001531 // If the top 16-bits are different than the lower 16-bits, ignoring
1532 // undefs, we have an i32 splat.
1533 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1534 if (MinSplatBits < 16) {
1535 // If the top 8-bits are different than the lower 8-bits, ignoring
1536 // undefs, we have an i16 splat.
Gabor Greife9f7f582008-08-31 15:37:04 +00001537 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1538 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001539 // Otherwise, we have an 8-bit splat.
1540 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1541 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1542 SplatSize = 1;
1543 return true;
1544 }
1545 } else {
1546 SplatBits = Bits16;
1547 SplatUndef = Undef16;
1548 SplatSize = 2;
1549 return true;
1550 }
1551 }
1552 } else {
1553 SplatBits = Bits32;
1554 SplatUndef = Undef32;
1555 SplatSize = 4;
1556 return true;
1557 }
Scott Michel8efdca42007-12-04 22:23:35 +00001558 }
1559 } else {
1560 SplatBits = Bits128[0];
1561 SplatUndef = Undef128[0];
1562 SplatSize = 8;
1563 return true;
1564 }
1565 }
1566
1567 return false; // Can't be a splat if two pieces don't match.
1568}
1569
Scott Michel8c67fa42009-01-21 04:58:48 +00001570//! Lower a BUILD_VECTOR instruction creatively:
1571SDValue
pingbak2f387e82009-01-26 03:31:40 +00001572LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001573 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00001574 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel4ec722e2008-07-16 17:17:29 +00001575 // UndefBits is set if the corresponding element of the vector is an
Scott Michel8efdca42007-12-04 22:23:35 +00001576 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel4ec722e2008-07-16 17:17:29 +00001577 // zero.
Scott Michel8efdca42007-12-04 22:23:35 +00001578 uint64_t VectorBits[2];
1579 uint64_t UndefBits[2];
1580 uint64_t SplatBits, SplatUndef;
1581 int SplatSize;
Gabor Greif1c80d112008-08-28 21:40:38 +00001582 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel8efdca42007-12-04 22:23:35 +00001583 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00001584 VT.getVectorElementType().getSizeInBits(),
Scott Michel8efdca42007-12-04 22:23:35 +00001585 SplatBits, SplatUndef, SplatSize))
Dan Gohman8181bd12008-07-27 21:46:04 +00001586 return SDValue(); // Not a constant vector, not a splat.
Scott Michel4ec722e2008-07-16 17:17:29 +00001587
Duncan Sands92c43912008-06-06 12:08:01 +00001588 switch (VT.getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001589 default:
Scott Michel8c67fa42009-01-21 04:58:48 +00001590 cerr << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
1591 << VT.getMVTString()
1592 << "\n";
1593 abort();
1594 /*NOTREACHED*/
Scott Michel8efdca42007-12-04 22:23:35 +00001595 case MVT::v4f32: {
pingbak2f387e82009-01-26 03:31:40 +00001596 uint32_t Value32 = uint32_t(SplatBits);
Scott Michel8efdca42007-12-04 22:23:35 +00001597 assert(SplatSize == 4
Scott Michel5a6f17b2008-01-30 02:55:46 +00001598 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel8efdca42007-12-04 22:23:35 +00001599 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001600 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00001601 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001602 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001603 break;
1604 }
1605 case MVT::v2f64: {
pingbak2f387e82009-01-26 03:31:40 +00001606 uint64_t f64val = uint64_t(SplatBits);
Scott Michel8efdca42007-12-04 22:23:35 +00001607 assert(SplatSize == 8
Scott Michelc630c412008-11-24 17:11:17 +00001608 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel8efdca42007-12-04 22:23:35 +00001609 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman8181bd12008-07-27 21:46:04 +00001610 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel8efdca42007-12-04 22:23:35 +00001611 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001612 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel8efdca42007-12-04 22:23:35 +00001613 break;
1614 }
1615 case MVT::v16i8: {
1616 // 8-bit constants have to be expanded to 16-bits
1617 unsigned short Value16 = SplatBits | (SplatBits << 8);
Dan Gohman8181bd12008-07-27 21:46:04 +00001618 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001619 for (int i = 0; i < 8; ++i)
1620 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1621 return DAG.getNode(ISD::BIT_CONVERT, VT,
1622 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1623 }
1624 case MVT::v8i16: {
1625 unsigned short Value16;
Scott Michel4ec722e2008-07-16 17:17:29 +00001626 if (SplatSize == 2)
Scott Michel8efdca42007-12-04 22:23:35 +00001627 Value16 = (unsigned short) (SplatBits & 0xffff);
1628 else
1629 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman8181bd12008-07-27 21:46:04 +00001630 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1631 SDValue Ops[8];
Scott Michel8efdca42007-12-04 22:23:35 +00001632 for (int i = 0; i < 8; ++i) Ops[i] = T;
1633 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1634 }
1635 case MVT::v4i32: {
1636 unsigned int Value = SplatBits;
Dan Gohman8181bd12008-07-27 21:46:04 +00001637 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel8efdca42007-12-04 22:23:35 +00001638 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1639 }
Scott Michel70741542009-01-06 23:10:38 +00001640 case MVT::v2i32: {
1641 unsigned int Value = SplatBits;
1642 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
1643 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
1644 }
Scott Michel8efdca42007-12-04 22:23:35 +00001645 case MVT::v2i64: {
pingbak2f387e82009-01-26 03:31:40 +00001646 return SPU::LowerSplat_v2i64(VT, DAG, SplatBits);
Scott Michel8efdca42007-12-04 22:23:35 +00001647 }
1648 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001649
Dan Gohman8181bd12008-07-27 21:46:04 +00001650 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001651}
1652
pingbak2f387e82009-01-26 03:31:40 +00001653SDValue
1654SPU::LowerSplat_v2i64(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal) {
1655 uint32_t upper = uint32_t(SplatVal >> 32);
1656 uint32_t lower = uint32_t(SplatVal);
1657
1658 if (upper == lower) {
1659 // Magic constant that can be matched by IL, ILA, et. al.
1660 SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
1661 return DAG.getNode(ISD::BIT_CONVERT, OpVT,
1662 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1663 Val, Val, Val, Val));
1664 } else {
1665 SDValue LO32;
1666 SDValue HI32;
1667 SmallVector<SDValue, 16> ShufBytes;
1668 SDValue Result;
1669 bool upper_special, lower_special;
1670
1671 // NOTE: This code creates common-case shuffle masks that can be easily
1672 // detected as common expressions. It is not attempting to create highly
1673 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1674
1675 // Detect if the upper or lower half is a special shuffle mask pattern:
1676 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1677 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1678
1679 // Create lower vector if not a special pattern
1680 if (!lower_special) {
1681 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
1682 LO32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
1683 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1684 LO32C, LO32C, LO32C, LO32C));
1685 }
1686
1687 // Create upper vector if not a special pattern
1688 if (!upper_special) {
1689 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
1690 HI32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
1691 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1692 HI32C, HI32C, HI32C, HI32C));
1693 }
1694
1695 // If either upper or lower are special, then the two input operands are
1696 // the same (basically, one of them is a "don't care")
1697 if (lower_special)
1698 LO32 = HI32;
1699 if (upper_special)
1700 HI32 = LO32;
1701 if (lower_special && upper_special) {
1702 // Unhappy situation... both upper and lower are special, so punt with
1703 // a target constant:
1704 SDValue Zero = DAG.getConstant(0, MVT::i32);
1705 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
1706 Zero, Zero);
1707 }
1708
1709 for (int i = 0; i < 4; ++i) {
1710 uint64_t val = 0;
1711 for (int j = 0; j < 4; ++j) {
1712 SDValue V;
1713 bool process_upper, process_lower;
1714 val <<= 8;
1715 process_upper = (upper_special && (i & 1) == 0);
1716 process_lower = (lower_special && (i & 1) == 1);
1717
1718 if (process_upper || process_lower) {
1719 if ((process_upper && upper == 0)
1720 || (process_lower && lower == 0))
1721 val |= 0x80;
1722 else if ((process_upper && upper == 0xffffffff)
1723 || (process_lower && lower == 0xffffffff))
1724 val |= 0xc0;
1725 else if ((process_upper && upper == 0x80000000)
1726 || (process_lower && lower == 0x80000000))
1727 val |= (j == 0 ? 0xe0 : 0x80);
1728 } else
1729 val |= i * 4 + j + ((i & 1) * 16);
1730 }
1731
1732 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
1733 }
1734
1735 return DAG.getNode(SPUISD::SHUFB, OpVT, HI32, LO32,
1736 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1737 &ShufBytes[0], ShufBytes.size()));
1738 }
1739}
1740
Scott Michel8efdca42007-12-04 22:23:35 +00001741/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1742/// which the Cell can operate. The code inspects V3 to ascertain whether the
1743/// permutation vector, V3, is monotonically increasing with one "exception"
1744/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel56a125e2008-11-22 23:50:42 +00001745/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel8efdca42007-12-04 22:23:35 +00001746/// In either case, the net result is going to eventually invoke SHUFB to
1747/// permute/shuffle the bytes from V1 and V2.
1748/// \note
Scott Michel56a125e2008-11-22 23:50:42 +00001749/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel8efdca42007-12-04 22:23:35 +00001750/// control word for byte/halfword/word insertion. This takes care of a single
1751/// element move from V2 into V1.
1752/// \note
1753/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman8181bd12008-07-27 21:46:04 +00001754static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
1755 SDValue V1 = Op.getOperand(0);
1756 SDValue V2 = Op.getOperand(1);
1757 SDValue PermMask = Op.getOperand(2);
Scott Michel4ec722e2008-07-16 17:17:29 +00001758
Scott Michel8efdca42007-12-04 22:23:35 +00001759 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel4ec722e2008-07-16 17:17:29 +00001760
Scott Michel8efdca42007-12-04 22:23:35 +00001761 // If we have a single element being moved from V1 to V2, this can be handled
1762 // using the C*[DX] compute mask instructions, but the vector elements have
1763 // to be monotonically increasing with one exception element.
Scott Michele2641a12008-12-04 21:01:44 +00001764 MVT VecVT = V1.getValueType();
1765 MVT EltVT = VecVT.getVectorElementType();
Scott Michel8efdca42007-12-04 22:23:35 +00001766 unsigned EltsFromV2 = 0;
1767 unsigned V2Elt = 0;
1768 unsigned V2EltIdx0 = 0;
1769 unsigned CurrElt = 0;
Scott Michele2641a12008-12-04 21:01:44 +00001770 unsigned MaxElts = VecVT.getVectorNumElements();
1771 unsigned PrevElt = 0;
1772 unsigned V0Elt = 0;
Scott Michel8efdca42007-12-04 22:23:35 +00001773 bool monotonic = true;
Scott Michele2641a12008-12-04 21:01:44 +00001774 bool rotate = true;
1775
1776 if (EltVT == MVT::i8) {
Scott Michel8efdca42007-12-04 22:23:35 +00001777 V2EltIdx0 = 16;
Scott Michele2641a12008-12-04 21:01:44 +00001778 } else if (EltVT == MVT::i16) {
Scott Michel8efdca42007-12-04 22:23:35 +00001779 V2EltIdx0 = 8;
Scott Michele2641a12008-12-04 21:01:44 +00001780 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel8efdca42007-12-04 22:23:35 +00001781 V2EltIdx0 = 4;
Scott Michele2641a12008-12-04 21:01:44 +00001782 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1783 V2EltIdx0 = 2;
1784 } else
Scott Michel8efdca42007-12-04 22:23:35 +00001785 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1786
Scott Michele2641a12008-12-04 21:01:44 +00001787 for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) {
1788 if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) {
1789 unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001790
Scott Michele2641a12008-12-04 21:01:44 +00001791 if (monotonic) {
1792 if (SrcElt >= V2EltIdx0) {
1793 if (1 >= (++EltsFromV2)) {
1794 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1795 }
1796 } else if (CurrElt != SrcElt) {
1797 monotonic = false;
1798 }
1799
1800 ++CurrElt;
1801 }
1802
1803 if (rotate) {
1804 if (PrevElt > 0 && SrcElt < MaxElts) {
1805 if ((PrevElt == SrcElt - 1)
1806 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
1807 PrevElt = SrcElt;
1808 if (SrcElt == 0)
1809 V0Elt = i;
1810 } else {
1811 rotate = false;
1812 }
1813 } else if (PrevElt == 0) {
1814 // First time through, need to keep track of previous element
1815 PrevElt = SrcElt;
1816 } else {
1817 // This isn't a rotation, takes elements from vector 2
1818 rotate = false;
1819 }
1820 }
Scott Michel8efdca42007-12-04 22:23:35 +00001821 }
Scott Michel8efdca42007-12-04 22:23:35 +00001822 }
1823
1824 if (EltsFromV2 == 1 && monotonic) {
1825 // Compute mask and shuffle
1826 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00001827 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1828 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands92c43912008-06-06 12:08:01 +00001829 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel8efdca42007-12-04 22:23:35 +00001830 // Initialize temporary register to 0
Dan Gohman8181bd12008-07-27 21:46:04 +00001831 SDValue InitTempReg =
Scott Michel8efdca42007-12-04 22:23:35 +00001832 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel56a125e2008-11-22 23:50:42 +00001833 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman8181bd12008-07-27 21:46:04 +00001834 SDValue ShufMaskOp =
Scott Michel0718cd82008-12-01 17:56:02 +00001835 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00001836 DAG.getTargetConstant(V2Elt, MVT::i32),
1837 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel8efdca42007-12-04 22:23:35 +00001838 // Use shuffle mask in SHUFB synthetic instruction:
1839 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
Scott Michele2641a12008-12-04 21:01:44 +00001840 } else if (rotate) {
1841 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michelae5cbf52008-12-29 03:23:36 +00001842
Scott Michele2641a12008-12-04 21:01:44 +00001843 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1844 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel8efdca42007-12-04 22:23:35 +00001845 } else {
Gabor Greife9f7f582008-08-31 15:37:04 +00001846 // Convert the SHUFFLE_VECTOR mask's input element units to the
1847 // actual bytes.
Duncan Sands92c43912008-06-06 12:08:01 +00001848 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel4ec722e2008-07-16 17:17:29 +00001849
Dan Gohman8181bd12008-07-27 21:46:04 +00001850 SmallVector<SDValue, 16> ResultMask;
Scott Michel8efdca42007-12-04 22:23:35 +00001851 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1852 unsigned SrcElt;
1853 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel5a6f17b2008-01-30 02:55:46 +00001854 SrcElt = 0;
Scott Michel4ec722e2008-07-16 17:17:29 +00001855 else
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001856 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel4ec722e2008-07-16 17:17:29 +00001857
Scott Michel97872d32008-02-23 18:41:37 +00001858 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00001859 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1860 MVT::i8));
Scott Michel8efdca42007-12-04 22:23:35 +00001861 }
1862 }
Scott Michel4ec722e2008-07-16 17:17:29 +00001863
Dan Gohman8181bd12008-07-27 21:46:04 +00001864 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel0718cd82008-12-01 17:56:02 +00001865 &ResultMask[0], ResultMask.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001866 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1867 }
1868}
1869
Dan Gohman8181bd12008-07-27 21:46:04 +00001870static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1871 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel8efdca42007-12-04 22:23:35 +00001872
Gabor Greif1c80d112008-08-28 21:40:38 +00001873 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel8efdca42007-12-04 22:23:35 +00001874 // For a constant, build the appropriate constant vector, which will
1875 // eventually simplify to a vector register load.
1876
Gabor Greif1c80d112008-08-28 21:40:38 +00001877 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman8181bd12008-07-27 21:46:04 +00001878 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands92c43912008-06-06 12:08:01 +00001879 MVT VT;
Scott Michel8efdca42007-12-04 22:23:35 +00001880 size_t n_copies;
1881
1882 // Create a constant vector:
Duncan Sands92c43912008-06-06 12:08:01 +00001883 switch (Op.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001884 default: assert(0 && "Unexpected constant value type in "
Scott Michel5a6f17b2008-01-30 02:55:46 +00001885 "LowerSCALAR_TO_VECTOR");
Scott Michel8efdca42007-12-04 22:23:35 +00001886 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1887 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1888 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1889 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1890 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1891 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1892 }
1893
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00001894 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel8efdca42007-12-04 22:23:35 +00001895 for (size_t j = 0; j < n_copies; ++j)
1896 ConstVecValues.push_back(CValue);
1897
1898 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00001899 &ConstVecValues[0], ConstVecValues.size());
Scott Michel8efdca42007-12-04 22:23:35 +00001900 } else {
1901 // Otherwise, copy the value from one register to another:
Duncan Sands92c43912008-06-06 12:08:01 +00001902 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel8efdca42007-12-04 22:23:35 +00001903 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1904 case MVT::i8:
1905 case MVT::i16:
1906 case MVT::i32:
1907 case MVT::i64:
1908 case MVT::f32:
1909 case MVT::f64:
Scott Michel06eabde2008-12-27 04:51:36 +00001910 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel8efdca42007-12-04 22:23:35 +00001911 }
1912 }
1913
Dan Gohman8181bd12008-07-27 21:46:04 +00001914 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001915}
1916
Dan Gohman8181bd12008-07-27 21:46:04 +00001917static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00001918 MVT VT = Op.getValueType();
Dan Gohman8181bd12008-07-27 21:46:04 +00001919 SDValue N = Op.getOperand(0);
1920 SDValue Elt = Op.getOperand(1);
Scott Michel56a125e2008-11-22 23:50:42 +00001921 SDValue retval;
Scott Michel8efdca42007-12-04 22:23:35 +00001922
Scott Michel56a125e2008-11-22 23:50:42 +00001923 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1924 // Constant argument:
1925 int EltNo = (int) C->getZExtValue();
Scott Michel8efdca42007-12-04 22:23:35 +00001926
Scott Michel56a125e2008-11-22 23:50:42 +00001927 // sanity checks:
1928 if (VT == MVT::i8 && EltNo >= 16)
1929 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1930 else if (VT == MVT::i16 && EltNo >= 8)
1931 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1932 else if (VT == MVT::i32 && EltNo >= 4)
1933 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1934 else if (VT == MVT::i64 && EltNo >= 2)
1935 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel8efdca42007-12-04 22:23:35 +00001936
Scott Michel56a125e2008-11-22 23:50:42 +00001937 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1938 // i32 and i64: Element 0 is the preferred slot
Scott Michelc630c412008-11-24 17:11:17 +00001939 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel56a125e2008-11-22 23:50:42 +00001940 }
Scott Michel8efdca42007-12-04 22:23:35 +00001941
Scott Michel56a125e2008-11-22 23:50:42 +00001942 // Need to generate shuffle mask and extract:
1943 int prefslot_begin = -1, prefslot_end = -1;
1944 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1945
1946 switch (VT.getSimpleVT()) {
1947 default:
1948 assert(false && "Invalid value type!");
1949 case MVT::i8: {
1950 prefslot_begin = prefslot_end = 3;
1951 break;
1952 }
1953 case MVT::i16: {
1954 prefslot_begin = 2; prefslot_end = 3;
1955 break;
1956 }
1957 case MVT::i32:
1958 case MVT::f32: {
1959 prefslot_begin = 0; prefslot_end = 3;
1960 break;
1961 }
1962 case MVT::i64:
1963 case MVT::f64: {
1964 prefslot_begin = 0; prefslot_end = 7;
1965 break;
1966 }
1967 }
1968
1969 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1970 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1971
1972 unsigned int ShufBytes[16];
1973 for (int i = 0; i < 16; ++i) {
1974 // zero fill uppper part of preferred slot, don't care about the
1975 // other slots:
1976 unsigned int mask_val;
1977 if (i <= prefslot_end) {
1978 mask_val =
1979 ((i < prefslot_begin)
1980 ? 0x80
1981 : elt_byte + (i - prefslot_begin));
1982
1983 ShufBytes[i] = mask_val;
1984 } else
1985 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1986 }
1987
1988 SDValue ShufMask[4];
1989 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michele2641a12008-12-04 21:01:44 +00001990 unsigned bidx = i * 4;
Scott Michel56a125e2008-11-22 23:50:42 +00001991 unsigned int bits = ((ShufBytes[bidx] << 24) |
1992 (ShufBytes[bidx+1] << 16) |
1993 (ShufBytes[bidx+2] << 8) |
1994 ShufBytes[bidx+3]);
1995 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1996 }
1997
1998 SDValue ShufMaskVec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1999 &ShufMask[0],
2000 sizeof(ShufMask) / sizeof(ShufMask[0]));
2001
Scott Michelc630c412008-11-24 17:11:17 +00002002 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel56a125e2008-11-22 23:50:42 +00002003 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2004 N, N, ShufMaskVec));
2005 } else {
2006 // Variable index: Rotate the requested element into slot 0, then replicate
2007 // slot 0 across the vector
2008 MVT VecVT = N.getValueType();
2009 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
2010 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
2011 abort();
2012 }
2013
2014 // Make life easier by making sure the index is zero-extended to i32
2015 if (Elt.getValueType() != MVT::i32)
2016 Elt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Elt);
2017
2018 // Scale the index to a bit/byte shift quantity
2019 APInt scaleFactor =
Scott Michelc630c412008-11-24 17:11:17 +00002020 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
2021 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel56a125e2008-11-22 23:50:42 +00002022 SDValue vecShift;
Scott Michel56a125e2008-11-22 23:50:42 +00002023
Scott Michelc630c412008-11-24 17:11:17 +00002024 if (scaleShift > 0) {
2025 // Scale the shift factor:
Scott Michel56a125e2008-11-22 23:50:42 +00002026 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel0718cd82008-12-01 17:56:02 +00002027 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel56a125e2008-11-22 23:50:42 +00002028 }
2029
Scott Michelc630c412008-11-24 17:11:17 +00002030 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt);
2031
2032 // Replicate the bytes starting at byte 0 across the entire vector (for
2033 // consistency with the notion of a unified register set)
Scott Michel56a125e2008-11-22 23:50:42 +00002034 SDValue replicate;
2035
2036 switch (VT.getSimpleVT()) {
2037 default:
2038 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
2039 abort();
2040 /*NOTREACHED*/
2041 case MVT::i8: {
Scott Michelc630c412008-11-24 17:11:17 +00002042 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel56a125e2008-11-22 23:50:42 +00002043 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2044 factor, factor);
2045 break;
2046 }
2047 case MVT::i16: {
Scott Michelc630c412008-11-24 17:11:17 +00002048 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel56a125e2008-11-22 23:50:42 +00002049 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2050 factor, factor);
2051 break;
2052 }
2053 case MVT::i32:
2054 case MVT::f32: {
2055 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
2056 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2057 factor, factor);
2058 break;
2059 }
2060 case MVT::i64:
2061 case MVT::f64: {
2062 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2063 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
2064 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, loFactor, hiFactor,
2065 loFactor, hiFactor);
2066 break;
2067 }
2068 }
2069
Scott Michelc630c412008-11-24 17:11:17 +00002070 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel0718cd82008-12-01 17:56:02 +00002071 DAG.getNode(SPUISD::SHUFB, VecVT,
2072 vecShift, vecShift, replicate));
Scott Michel8efdca42007-12-04 22:23:35 +00002073 }
2074
Scott Michel56a125e2008-11-22 23:50:42 +00002075 return retval;
Scott Michel8efdca42007-12-04 22:23:35 +00002076}
2077
Dan Gohman8181bd12008-07-27 21:46:04 +00002078static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2079 SDValue VecOp = Op.getOperand(0);
2080 SDValue ValOp = Op.getOperand(1);
2081 SDValue IdxOp = Op.getOperand(2);
Duncan Sands92c43912008-06-06 12:08:01 +00002082 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002083
2084 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2085 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2086
Duncan Sands92c43912008-06-06 12:08:01 +00002087 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel0718cd82008-12-01 17:56:02 +00002088 // Use $sp ($1) because it's always 16-byte aligned and it's available:
2089 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
2090 DAG.getRegister(SPU::R1, PtrVT),
2091 DAG.getConstant(CN->getSExtValue(), PtrVT));
2092 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer);
Scott Michel8efdca42007-12-04 22:23:35 +00002093
Dan Gohman8181bd12008-07-27 21:46:04 +00002094 SDValue result =
Scott Michel8efdca42007-12-04 22:23:35 +00002095 DAG.getNode(SPUISD::SHUFB, VT,
2096 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michelae5cbf52008-12-29 03:23:36 +00002097 VecOp,
pingbakb8913342009-01-26 03:37:41 +00002098 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel8efdca42007-12-04 22:23:35 +00002099
2100 return result;
2101}
2102
Scott Michel06eabde2008-12-27 04:51:36 +00002103static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2104 const TargetLowering &TLI)
Scott Michel97872d32008-02-23 18:41:37 +00002105{
Dan Gohman8181bd12008-07-27 21:46:04 +00002106 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michel06eabde2008-12-27 04:51:36 +00002107 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel8efdca42007-12-04 22:23:35 +00002108
2109 assert(Op.getValueType() == MVT::i8);
2110 switch (Opc) {
2111 default:
2112 assert(0 && "Unhandled i8 math operator");
2113 /*NOTREACHED*/
2114 break;
Scott Michel4d07fb72008-12-30 23:28:25 +00002115 case ISD::ADD: {
2116 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2117 // the result:
2118 SDValue N1 = Op.getOperand(1);
2119 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2120 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
2121 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2122 DAG.getNode(Opc, MVT::i16, N0, N1));
2123
2124 }
2125
Scott Michel8efdca42007-12-04 22:23:35 +00002126 case ISD::SUB: {
2127 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2128 // the result:
Dan Gohman8181bd12008-07-27 21:46:04 +00002129 SDValue N1 = Op.getOperand(1);
Scott Michel4d07fb72008-12-30 23:28:25 +00002130 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2131 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
Scott Michel4ec722e2008-07-16 17:17:29 +00002132 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002133 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel4ec722e2008-07-16 17:17:29 +00002134 }
Scott Michel8efdca42007-12-04 22:23:35 +00002135 case ISD::ROTR:
2136 case ISD::ROTL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002137 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002138 unsigned N1Opc;
2139 N0 = (N0.getOpcode() != ISD::Constant
2140 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002141 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2142 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002143 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002144 ? ISD::ZERO_EXTEND
2145 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002146 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002147 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002148 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002149 TLI.getShiftAmountTy()));
Dan Gohman8181bd12008-07-27 21:46:04 +00002150 SDValue ExpandArg =
Scott Michel8efdca42007-12-04 22:23:35 +00002151 DAG.getNode(ISD::OR, MVT::i16, N0,
2152 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sands7aef60d2008-10-30 19:24:28 +00002153 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel4ec722e2008-07-16 17:17:29 +00002154 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002155 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2156 }
2157 case ISD::SRL:
2158 case ISD::SHL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002159 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002160 unsigned N1Opc;
2161 N0 = (N0.getOpcode() != ISD::Constant
2162 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002163 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002164 MVT::i32));
2165 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002166 ? ISD::ZERO_EXTEND
2167 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002168 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002169 ? DAG.getNode(N1Opc, ShiftVT, N1)
2170 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002171 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002172 DAG.getNode(Opc, MVT::i16, N0, N1));
2173 }
2174 case ISD::SRA: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002175 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002176 unsigned N1Opc;
2177 N0 = (N0.getOpcode() != ISD::Constant
2178 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michel06eabde2008-12-27 04:51:36 +00002179 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002180 MVT::i16));
Scott Michel06eabde2008-12-27 04:51:36 +00002181 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greife9f7f582008-08-31 15:37:04 +00002182 ? ISD::SIGN_EXTEND
2183 : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002184 N1 = (N1.getOpcode() != ISD::Constant
Scott Michel06eabde2008-12-27 04:51:36 +00002185 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002186 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michel06eabde2008-12-27 04:51:36 +00002187 ShiftVT));
Scott Michel4ec722e2008-07-16 17:17:29 +00002188 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002189 DAG.getNode(Opc, MVT::i16, N0, N1));
2190 }
2191 case ISD::MUL: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002192 SDValue N1 = Op.getOperand(1);
Scott Michel8efdca42007-12-04 22:23:35 +00002193 unsigned N1Opc;
2194 N0 = (N0.getOpcode() != ISD::Constant
2195 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002196 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2197 MVT::i16));
Duncan Sandsec142ee2008-06-08 20:54:56 +00002198 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel8efdca42007-12-04 22:23:35 +00002199 N1 = (N1.getOpcode() != ISD::Constant
2200 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michel06eabde2008-12-27 04:51:36 +00002201 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanfaeb4a32008-09-12 16:56:44 +00002202 MVT::i16));
Scott Michel4ec722e2008-07-16 17:17:29 +00002203 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel8efdca42007-12-04 22:23:35 +00002204 DAG.getNode(Opc, MVT::i16, N0, N1));
2205 break;
2206 }
2207 }
2208
Dan Gohman8181bd12008-07-27 21:46:04 +00002209 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002210}
2211
Scott Michel750b93f2009-01-15 04:41:47 +00002212//! Generate the carry-generate shuffle mask.
2213SDValue SPU::getCarryGenerateShufMask(SelectionDAG &DAG) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002214 SmallVector<SDValue, 16 > ShufBytes;
Scott Michel97872d32008-02-23 18:41:37 +00002215
Scott Michel8c67fa42009-01-21 04:58:48 +00002216 // Create the shuffle mask for "rotating" the borrow up one register slot
2217 // once the borrow is generated.
2218 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2219 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2220 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2221 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
Scott Michel97872d32008-02-23 18:41:37 +00002222
Scott Michel8c67fa42009-01-21 04:58:48 +00002223 return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2224 &ShufBytes[0], ShufBytes.size());
Scott Michel750b93f2009-01-15 04:41:47 +00002225}
Scott Michel97872d32008-02-23 18:41:37 +00002226
Scott Michel750b93f2009-01-15 04:41:47 +00002227//! Generate the borrow-generate shuffle mask
2228SDValue SPU::getBorrowGenerateShufMask(SelectionDAG &DAG) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002229 SmallVector<SDValue, 16 > ShufBytes;
Scott Michel97872d32008-02-23 18:41:37 +00002230
Scott Michel8c67fa42009-01-21 04:58:48 +00002231 // Create the shuffle mask for "rotating" the borrow up one register slot
2232 // once the borrow is generated.
2233 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2234 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2235 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2236 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
Scott Michelf2df6cb2008-11-24 18:20:46 +00002237
Scott Michel8c67fa42009-01-21 04:58:48 +00002238 return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2239 &ShufBytes[0], ShufBytes.size());
Scott Michel97872d32008-02-23 18:41:37 +00002240}
2241
Scott Michel8efdca42007-12-04 22:23:35 +00002242//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman8181bd12008-07-27 21:46:04 +00002243static SDValue
2244LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2245 SDValue ConstVec;
2246 SDValue Arg;
Duncan Sands92c43912008-06-06 12:08:01 +00002247 MVT VT = Op.getValueType();
Scott Michel8efdca42007-12-04 22:23:35 +00002248
2249 ConstVec = Op.getOperand(0);
2250 Arg = Op.getOperand(1);
Gabor Greif1c80d112008-08-28 21:40:38 +00002251 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2252 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel8efdca42007-12-04 22:23:35 +00002253 ConstVec = ConstVec.getOperand(0);
2254 } else {
2255 ConstVec = Op.getOperand(1);
2256 Arg = Op.getOperand(0);
Gabor Greif1c80d112008-08-28 21:40:38 +00002257 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel5a6f17b2008-01-30 02:55:46 +00002258 ConstVec = ConstVec.getOperand(0);
Scott Michel8efdca42007-12-04 22:23:35 +00002259 }
2260 }
2261 }
2262
Gabor Greif1c80d112008-08-28 21:40:38 +00002263 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel8efdca42007-12-04 22:23:35 +00002264 uint64_t VectorBits[2];
2265 uint64_t UndefBits[2];
2266 uint64_t SplatBits, SplatUndef;
2267 int SplatSize;
2268
Gabor Greif1c80d112008-08-28 21:40:38 +00002269 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002270 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands92c43912008-06-06 12:08:01 +00002271 VT.getVectorElementType().getSizeInBits(),
Scott Michel5a6f17b2008-01-30 02:55:46 +00002272 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002273 SDValue tcVec[16];
2274 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel8efdca42007-12-04 22:23:35 +00002275 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2276
2277 // Turn the BUILD_VECTOR into a set of target constants:
2278 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel5a6f17b2008-01-30 02:55:46 +00002279 tcVec[i] = tc;
Scott Michel8efdca42007-12-04 22:23:35 +00002280
Gabor Greif1c80d112008-08-28 21:40:38 +00002281 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002282 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel8efdca42007-12-04 22:23:35 +00002283 }
2284 }
Scott Michelc899a122009-01-26 22:33:37 +00002285
Nate Begeman7569e762008-07-29 19:07:27 +00002286 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2287 // lowered. Return the operation, rather than a null SDValue.
2288 return Op;
Scott Michel8efdca42007-12-04 22:23:35 +00002289}
2290
Scott Michel8efdca42007-12-04 22:23:35 +00002291//! Custom lowering for CTPOP (count population)
2292/*!
2293 Custom lowering code that counts the number ones in the input
2294 operand. SPU has such an instruction, but it counts the number of
2295 ones per byte, which then have to be accumulated.
2296*/
Dan Gohman8181bd12008-07-27 21:46:04 +00002297static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands92c43912008-06-06 12:08:01 +00002298 MVT VT = Op.getValueType();
2299 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel8efdca42007-12-04 22:23:35 +00002300
Duncan Sands92c43912008-06-06 12:08:01 +00002301 switch (VT.getSimpleVT()) {
2302 default:
2303 assert(false && "Invalid value type!");
Scott Michel8efdca42007-12-04 22:23:35 +00002304 case MVT::i8: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002305 SDValue N = Op.getOperand(0);
2306 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002307
Scott Michel06eabde2008-12-27 04:51:36 +00002308 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002309 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002310
2311 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2312 }
2313
2314 case MVT::i16: {
2315 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002316 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002317
Chris Lattner1b989192007-12-31 04:13:23 +00002318 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002319
Dan Gohman8181bd12008-07-27 21:46:04 +00002320 SDValue N = Op.getOperand(0);
2321 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2322 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sands7aef60d2008-10-30 19:24:28 +00002323 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002324
Scott Michel06eabde2008-12-27 04:51:36 +00002325 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002326 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002327
2328 // CNTB_result becomes the chain to which all of the virtual registers
2329 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002330 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002331 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002332
Dan Gohman8181bd12008-07-27 21:46:04 +00002333 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002334 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2335
Dan Gohman8181bd12008-07-27 21:46:04 +00002336 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel8efdca42007-12-04 22:23:35 +00002337
2338 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002339 DAG.getNode(ISD::ADD, MVT::i16,
2340 DAG.getNode(ISD::SRL, MVT::i16,
2341 Tmp1, Shift1),
2342 Tmp1),
2343 Mask0);
Scott Michel8efdca42007-12-04 22:23:35 +00002344 }
2345
2346 case MVT::i32: {
2347 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner1b989192007-12-31 04:13:23 +00002348 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel8efdca42007-12-04 22:23:35 +00002349
Chris Lattner1b989192007-12-31 04:13:23 +00002350 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2351 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel8efdca42007-12-04 22:23:35 +00002352
Dan Gohman8181bd12008-07-27 21:46:04 +00002353 SDValue N = Op.getOperand(0);
2354 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2355 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2356 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2357 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel8efdca42007-12-04 22:23:35 +00002358
Scott Michel06eabde2008-12-27 04:51:36 +00002359 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman8181bd12008-07-27 21:46:04 +00002360 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel8efdca42007-12-04 22:23:35 +00002361
2362 // CNTB_result becomes the chain to which all of the virtual registers
2363 // CNTB_reg, SUM1_reg become associated:
Dan Gohman8181bd12008-07-27 21:46:04 +00002364 SDValue CNTB_result =
Scott Michel8efdca42007-12-04 22:23:35 +00002365 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel4ec722e2008-07-16 17:17:29 +00002366
Dan Gohman8181bd12008-07-27 21:46:04 +00002367 SDValue CNTB_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002368 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2369
Dan Gohman8181bd12008-07-27 21:46:04 +00002370 SDValue Comp1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002371 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002372 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel8efdca42007-12-04 22:23:35 +00002373
Dan Gohman8181bd12008-07-27 21:46:04 +00002374 SDValue Sum1 =
Scott Michel8efdca42007-12-04 22:23:35 +00002375 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002376 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002377
Dan Gohman8181bd12008-07-27 21:46:04 +00002378 SDValue Sum1_rescopy =
Scott Michel8efdca42007-12-04 22:23:35 +00002379 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2380
Dan Gohman8181bd12008-07-27 21:46:04 +00002381 SDValue Comp2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002382 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002383 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2384 Shift2);
Dan Gohman8181bd12008-07-27 21:46:04 +00002385 SDValue Sum2 =
Scott Michel8efdca42007-12-04 22:23:35 +00002386 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel5a6f17b2008-01-30 02:55:46 +00002387 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel8efdca42007-12-04 22:23:35 +00002388
2389 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2390 }
2391
2392 case MVT::i64:
2393 break;
2394 }
2395
Dan Gohman8181bd12008-07-27 21:46:04 +00002396 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002397}
2398
pingbak2f387e82009-01-26 03:31:40 +00002399//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Michel8c67fa42009-01-21 04:58:48 +00002400/*!
pingbak2f387e82009-01-26 03:31:40 +00002401 f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
2402 All conversions to i64 are expanded to a libcall.
Scott Michel8c67fa42009-01-21 04:58:48 +00002403 */
pingbak2f387e82009-01-26 03:31:40 +00002404static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2405 SPUTargetLowering &TLI) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002406 MVT OpVT = Op.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002407 SDValue Op0 = Op.getOperand(0);
pingbak2f387e82009-01-26 03:31:40 +00002408 MVT Op0VT = Op0.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002409
pingbak2f387e82009-01-26 03:31:40 +00002410 if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
2411 || OpVT == MVT::i64) {
2412 // Convert f32 / f64 to i32 / i64 via libcall.
2413 RTLIB::Libcall LC =
2414 (Op.getOpcode() == ISD::FP_TO_SINT)
2415 ? RTLIB::getFPTOSINT(Op0VT, OpVT)
2416 : RTLIB::getFPTOUINT(Op0VT, OpVT);
2417 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
2418 SDValue Dummy;
2419 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2420 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002421
Scott Michelc899a122009-01-26 22:33:37 +00002422 return Op; // return unmolested, legalized op
pingbak2f387e82009-01-26 03:31:40 +00002423}
Scott Michel8c67fa42009-01-21 04:58:48 +00002424
pingbak2f387e82009-01-26 03:31:40 +00002425//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
2426/*!
2427 i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
2428 All conversions from i64 are expanded to a libcall.
2429 */
2430static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
2431 SPUTargetLowering &TLI) {
2432 MVT OpVT = Op.getValueType();
2433 SDValue Op0 = Op.getOperand(0);
2434 MVT Op0VT = Op0.getValueType();
2435
2436 if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
2437 || Op0VT == MVT::i64) {
2438 // Convert i32, i64 to f64 via libcall:
2439 RTLIB::Libcall LC =
2440 (Op.getOpcode() == ISD::SINT_TO_FP)
2441 ? RTLIB::getSINTTOFP(Op0VT, OpVT)
2442 : RTLIB::getUINTTOFP(Op0VT, OpVT);
2443 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
2444 SDValue Dummy;
2445 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2446 }
2447
Scott Michelc899a122009-01-26 22:33:37 +00002448 return Op; // return unmolested, legalized
Scott Michel8c67fa42009-01-21 04:58:48 +00002449}
2450
2451//! Lower ISD::SETCC
2452/*!
2453 This handles MVT::f64 (double floating point) condition lowering
2454 */
Scott Michel8c67fa42009-01-21 04:58:48 +00002455static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2456 const TargetLowering &TLI) {
pingbak2f387e82009-01-26 03:31:40 +00002457 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002458 DebugLoc dl = Op.getNode()->getDebugLoc();
pingbak2f387e82009-01-26 03:31:40 +00002459 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2460
Scott Michel8c67fa42009-01-21 04:58:48 +00002461 SDValue lhs = Op.getOperand(0);
2462 SDValue rhs = Op.getOperand(1);
Scott Michel8c67fa42009-01-21 04:58:48 +00002463 MVT lhsVT = lhs.getValueType();
Scott Michel8c67fa42009-01-21 04:58:48 +00002464 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2465
pingbak2f387e82009-01-26 03:31:40 +00002466 MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
2467 APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2468 MVT IntVT(MVT::i64);
2469
2470 // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
2471 // selected to a NOP:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002472 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, dl, IntVT, lhs);
pingbak2f387e82009-01-26 03:31:40 +00002473 SDValue lhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002474 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2475 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002476 i64lhs, DAG.getConstant(32, MVT::i32)));
2477 SDValue lhsHi32abs =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002478 DAG.getNode(ISD::AND, dl, MVT::i32,
pingbak2f387e82009-01-26 03:31:40 +00002479 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2480 SDValue lhsLo32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002481 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, i64lhs);
pingbak2f387e82009-01-26 03:31:40 +00002482
2483 // SETO and SETUO only use the lhs operand:
2484 if (CC->get() == ISD::SETO) {
2485 // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
2486 // SETUO
2487 APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
Dale Johannesen85fc0932009-02-04 01:48:28 +00002488 return DAG.getNode(ISD::XOR, dl, ccResultVT,
2489 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002490 lhs, DAG.getConstantFP(0.0, lhsVT),
2491 ISD::SETUO),
2492 DAG.getConstant(ccResultAllOnes, ccResultVT));
2493 } else if (CC->get() == ISD::SETUO) {
2494 // Evaluates to true if Op0 is [SQ]NaN
Dale Johannesen85fc0932009-02-04 01:48:28 +00002495 return DAG.getNode(ISD::AND, dl, ccResultVT,
2496 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002497 lhsHi32abs,
2498 DAG.getConstant(0x7ff00000, MVT::i32),
2499 ISD::SETGE),
Dale Johannesen85fc0932009-02-04 01:48:28 +00002500 DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002501 lhsLo32,
2502 DAG.getConstant(0, MVT::i32),
2503 ISD::SETGT));
2504 }
2505
2506 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, rhs);
2507 SDValue rhsHi32 =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002508 DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
2509 DAG.getNode(ISD::SRL, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002510 i64rhs, DAG.getConstant(32, MVT::i32)));
2511
2512 // If a value is negative, subtract from the sign magnitude constant:
2513 SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
2514
2515 // Convert the sign-magnitude representation into 2's complement:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002516 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002517 lhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002518 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64lhs);
pingbak2f387e82009-01-26 03:31:40 +00002519 SDValue lhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002520 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002521 lhsSelectMask, lhsSignMag2TC, i64lhs);
2522
Dale Johannesen85fc0932009-02-04 01:48:28 +00002523 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002524 rhsHi32, DAG.getConstant(31, MVT::i32));
Dale Johannesen85fc0932009-02-04 01:48:28 +00002525 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, dl, IntVT, signMag2TC, i64rhs);
pingbak2f387e82009-01-26 03:31:40 +00002526 SDValue rhsSelect =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002527 DAG.getNode(ISD::SELECT, dl, IntVT,
pingbak2f387e82009-01-26 03:31:40 +00002528 rhsSelectMask, rhsSignMag2TC, i64rhs);
2529
2530 unsigned compareOp;
2531
Scott Michel8c67fa42009-01-21 04:58:48 +00002532 switch (CC->get()) {
2533 case ISD::SETOEQ:
Scott Michel8c67fa42009-01-21 04:58:48 +00002534 case ISD::SETUEQ:
pingbak2f387e82009-01-26 03:31:40 +00002535 compareOp = ISD::SETEQ; break;
2536 case ISD::SETOGT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002537 case ISD::SETUGT:
pingbak2f387e82009-01-26 03:31:40 +00002538 compareOp = ISD::SETGT; break;
2539 case ISD::SETOGE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002540 case ISD::SETUGE:
pingbak2f387e82009-01-26 03:31:40 +00002541 compareOp = ISD::SETGE; break;
2542 case ISD::SETOLT:
Scott Michel8c67fa42009-01-21 04:58:48 +00002543 case ISD::SETULT:
pingbak2f387e82009-01-26 03:31:40 +00002544 compareOp = ISD::SETLT; break;
2545 case ISD::SETOLE:
Scott Michel8c67fa42009-01-21 04:58:48 +00002546 case ISD::SETULE:
pingbak2f387e82009-01-26 03:31:40 +00002547 compareOp = ISD::SETLE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002548 case ISD::SETUNE:
pingbak2f387e82009-01-26 03:31:40 +00002549 case ISD::SETONE:
2550 compareOp = ISD::SETNE; break;
Scott Michel8c67fa42009-01-21 04:58:48 +00002551 default:
2552 cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
2553 abort();
2554 break;
2555 }
2556
pingbak2f387e82009-01-26 03:31:40 +00002557 SDValue result =
Dale Johannesen85fc0932009-02-04 01:48:28 +00002558 DAG.getSetCC(dl, ccResultVT, lhsSelect, rhsSelect,
2559 (ISD::CondCode) compareOp);
pingbak2f387e82009-01-26 03:31:40 +00002560
2561 if ((CC->get() & 0x8) == 0) {
2562 // Ordered comparison:
Dale Johannesen85fc0932009-02-04 01:48:28 +00002563 SDValue lhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002564 lhs, DAG.getConstantFP(0.0, MVT::f64),
2565 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002566 SDValue rhsNaN = DAG.getSetCC(dl, ccResultVT,
pingbak2f387e82009-01-26 03:31:40 +00002567 rhs, DAG.getConstantFP(0.0, MVT::f64),
2568 ISD::SETO);
Dale Johannesen85fc0932009-02-04 01:48:28 +00002569 SDValue ordered = DAG.getNode(ISD::AND, dl, ccResultVT, lhsNaN, rhsNaN);
pingbak2f387e82009-01-26 03:31:40 +00002570
Dale Johannesen85fc0932009-02-04 01:48:28 +00002571 result = DAG.getNode(ISD::AND, dl, ccResultVT, ordered, result);
pingbak2f387e82009-01-26 03:31:40 +00002572 }
2573
2574 return result;
Scott Michel8c67fa42009-01-21 04:58:48 +00002575}
2576
Scott Michel56a125e2008-11-22 23:50:42 +00002577//! Lower ISD::SELECT_CC
2578/*!
2579 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2580 SELB instruction.
2581
2582 \note Need to revisit this in the future: if the code path through the true
2583 and false value computations is longer than the latency of a branch (6
2584 cycles), then it would be more advantageous to branch and insert a new basic
2585 block and branch on the condition. However, this code does not make that
2586 assumption, given the simplisitc uses so far.
2587 */
2588
Scott Michel06eabde2008-12-27 04:51:36 +00002589static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2590 const TargetLowering &TLI) {
Scott Michel56a125e2008-11-22 23:50:42 +00002591 MVT VT = Op.getValueType();
2592 SDValue lhs = Op.getOperand(0);
2593 SDValue rhs = Op.getOperand(1);
2594 SDValue trueval = Op.getOperand(2);
2595 SDValue falseval = Op.getOperand(3);
2596 SDValue condition = Op.getOperand(4);
2597
Scott Michel06eabde2008-12-27 04:51:36 +00002598 // NOTE: SELB's arguments: $rA, $rB, $mask
2599 //
2600 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2601 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2602 // condition was true and 0s where the condition was false. Hence, the
2603 // arguments to SELB get reversed.
2604
Scott Michel56a125e2008-11-22 23:50:42 +00002605 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2606 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2607 // with another "cannot select select_cc" assert:
2608
Duncan Sands4a361272009-01-01 15:52:00 +00002609 SDValue compare = DAG.getNode(ISD::SETCC,
2610 TLI.getSetCCResultType(Op.getValueType()),
Scott Michel06eabde2008-12-27 04:51:36 +00002611 lhs, rhs, condition);
2612 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel56a125e2008-11-22 23:50:42 +00002613}
2614
Scott Michelec8c82e2008-12-02 19:53:53 +00002615//! Custom lower ISD::TRUNCATE
2616static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2617{
2618 MVT VT = Op.getValueType();
2619 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2620 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
2621
2622 SDValue Op0 = Op.getOperand(0);
2623 MVT Op0VT = Op0.getValueType();
2624 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
2625
Scott Michel06eabde2008-12-27 04:51:36 +00002626 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michelc5a29fe2009-01-03 00:27:53 +00002627 // Create shuffle mask, least significant doubleword of quadword
Scott Michel06eabde2008-12-27 04:51:36 +00002628 unsigned maskHigh = 0x08090a0b;
2629 unsigned maskLow = 0x0c0d0e0f;
2630 // Use a shuffle to perform the truncation
2631 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2632 DAG.getConstant(maskHigh, MVT::i32),
2633 DAG.getConstant(maskLow, MVT::i32),
2634 DAG.getConstant(maskHigh, MVT::i32),
2635 DAG.getConstant(maskLow, MVT::i32));
2636
2637
2638 SDValue PromoteScalar = DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
2639
2640 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2641 PromoteScalar, PromoteScalar, shufMask);
2642
2643 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2644 DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle));
Scott Michelec8c82e2008-12-02 19:53:53 +00002645 }
2646
Scott Michel06eabde2008-12-27 04:51:36 +00002647 return SDValue(); // Leave the truncate unmolested
Scott Michelec8c82e2008-12-02 19:53:53 +00002648}
2649
Scott Michel56a125e2008-11-22 23:50:42 +00002650//! Custom (target-specific) lowering entry point
2651/*!
2652 This is where LLVM's DAG selection process calls to do target-specific
2653 lowering of nodes.
2654 */
Dan Gohman8181bd12008-07-27 21:46:04 +00002655SDValue
2656SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel8efdca42007-12-04 22:23:35 +00002657{
Scott Michel97872d32008-02-23 18:41:37 +00002658 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands92c43912008-06-06 12:08:01 +00002659 MVT VT = Op.getValueType();
Scott Michel97872d32008-02-23 18:41:37 +00002660
2661 switch (Opc) {
Scott Michel8efdca42007-12-04 22:23:35 +00002662 default: {
2663 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michel97872d32008-02-23 18:41:37 +00002664 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greif1c80d112008-08-28 21:40:38 +00002665 cerr << "*Op.getNode():\n";
2666 Op.getNode()->dump();
Scott Michel8efdca42007-12-04 22:23:35 +00002667 abort();
2668 }
2669 case ISD::LOAD:
Scott Michelec8c82e2008-12-02 19:53:53 +00002670 case ISD::EXTLOAD:
Scott Michel8efdca42007-12-04 22:23:35 +00002671 case ISD::SEXTLOAD:
2672 case ISD::ZEXTLOAD:
2673 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2674 case ISD::STORE:
2675 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2676 case ISD::ConstantPool:
2677 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2678 case ISD::GlobalAddress:
2679 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2680 case ISD::JumpTable:
2681 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002682 case ISD::ConstantFP:
2683 return LowerConstantFP(Op, DAG);
2684 case ISD::FORMAL_ARGUMENTS:
Scott Michel394e26d2008-01-17 20:38:41 +00002685 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel8efdca42007-12-04 22:23:35 +00002686 case ISD::CALL:
Scott Micheldbac4cf2008-01-11 02:53:15 +00002687 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel8efdca42007-12-04 22:23:35 +00002688 case ISD::RET:
2689 return LowerRET(Op, DAG, getTargetMachine());
2690
Scott Michel4d07fb72008-12-30 23:28:25 +00002691 // i8, i64 math ops:
Scott Michel67224b22008-06-02 22:18:03 +00002692 case ISD::ADD:
Scott Michel8efdca42007-12-04 22:23:35 +00002693 case ISD::SUB:
2694 case ISD::ROTR:
2695 case ISD::ROTL:
2696 case ISD::SRL:
2697 case ISD::SHL:
Scott Michel67224b22008-06-02 22:18:03 +00002698 case ISD::SRA: {
Scott Michel97872d32008-02-23 18:41:37 +00002699 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002700 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel97872d32008-02-23 18:41:37 +00002701 break;
Scott Michel67224b22008-06-02 22:18:03 +00002702 }
Scott Michel8efdca42007-12-04 22:23:35 +00002703
pingbak2f387e82009-01-26 03:31:40 +00002704 case ISD::FP_TO_SINT:
2705 case ISD::FP_TO_UINT:
2706 return LowerFP_TO_INT(Op, DAG, *this);
2707
2708 case ISD::SINT_TO_FP:
2709 case ISD::UINT_TO_FP:
2710 return LowerINT_TO_FP(Op, DAG, *this);
Scott Michel8c67fa42009-01-21 04:58:48 +00002711
Scott Michel8efdca42007-12-04 22:23:35 +00002712 // Vector-related lowering.
2713 case ISD::BUILD_VECTOR:
pingbak2f387e82009-01-26 03:31:40 +00002714 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002715 case ISD::SCALAR_TO_VECTOR:
2716 return LowerSCALAR_TO_VECTOR(Op, DAG);
2717 case ISD::VECTOR_SHUFFLE:
2718 return LowerVECTOR_SHUFFLE(Op, DAG);
2719 case ISD::EXTRACT_VECTOR_ELT:
2720 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2721 case ISD::INSERT_VECTOR_ELT:
2722 return LowerINSERT_VECTOR_ELT(Op, DAG);
2723
2724 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2725 case ISD::AND:
2726 case ISD::OR:
2727 case ISD::XOR:
2728 return LowerByteImmed(Op, DAG);
2729
2730 // Vector and i8 multiply:
2731 case ISD::MUL:
Scott Michel4d07fb72008-12-30 23:28:25 +00002732 if (VT == MVT::i8)
Scott Michel06eabde2008-12-27 04:51:36 +00002733 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel8efdca42007-12-04 22:23:35 +00002734
Scott Michel8efdca42007-12-04 22:23:35 +00002735 case ISD::CTPOP:
2736 return LowerCTPOP(Op, DAG);
Scott Michel56a125e2008-11-22 23:50:42 +00002737
2738 case ISD::SELECT_CC:
Scott Michel06eabde2008-12-27 04:51:36 +00002739 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelec8c82e2008-12-02 19:53:53 +00002740
Scott Michel8c67fa42009-01-21 04:58:48 +00002741 case ISD::SETCC:
2742 return LowerSETCC(Op, DAG, *this);
2743
Scott Michelec8c82e2008-12-02 19:53:53 +00002744 case ISD::TRUNCATE:
2745 return LowerTRUNCATE(Op, DAG);
Scott Michel8efdca42007-12-04 22:23:35 +00002746 }
2747
Dan Gohman8181bd12008-07-27 21:46:04 +00002748 return SDValue();
Scott Michel8efdca42007-12-04 22:23:35 +00002749}
2750
Duncan Sands7d9834b2008-12-01 11:39:25 +00002751void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2752 SmallVectorImpl<SDValue>&Results,
2753 SelectionDAG &DAG)
Scott Michel6e2d68b2008-11-10 23:43:06 +00002754{
2755#if 0
2756 unsigned Opc = (unsigned) N->getOpcode();
2757 MVT OpVT = N->getValueType(0);
2758
2759 switch (Opc) {
2760 default: {
2761 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2762 cerr << "Op.getOpcode() = " << Opc << "\n";
2763 cerr << "*Op.getNode():\n";
2764 N->dump();
2765 abort();
2766 /*NOTREACHED*/
2767 }
2768 }
2769#endif
2770
2771 /* Otherwise, return unchanged */
Scott Michel6e2d68b2008-11-10 23:43:06 +00002772}
2773
Scott Michel8efdca42007-12-04 22:23:35 +00002774//===----------------------------------------------------------------------===//
Scott Michel8efdca42007-12-04 22:23:35 +00002775// Target Optimization Hooks
2776//===----------------------------------------------------------------------===//
2777
Dan Gohman8181bd12008-07-27 21:46:04 +00002778SDValue
Scott Michel8efdca42007-12-04 22:23:35 +00002779SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2780{
2781#if 0
2782 TargetMachine &TM = getTargetMachine();
Scott Michelf9f42e62008-01-29 02:16:57 +00002783#endif
2784 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel8efdca42007-12-04 22:23:35 +00002785 SelectionDAG &DAG = DCI.DAG;
Scott Michel0718cd82008-12-01 17:56:02 +00002786 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2787 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michel06eabde2008-12-27 04:51:36 +00002788 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel0718cd82008-12-01 17:56:02 +00002789 SDValue Result; // Initially, empty result
Scott Michel8efdca42007-12-04 22:23:35 +00002790
2791 switch (N->getOpcode()) {
2792 default: break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002793 case ISD::ADD: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002794 SDValue Op1 = N->getOperand(1);
Scott Michelf9f42e62008-01-29 02:16:57 +00002795
Scott Michel06eabde2008-12-27 04:51:36 +00002796 if (Op0.getOpcode() == SPUISD::IndirectAddr
2797 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2798 // Normalize the operands to reduce repeated code
2799 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michelae5cbf52008-12-29 03:23:36 +00002800
Scott Michel06eabde2008-12-27 04:51:36 +00002801 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2802 IndirectArg = Op1;
2803 AddArg = Op0;
2804 }
2805
2806 if (isa<ConstantSDNode>(AddArg)) {
2807 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2808 SDValue IndOp1 = IndirectArg.getOperand(1);
2809
2810 if (CN0->isNullValue()) {
2811 // (add (SPUindirect <arg>, <arg>), 0) ->
2812 // (SPUindirect <arg>, <arg>)
Scott Michelf9f42e62008-01-29 02:16:57 +00002813
Scott Michel8c2746e2008-12-04 17:16:59 +00002814#if !defined(NDEBUG)
Scott Michel06eabde2008-12-27 04:51:36 +00002815 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002816 cerr << "\n"
Scott Michel06eabde2008-12-27 04:51:36 +00002817 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2818 << "With: (SPUindirect <arg>, <arg>)\n";
2819 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002820#endif
2821
Scott Michel06eabde2008-12-27 04:51:36 +00002822 return IndirectArg;
2823 } else if (isa<ConstantSDNode>(IndOp1)) {
2824 // (add (SPUindirect <arg>, <const>), <const>) ->
2825 // (SPUindirect <arg>, <const + const>)
2826 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2827 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2828 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michelf9f42e62008-01-29 02:16:57 +00002829
Scott Michel06eabde2008-12-27 04:51:36 +00002830#if !defined(NDEBUG)
2831 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2832 cerr << "\n"
2833 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2834 << "), " << CN0->getSExtValue() << ")\n"
2835 << "With: (SPUindirect <arg>, "
2836 << combinedConst << ")\n";
2837 }
2838#endif
Scott Michelf9f42e62008-01-29 02:16:57 +00002839
Scott Michel06eabde2008-12-27 04:51:36 +00002840 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2841 IndirectArg, combinedValue);
2842 }
Scott Michelf9f42e62008-01-29 02:16:57 +00002843 }
2844 }
Scott Michel97872d32008-02-23 18:41:37 +00002845 break;
2846 }
2847 case ISD::SIGN_EXTEND:
2848 case ISD::ZERO_EXTEND:
2849 case ISD::ANY_EXTEND: {
Scott Michel0718cd82008-12-01 17:56:02 +00002850 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michel97872d32008-02-23 18:41:37 +00002851 // (any_extend (SPUextract_elt0 <arg>)) ->
2852 // (SPUextract_elt0 <arg>)
2853 // Types must match, however...
Scott Michel8c2746e2008-12-04 17:16:59 +00002854#if !defined(NDEBUG)
2855 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel6ccefab2008-12-04 03:02:42 +00002856 cerr << "\nReplace: ";
2857 N->dump(&DAG);
2858 cerr << "\nWith: ";
2859 Op0.getNode()->dump(&DAG);
2860 cerr << "\n";
Scott Michel8c2746e2008-12-04 17:16:59 +00002861 }
Scott Michel6ccefab2008-12-04 03:02:42 +00002862#endif
Scott Michel97872d32008-02-23 18:41:37 +00002863
2864 return Op0;
2865 }
2866 break;
2867 }
2868 case SPUISD::IndirectAddr: {
2869 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
Scott Michel8c67fa42009-01-21 04:58:48 +00002870 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2871 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michel97872d32008-02-23 18:41:37 +00002872 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2873 // (SPUaform <addr>, 0)
2874
2875 DEBUG(cerr << "Replace: ");
2876 DEBUG(N->dump(&DAG));
2877 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002878 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002879 DEBUG(cerr << "\n");
2880
2881 return Op0;
2882 }
Scott Michel06eabde2008-12-27 04:51:36 +00002883 } else if (Op0.getOpcode() == ISD::ADD) {
2884 SDValue Op1 = N->getOperand(1);
2885 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2886 // (SPUindirect (add <arg>, <arg>), 0) ->
2887 // (SPUindirect <arg>, <arg>)
2888 if (CN1->isNullValue()) {
2889
2890#if !defined(NDEBUG)
2891 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2892 cerr << "\n"
2893 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2894 << "With: (SPUindirect <arg>, <arg>)\n";
2895 }
2896#endif
2897
2898 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2899 Op0.getOperand(0), Op0.getOperand(1));
2900 }
2901 }
Scott Michel97872d32008-02-23 18:41:37 +00002902 }
2903 break;
2904 }
2905 case SPUISD::SHLQUAD_L_BITS:
2906 case SPUISD::SHLQUAD_L_BYTES:
2907 case SPUISD::VEC_SHL:
2908 case SPUISD::VEC_SRL:
2909 case SPUISD::VEC_SRA:
Scott Michel06eabde2008-12-27 04:51:36 +00002910 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman8181bd12008-07-27 21:46:04 +00002911 SDValue Op1 = N->getOperand(1);
Scott Michel97872d32008-02-23 18:41:37 +00002912
Scott Michel06eabde2008-12-27 04:51:36 +00002913 // Kill degenerate vector shifts:
2914 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2915 if (CN->isNullValue()) {
Scott Michel97872d32008-02-23 18:41:37 +00002916 Result = Op0;
2917 }
2918 }
2919 break;
2920 }
Scott Michel06eabde2008-12-27 04:51:36 +00002921 case SPUISD::PREFSLOT2VEC: {
Scott Michel97872d32008-02-23 18:41:37 +00002922 switch (Op0.getOpcode()) {
2923 default:
2924 break;
2925 case ISD::ANY_EXTEND:
2926 case ISD::ZERO_EXTEND:
2927 case ISD::SIGN_EXTEND: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002928 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michel97872d32008-02-23 18:41:37 +00002929 // <arg>
Scott Michelae5cbf52008-12-29 03:23:36 +00002930 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman8181bd12008-07-27 21:46:04 +00002931 SDValue Op00 = Op0.getOperand(0);
Scott Michelc630c412008-11-24 17:11:17 +00002932 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman8181bd12008-07-27 21:46:04 +00002933 SDValue Op000 = Op00.getOperand(0);
Scott Michel0718cd82008-12-01 17:56:02 +00002934 if (Op000.getValueType() == NodeVT) {
Scott Michel97872d32008-02-23 18:41:37 +00002935 Result = Op000;
2936 }
2937 }
2938 break;
2939 }
Scott Michelc630c412008-11-24 17:11:17 +00002940 case SPUISD::VEC2PREFSLOT: {
Scott Michelae5cbf52008-12-29 03:23:36 +00002941 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michel97872d32008-02-23 18:41:37 +00002942 // <arg>
2943 Result = Op0.getOperand(0);
2944 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00002945 }
Scott Michel97872d32008-02-23 18:41:37 +00002946 }
2947 break;
Scott Michelf9f42e62008-01-29 02:16:57 +00002948 }
2949 }
Scott Michel8c67fa42009-01-21 04:58:48 +00002950
Scott Michel394e26d2008-01-17 20:38:41 +00002951 // Otherwise, return unchanged.
Scott Michel0718cd82008-12-01 17:56:02 +00002952#ifndef NDEBUG
Gabor Greif1c80d112008-08-28 21:40:38 +00002953 if (Result.getNode()) {
Scott Michel97872d32008-02-23 18:41:37 +00002954 DEBUG(cerr << "\nReplace.SPU: ");
2955 DEBUG(N->dump(&DAG));
2956 DEBUG(cerr << "\nWith: ");
Gabor Greif1c80d112008-08-28 21:40:38 +00002957 DEBUG(Result.getNode()->dump(&DAG));
Scott Michel97872d32008-02-23 18:41:37 +00002958 DEBUG(cerr << "\n");
2959 }
2960#endif
2961
2962 return Result;
Scott Michel8efdca42007-12-04 22:23:35 +00002963}
2964
2965//===----------------------------------------------------------------------===//
2966// Inline Assembly Support
2967//===----------------------------------------------------------------------===//
2968
2969/// getConstraintType - Given a constraint letter, return the type of
2970/// constraint it is for this target.
Scott Michel4ec722e2008-07-16 17:17:29 +00002971SPUTargetLowering::ConstraintType
Scott Michel8efdca42007-12-04 22:23:35 +00002972SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2973 if (ConstraintLetter.size() == 1) {
2974 switch (ConstraintLetter[0]) {
2975 default: break;
2976 case 'b':
2977 case 'r':
2978 case 'f':
2979 case 'v':
2980 case 'y':
2981 return C_RegisterClass;
Scott Michel4ec722e2008-07-16 17:17:29 +00002982 }
Scott Michel8efdca42007-12-04 22:23:35 +00002983 }
2984 return TargetLowering::getConstraintType(ConstraintLetter);
2985}
2986
Scott Michel4ec722e2008-07-16 17:17:29 +00002987std::pair<unsigned, const TargetRegisterClass*>
Scott Michel8efdca42007-12-04 22:23:35 +00002988SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands92c43912008-06-06 12:08:01 +00002989 MVT VT) const
Scott Michel8efdca42007-12-04 22:23:35 +00002990{
2991 if (Constraint.size() == 1) {
2992 // GCC RS6000 Constraint Letters
2993 switch (Constraint[0]) {
2994 case 'b': // R1-R31
2995 case 'r': // R0-R31
2996 if (VT == MVT::i64)
2997 return std::make_pair(0U, SPU::R64CRegisterClass);
2998 return std::make_pair(0U, SPU::R32CRegisterClass);
2999 case 'f':
3000 if (VT == MVT::f32)
3001 return std::make_pair(0U, SPU::R32FPRegisterClass);
3002 else if (VT == MVT::f64)
3003 return std::make_pair(0U, SPU::R64FPRegisterClass);
3004 break;
Scott Michel4ec722e2008-07-16 17:17:29 +00003005 case 'v':
Scott Michel8efdca42007-12-04 22:23:35 +00003006 return std::make_pair(0U, SPU::GPRCRegisterClass);
3007 }
3008 }
Scott Michel4ec722e2008-07-16 17:17:29 +00003009
Scott Michel8efdca42007-12-04 22:23:35 +00003010 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
3011}
3012
Scott Michel97872d32008-02-23 18:41:37 +00003013//! Compute used/known bits for a SPU operand
Scott Michel8efdca42007-12-04 22:23:35 +00003014void
Dan Gohman8181bd12008-07-27 21:46:04 +00003015SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohmand0dfc772008-02-13 22:28:48 +00003016 const APInt &Mask,
Scott Michel4ec722e2008-07-16 17:17:29 +00003017 APInt &KnownZero,
Dan Gohman229fa052008-02-13 00:35:47 +00003018 APInt &KnownOne,
Scott Michel5a6f17b2008-01-30 02:55:46 +00003019 const SelectionDAG &DAG,
3020 unsigned Depth ) const {
Scott Michelbc5fbc12008-04-30 00:30:08 +00003021#if 0
Scott Michel97872d32008-02-23 18:41:37 +00003022 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
3023
3024 switch (Op.getOpcode()) {
3025 default:
3026 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
3027 break;
Scott Michel97872d32008-02-23 18:41:37 +00003028 case CALL:
3029 case SHUFB:
Scott Michel56a125e2008-11-22 23:50:42 +00003030 case SHUFFLE_MASK:
Scott Michel97872d32008-02-23 18:41:37 +00003031 case CNTB:
Scott Michel8c67fa42009-01-21 04:58:48 +00003032 case SPUISD::PREFSLOT2VEC:
Scott Michel97872d32008-02-23 18:41:37 +00003033 case SPUISD::LDRESULT:
Scott Michel8c67fa42009-01-21 04:58:48 +00003034 case SPUISD::VEC2PREFSLOT:
Scott Michelbc5fbc12008-04-30 00:30:08 +00003035 case SPUISD::SHLQUAD_L_BITS:
3036 case SPUISD::SHLQUAD_L_BYTES:
3037 case SPUISD::VEC_SHL:
3038 case SPUISD::VEC_SRL:
3039 case SPUISD::VEC_SRA:
3040 case SPUISD::VEC_ROTL:
3041 case SPUISD::VEC_ROTR:
Scott Michelbc5fbc12008-04-30 00:30:08 +00003042 case SPUISD::ROTBYTES_LEFT:
Scott Michel67224b22008-06-02 22:18:03 +00003043 case SPUISD::SELECT_MASK:
3044 case SPUISD::SELB:
Scott Michel97872d32008-02-23 18:41:37 +00003045 }
Scott Michel8c67fa42009-01-21 04:58:48 +00003046#endif
Scott Michel8efdca42007-12-04 22:23:35 +00003047}
Scott Michel4d07fb72008-12-30 23:28:25 +00003048
Scott Michel06eabde2008-12-27 04:51:36 +00003049unsigned
3050SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
3051 unsigned Depth) const {
3052 switch (Op.getOpcode()) {
3053 default:
3054 return 1;
Scott Michel8efdca42007-12-04 22:23:35 +00003055
Scott Michel06eabde2008-12-27 04:51:36 +00003056 case ISD::SETCC: {
3057 MVT VT = Op.getValueType();
3058
3059 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
3060 VT = MVT::i32;
3061 }
3062 return VT.getSizeInBits();
3063 }
3064 }
3065}
Scott Michelae5cbf52008-12-29 03:23:36 +00003066
Scott Michelbc5fbc12008-04-30 00:30:08 +00003067// LowerAsmOperandForConstraint
3068void
Dan Gohman8181bd12008-07-27 21:46:04 +00003069SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michelbc5fbc12008-04-30 00:30:08 +00003070 char ConstraintLetter,
Evan Cheng7f250d62008-09-24 00:05:32 +00003071 bool hasMemory,
Dan Gohman8181bd12008-07-27 21:46:04 +00003072 std::vector<SDValue> &Ops,
Scott Michelbc5fbc12008-04-30 00:30:08 +00003073 SelectionDAG &DAG) const {
3074 // Default, for the time being, to the base class handler
Evan Cheng7f250d62008-09-24 00:05:32 +00003075 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
3076 Ops, DAG);
Scott Michelbc5fbc12008-04-30 00:30:08 +00003077}
3078
Scott Michel8efdca42007-12-04 22:23:35 +00003079/// isLegalAddressImmediate - Return true if the integer value can be used
3080/// as the offset of the target addressing mode.
Gabor Greife9f7f582008-08-31 15:37:04 +00003081bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3082 const Type *Ty) const {
Scott Michel8efdca42007-12-04 22:23:35 +00003083 // SPU's addresses are 256K:
3084 return (V > -(1 << 18) && V < (1 << 18) - 1);
3085}
3086
3087bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel4ec722e2008-07-16 17:17:29 +00003088 return false;
Scott Michel8efdca42007-12-04 22:23:35 +00003089}
Dan Gohman36322c72008-10-18 02:06:02 +00003090
3091bool
3092SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
3093 // The SPU target isn't yet aware of offsets.
3094 return false;
3095}