blob: 86b233c1ecd1ec2dc339576c7ed89617dd7f17ef [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelLowering.cpp - Cell SPU DAG Lowering Implementation --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SPUTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUISelLowering.h"
16#include "SPUTargetMachine.h"
Scott Michel203b2d62008-04-30 00:30:08 +000017#include "SPUFrameInfo.h"
Scott Michelf0569be2008-12-27 04:51:36 +000018#include "llvm/ADT/APInt.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000019#include "llvm/ADT/VectorExtras.h"
Scott Michelc9c8b2a2009-01-26 03:31:40 +000020#include "llvm/CallingConv.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000021#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000026#include "llvm/CodeGen/SelectionDAG.h"
Scott Michel266bc8f2007-12-04 22:23:35 +000027#include "llvm/Constants.h"
28#include "llvm/Function.h"
29#include "llvm/Intrinsics.h"
30#include "llvm/Support/Debug.h"
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 Sands83ec4b62008-06-06 12:08:01 +000042 //! MVT mapping to useful data for Cell SPU
Scott Michel266bc8f2007-12-04 22:23:35 +000043 struct valtype_map_s {
Scott Michel7a1c9e92008-11-22 23:50:42 +000044 const MVT valtype;
45 const int prefslot_byte;
Scott Michel266bc8f2007-12-04 22:23:35 +000046 };
Scott Michel5af8f0e2008-07-16 17:17:29 +000047
Scott Michel266bc8f2007-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 Sands83ec4b62008-06-06 12:08:01 +000061 const valtype_map_s *getValueTypeMapEntry(MVT VT) {
Scott Michel266bc8f2007-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 Michel7f9ba9b2008-01-30 02:55:46 +000066 retval = valtype_map + i;
67 break;
Scott Michel266bc8f2007-12-04 22:23:35 +000068 }
69 }
70
71#ifndef NDEBUG
72 if (retval == 0) {
73 cerr << "getValueTypeMapEntry returns NULL for "
Duncan Sands83ec4b62008-06-06 12:08:01 +000074 << VT.getMVTString()
Scott Michel7f9ba9b2008-01-30 02:55:46 +000075 << "\n";
Scott Michel266bc8f2007-12-04 22:23:35 +000076 abort();
77 }
78#endif
79
80 return retval;
81 }
Scott Michel94bd57e2009-01-15 04:41:47 +000082
Scott Michelc9c8b2a2009-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,
116 CallingConv::C, false, Callee, Args, DAG);
117
118 return CallInfo.first;
119 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000120}
121
122SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
123 : TargetLowering(TM),
124 SPUTM(TM)
125{
126 // Fold away setcc operations if possible.
127 setPow2DivIsCheap();
128
129 // Use _setjmp/_longjmp instead of setjmp/longjmp.
130 setUseUnderscoreSetJmp(true);
131 setUseUnderscoreLongJmp(true);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000132
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000133 // Set RTLIB libcall names as used by SPU:
134 setLibcallName(RTLIB::DIV_F64, "__fast_divdf3");
135
Scott Michel266bc8f2007-12-04 22:23:35 +0000136 // Set up the SPU's register classes:
Scott Michel504c3692007-12-17 22:32:34 +0000137 addRegisterClass(MVT::i8, SPU::R8CRegisterClass);
138 addRegisterClass(MVT::i16, SPU::R16CRegisterClass);
139 addRegisterClass(MVT::i32, SPU::R32CRegisterClass);
140 addRegisterClass(MVT::i64, SPU::R64CRegisterClass);
141 addRegisterClass(MVT::f32, SPU::R32FPRegisterClass);
142 addRegisterClass(MVT::f64, SPU::R64FPRegisterClass);
Scott Michel266bc8f2007-12-04 22:23:35 +0000143 addRegisterClass(MVT::i128, SPU::GPRCRegisterClass);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000144
Scott Michel266bc8f2007-12-04 22:23:35 +0000145 // SPU has no sign or zero extended loads for i1, i8, i16:
Evan Cheng03294662008-10-14 21:26:46 +0000146 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
147 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
148 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000149
Scott Michelf0569be2008-12-27 04:51:36 +0000150 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
151 setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
Scott Michelb30e8f62008-12-02 19:53:53 +0000152
Scott Michel266bc8f2007-12-04 22:23:35 +0000153 // SPU constant load actions are custom lowered:
Nate Begemanccef5802008-02-14 18:43:04 +0000154 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000155 setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
156
157 // SPU's loads and stores have to be custom lowered:
Scott Micheldd950092009-01-06 03:36:14 +0000158 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
Scott Michel266bc8f2007-12-04 22:23:35 +0000159 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000160 MVT VT = (MVT::SimpleValueType)sctype;
161
Scott Michelf0569be2008-12-27 04:51:36 +0000162 setOperationAction(ISD::LOAD, VT, Custom);
163 setOperationAction(ISD::STORE, VT, Custom);
164 setLoadExtAction(ISD::EXTLOAD, VT, Custom);
165 setLoadExtAction(ISD::ZEXTLOAD, VT, Custom);
166 setLoadExtAction(ISD::SEXTLOAD, VT, Custom);
167
168 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) {
169 MVT StoreVT = (MVT::SimpleValueType) stype;
170 setTruncStoreAction(VT, StoreVT, Expand);
171 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000172 }
173
Scott Michelf0569be2008-12-27 04:51:36 +0000174 for (unsigned sctype = (unsigned) MVT::f32; sctype < (unsigned) MVT::f64;
175 ++sctype) {
176 MVT VT = (MVT::SimpleValueType) sctype;
177
178 setOperationAction(ISD::LOAD, VT, Custom);
179 setOperationAction(ISD::STORE, VT, Custom);
180
181 for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::f32; --stype) {
182 MVT StoreVT = (MVT::SimpleValueType) stype;
183 setTruncStoreAction(VT, StoreVT, Expand);
184 }
185 }
186
Scott Michel266bc8f2007-12-04 22:23:35 +0000187 // Expand the jumptable branches
188 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
189 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000190
191 // Custom lower SELECT_CC for most cases, but expand by default
Scott Michel5af8f0e2008-07-16 17:17:29 +0000192 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
Scott Michel7a1c9e92008-11-22 23:50:42 +0000193 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
194 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
195 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
196 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000197
198 // SPU has no intrinsics for these particular operations:
Andrew Lenharthd497d9f2008-02-16 14:46:26 +0000199 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
200
Scott Michelf0569be2008-12-27 04:51:36 +0000201 // SPU has no SREM/UREM instructions
Scott Michel266bc8f2007-12-04 22:23:35 +0000202 setOperationAction(ISD::SREM, MVT::i32, Expand);
203 setOperationAction(ISD::UREM, MVT::i32, Expand);
204 setOperationAction(ISD::SREM, MVT::i64, Expand);
205 setOperationAction(ISD::UREM, MVT::i64, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000206
Scott Michel266bc8f2007-12-04 22:23:35 +0000207 // We don't support sin/cos/sqrt/fmod
208 setOperationAction(ISD::FSIN , MVT::f64, Expand);
209 setOperationAction(ISD::FCOS , MVT::f64, Expand);
210 setOperationAction(ISD::FREM , MVT::f64, Expand);
211 setOperationAction(ISD::FSIN , MVT::f32, Expand);
212 setOperationAction(ISD::FCOS , MVT::f32, Expand);
213 setOperationAction(ISD::FREM , MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000214
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000215 // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt
216 // for f32!)
Scott Michel266bc8f2007-12-04 22:23:35 +0000217 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
218 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000219
Scott Michel266bc8f2007-12-04 22:23:35 +0000220 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
221 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
222
223 // SPU can do rotate right and left, so legalize it... but customize for i8
224 // because instructions don't exist.
Bill Wendling9440e352008-08-31 02:59:23 +0000225
226 // FIXME: Change from "expand" to appropriate type once ROTR is supported in
227 // .td files.
228 setOperationAction(ISD::ROTR, MVT::i32, Expand /*Legal*/);
229 setOperationAction(ISD::ROTR, MVT::i16, Expand /*Legal*/);
230 setOperationAction(ISD::ROTR, MVT::i8, Expand /*Custom*/);
231
Scott Michel266bc8f2007-12-04 22:23:35 +0000232 setOperationAction(ISD::ROTL, MVT::i32, Legal);
233 setOperationAction(ISD::ROTL, MVT::i16, Legal);
234 setOperationAction(ISD::ROTL, MVT::i8, Custom);
Scott Micheldc91bea2008-11-20 16:36:33 +0000235
Scott Michel266bc8f2007-12-04 22:23:35 +0000236 // SPU has no native version of shift left/right for i8
237 setOperationAction(ISD::SHL, MVT::i8, Custom);
238 setOperationAction(ISD::SRL, MVT::i8, Custom);
239 setOperationAction(ISD::SRA, MVT::i8, Custom);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000240
Scott Michel02d711b2008-12-30 23:28:25 +0000241 // Make these operations legal and handle them during instruction selection:
242 setOperationAction(ISD::SHL, MVT::i64, Legal);
243 setOperationAction(ISD::SRL, MVT::i64, Legal);
244 setOperationAction(ISD::SRA, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000245
Scott Michel5af8f0e2008-07-16 17:17:29 +0000246 // Custom lower i8, i32 and i64 multiplications
247 setOperationAction(ISD::MUL, MVT::i8, Custom);
Scott Michel1df30c42008-12-29 03:23:36 +0000248 setOperationAction(ISD::MUL, MVT::i32, Legal);
Scott Michel94bd57e2009-01-15 04:41:47 +0000249 setOperationAction(ISD::MUL, MVT::i64, Legal);
Scott Michel9c0c6b22008-11-21 02:56:16 +0000250
Scott Michel8bf61e82008-06-02 22:18:03 +0000251 // Need to custom handle (some) common i8, i64 math ops
Scott Michel02d711b2008-12-30 23:28:25 +0000252 setOperationAction(ISD::ADD, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000253 setOperationAction(ISD::ADD, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000254 setOperationAction(ISD::SUB, MVT::i8, Custom);
Scott Michel94bd57e2009-01-15 04:41:47 +0000255 setOperationAction(ISD::SUB, MVT::i64, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000256
Scott Michel266bc8f2007-12-04 22:23:35 +0000257 // SPU does not have BSWAP. It does have i32 support CTLZ.
258 // CTPOP has to be custom lowered.
259 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
260 setOperationAction(ISD::BSWAP, MVT::i64, Expand);
261
262 setOperationAction(ISD::CTPOP, MVT::i8, Custom);
263 setOperationAction(ISD::CTPOP, MVT::i16, Custom);
264 setOperationAction(ISD::CTPOP, MVT::i32, Custom);
265 setOperationAction(ISD::CTPOP, MVT::i64, Custom);
266
267 setOperationAction(ISD::CTTZ , MVT::i32, Expand);
268 setOperationAction(ISD::CTTZ , MVT::i64, Expand);
269
270 setOperationAction(ISD::CTLZ , MVT::i32, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000271
Scott Michel8bf61e82008-06-02 22:18:03 +0000272 // SPU has a version of select that implements (a&~c)|(b&c), just like
Scott Michel405fba12008-03-10 23:49:09 +0000273 // select ought to work:
Scott Michel78c47fa2008-03-10 16:58:52 +0000274 setOperationAction(ISD::SELECT, MVT::i8, Legal);
Scott Michelad2715e2008-03-05 23:02:02 +0000275 setOperationAction(ISD::SELECT, MVT::i16, Legal);
276 setOperationAction(ISD::SELECT, MVT::i32, Legal);
Scott Michelf0569be2008-12-27 04:51:36 +0000277 setOperationAction(ISD::SELECT, MVT::i64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000278
Scott Michel78c47fa2008-03-10 16:58:52 +0000279 setOperationAction(ISD::SETCC, MVT::i8, Legal);
280 setOperationAction(ISD::SETCC, MVT::i16, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000281 setOperationAction(ISD::SETCC, MVT::i32, Legal);
282 setOperationAction(ISD::SETCC, MVT::i64, Legal);
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000283 setOperationAction(ISD::SETCC, MVT::f64, Custom);
Scott Michelad2715e2008-03-05 23:02:02 +0000284
Scott Michelf0569be2008-12-27 04:51:36 +0000285 // Custom lower i128 -> i64 truncates
Scott Michelb30e8f62008-12-02 19:53:53 +0000286 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
287
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000288 // SPU has a legal FP -> signed INT instruction for f32, but for f64, need
289 // to expand to a libcall, hence the custom lowering:
290 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
291 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000292
293 // FDIV on SPU requires custom lowering
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000294 setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
Scott Michel266bc8f2007-12-04 22:23:35 +0000295
Scott Michel9de57a92009-01-26 22:33:37 +0000296 // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000297 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000298 setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000299 setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
300 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000301 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote);
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000302 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +0000303 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
304 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
305
Scott Michel86c041f2007-12-20 00:44:13 +0000306 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Legal);
307 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Legal);
308 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Legal);
309 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Legal);
Scott Michel266bc8f2007-12-04 22:23:35 +0000310
311 // We cannot sextinreg(i1). Expand to shifts.
312 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000313
Scott Michel266bc8f2007-12-04 22:23:35 +0000314 // Support label based line numbers.
Dan Gohman7f460202008-06-30 20:59:49 +0000315 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000316 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000317
318 // We want to legalize GlobalAddress and ConstantPool nodes into the
Scott Michel266bc8f2007-12-04 22:23:35 +0000319 // appropriate instructions to materialize the address.
Scott Michel9c0c6b22008-11-21 02:56:16 +0000320 for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
Scott Michel053c1da2008-01-29 02:16:57 +0000321 ++sctype) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000322 MVT VT = (MVT::SimpleValueType)sctype;
323
Scott Michel1df30c42008-12-29 03:23:36 +0000324 setOperationAction(ISD::GlobalAddress, VT, Custom);
325 setOperationAction(ISD::ConstantPool, VT, Custom);
326 setOperationAction(ISD::JumpTable, VT, Custom);
Scott Michel053c1da2008-01-29 02:16:57 +0000327 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000328
329 // RET must be custom lowered, to meet ABI requirements
330 setOperationAction(ISD::RET, MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000331
Scott Michel266bc8f2007-12-04 22:23:35 +0000332 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
333 setOperationAction(ISD::VASTART , MVT::Other, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000334
Scott Michel266bc8f2007-12-04 22:23:35 +0000335 // Use the default implementation.
336 setOperationAction(ISD::VAARG , MVT::Other, Expand);
337 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
338 setOperationAction(ISD::VAEND , MVT::Other, Expand);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000339 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000340 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
341 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
342 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
343
344 // Cell SPU has instructions for converting between i64 and fp.
345 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
346 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000347
Scott Michel266bc8f2007-12-04 22:23:35 +0000348 // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
349 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
350
351 // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
352 setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
353
354 // First set operation action for all vector types to expand. Then we
355 // will selectively turn on ones that can be effectively codegen'd.
356 addRegisterClass(MVT::v16i8, SPU::VECREGRegisterClass);
357 addRegisterClass(MVT::v8i16, SPU::VECREGRegisterClass);
358 addRegisterClass(MVT::v4i32, SPU::VECREGRegisterClass);
359 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
360 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
361 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
362
Scott Michel21213e72009-01-06 23:10:38 +0000363 // "Odd size" vector classes that we're willing to support:
364 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
365
Duncan Sands83ec4b62008-06-06 12:08:01 +0000366 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
367 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
368 MVT VT = (MVT::SimpleValueType)i;
Scott Michel266bc8f2007-12-04 22:23:35 +0000369
Duncan Sands83ec4b62008-06-06 12:08:01 +0000370 // add/sub are legal for all supported vector VT's.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000371 setOperationAction(ISD::ADD, VT, Legal);
372 setOperationAction(ISD::SUB, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000373 // mul has to be custom lowered.
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000374 setOperationAction(ISD::MUL, VT, Legal);
Duncan Sands83ec4b62008-06-06 12:08:01 +0000375
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000376 setOperationAction(ISD::AND, VT, Legal);
377 setOperationAction(ISD::OR, VT, Legal);
378 setOperationAction(ISD::XOR, VT, Legal);
379 setOperationAction(ISD::LOAD, VT, Legal);
380 setOperationAction(ISD::SELECT, VT, Legal);
381 setOperationAction(ISD::STORE, VT, Legal);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000382
Scott Michel266bc8f2007-12-04 22:23:35 +0000383 // These operations need to be expanded:
Scott Michelc9c8b2a2009-01-26 03:31:40 +0000384 setOperationAction(ISD::SDIV, VT, Expand);
385 setOperationAction(ISD::SREM, VT, Expand);
386 setOperationAction(ISD::UDIV, VT, Expand);
387 setOperationAction(ISD::UREM, VT, Expand);
Scott Michel266bc8f2007-12-04 22:23:35 +0000388
389 // Custom lower build_vector, constant pool spills, insert and
390 // extract vector elements:
Duncan Sands83ec4b62008-06-06 12:08:01 +0000391 setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
392 setOperationAction(ISD::ConstantPool, VT, Custom);
393 setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
394 setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
395 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
396 setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
Scott Michel266bc8f2007-12-04 22:23:35 +0000397 }
398
Scott Michel266bc8f2007-12-04 22:23:35 +0000399 setOperationAction(ISD::AND, MVT::v16i8, Custom);
400 setOperationAction(ISD::OR, MVT::v16i8, Custom);
401 setOperationAction(ISD::XOR, MVT::v16i8, Custom);
402 setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000403
Scott Michel02d711b2008-12-30 23:28:25 +0000404 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
Scott Michel1df30c42008-12-29 03:23:36 +0000405
Scott Michel266bc8f2007-12-04 22:23:35 +0000406 setShiftAmountType(MVT::i32);
Scott Michelf0569be2008-12-27 04:51:36 +0000407 setBooleanContents(ZeroOrNegativeOneBooleanContent);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000408
Scott Michel266bc8f2007-12-04 22:23:35 +0000409 setStackPointerRegisterToSaveRestore(SPU::R1);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000410
Scott Michel266bc8f2007-12-04 22:23:35 +0000411 // We have target-specific dag combine patterns for the following nodes:
Scott Michel053c1da2008-01-29 02:16:57 +0000412 setTargetDAGCombine(ISD::ADD);
Scott Michela59d4692008-02-23 18:41:37 +0000413 setTargetDAGCombine(ISD::ZERO_EXTEND);
414 setTargetDAGCombine(ISD::SIGN_EXTEND);
415 setTargetDAGCombine(ISD::ANY_EXTEND);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000416
Scott Michel266bc8f2007-12-04 22:23:35 +0000417 computeRegisterProperties();
Scott Michel7a1c9e92008-11-22 23:50:42 +0000418
Scott Michele07d3de2008-12-09 03:37:19 +0000419 // Set pre-RA register scheduler default to BURR, which produces slightly
420 // better code than the default (could also be TDRR, but TargetLowering.h
421 // needs a mod to support that model):
422 setSchedulingPreference(SchedulingForRegPressure);
Scott Michel266bc8f2007-12-04 22:23:35 +0000423}
424
425const char *
426SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
427{
428 if (node_names.empty()) {
429 node_names[(unsigned) SPUISD::RET_FLAG] = "SPUISD::RET_FLAG";
430 node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
431 node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
432 node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
Scott Michel9de5d0d2008-01-11 02:53:15 +0000433 node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
Scott Michel053c1da2008-01-29 02:16:57 +0000434 node_names[(unsigned) SPUISD::IndirectAddr] = "SPUISD::IndirectAddr";
Scott Michel266bc8f2007-12-04 22:23:35 +0000435 node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
436 node_names[(unsigned) SPUISD::CALL] = "SPUISD::CALL";
437 node_names[(unsigned) SPUISD::SHUFB] = "SPUISD::SHUFB";
Scott Michel7a1c9e92008-11-22 23:50:42 +0000438 node_names[(unsigned) SPUISD::SHUFFLE_MASK] = "SPUISD::SHUFFLE_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000439 node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB";
Scott Michel1df30c42008-12-29 03:23:36 +0000440 node_names[(unsigned) SPUISD::PREFSLOT2VEC] = "SPUISD::PREFSLOT2VEC";
Scott Michel104de432008-11-24 17:11:17 +0000441 node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT";
Scott Michela59d4692008-02-23 18:41:37 +0000442 node_names[(unsigned) SPUISD::SHLQUAD_L_BITS] = "SPUISD::SHLQUAD_L_BITS";
443 node_names[(unsigned) SPUISD::SHLQUAD_L_BYTES] = "SPUISD::SHLQUAD_L_BYTES";
Scott Michel266bc8f2007-12-04 22:23:35 +0000444 node_names[(unsigned) SPUISD::VEC_SHL] = "SPUISD::VEC_SHL";
445 node_names[(unsigned) SPUISD::VEC_SRL] = "SPUISD::VEC_SRL";
446 node_names[(unsigned) SPUISD::VEC_SRA] = "SPUISD::VEC_SRA";
447 node_names[(unsigned) SPUISD::VEC_ROTL] = "SPUISD::VEC_ROTL";
448 node_names[(unsigned) SPUISD::VEC_ROTR] = "SPUISD::VEC_ROTR";
Scott Micheld1e8d9c2009-01-21 04:58:48 +0000449 node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT";
450 node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] =
451 "SPUISD::ROTBYTES_LEFT_BITS";
Scott Michel8bf61e82008-06-02 22:18:03 +0000452 node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK";
Scott Michel266bc8f2007-12-04 22:23:35 +0000453 node_names[(unsigned) SPUISD::SELB] = "SPUISD::SELB";
Scott Michel94bd57e2009-01-15 04:41:47 +0000454 node_names[(unsigned) SPUISD::ADD64_MARKER] = "SPUISD::ADD64_MARKER";
455 node_names[(unsigned) SPUISD::SUB64_MARKER] = "SPUISD::SUB64_MARKER";
456 node_names[(unsigned) SPUISD::MUL64_MARKER] = "SPUISD::MUL64_MARKER";
Scott Michel266bc8f2007-12-04 22:23:35 +0000457 }
458
459 std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
460
461 return ((i != node_names.end()) ? i->second : 0);
462}
463
Scott Michelf0569be2008-12-27 04:51:36 +0000464//===----------------------------------------------------------------------===//
465// Return the Cell SPU's SETCC result type
466//===----------------------------------------------------------------------===//
467
Duncan Sands5480c042009-01-01 15:52:00 +0000468MVT SPUTargetLowering::getSetCCResultType(MVT VT) const {
Scott Michelf0569be2008-12-27 04:51:36 +0000469 // i16 and i32 are valid SETCC result types
470 return ((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) ? VT : MVT::i32);
Scott Michel78c47fa2008-03-10 16:58:52 +0000471}
472
Scott Michel266bc8f2007-12-04 22:23:35 +0000473//===----------------------------------------------------------------------===//
474// Calling convention code:
475//===----------------------------------------------------------------------===//
476
477#include "SPUGenCallingConv.inc"
478
479//===----------------------------------------------------------------------===//
480// LowerOperation implementation
481//===----------------------------------------------------------------------===//
482
483/// Custom lower loads for CellSPU
484/*!
485 All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
486 within a 16-byte block, we have to rotate to extract the requested element.
Scott Michel30ee7df2008-12-04 03:02:42 +0000487
488 For extending loads, we also want to ensure that the following sequence is
489 emitted, e.g. for MVT::f32 extending load to MVT::f64:
490
491\verbatim
Scott Michel1df30c42008-12-29 03:23:36 +0000492%1 v16i8,ch = load
Scott Michel30ee7df2008-12-04 03:02:42 +0000493%2 v16i8,ch = rotate %1
Scott Michel1df30c42008-12-29 03:23:36 +0000494%3 v4f8, ch = bitconvert %2
Scott Michel30ee7df2008-12-04 03:02:42 +0000495%4 f32 = vec2perfslot %3
496%5 f64 = fp_extend %4
497\endverbatim
498*/
Dan Gohman475871a2008-07-27 21:46:04 +0000499static SDValue
500LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000501 LoadSDNode *LN = cast<LoadSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000502 SDValue the_chain = LN->getChain();
Scott Michelf0569be2008-12-27 04:51:36 +0000503 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel30ee7df2008-12-04 03:02:42 +0000504 MVT InVT = LN->getMemoryVT();
505 MVT OutVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000506 ISD::LoadExtType ExtType = LN->getExtensionType();
507 unsigned alignment = LN->getAlignment();
Scott Michelf0569be2008-12-27 04:51:36 +0000508 const valtype_map_s *vtm = getValueTypeMapEntry(InVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000509
Scott Michel266bc8f2007-12-04 22:23:35 +0000510 switch (LN->getAddressingMode()) {
511 case ISD::UNINDEXED: {
Scott Michelf0569be2008-12-27 04:51:36 +0000512 SDValue result;
513 SDValue basePtr = LN->getBasePtr();
514 SDValue rotate;
Scott Michel266bc8f2007-12-04 22:23:35 +0000515
Scott Michelf0569be2008-12-27 04:51:36 +0000516 if (alignment == 16) {
517 ConstantSDNode *CN;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000518
Scott Michelf0569be2008-12-27 04:51:36 +0000519 // Special cases for a known aligned load to simplify the base pointer
520 // and the rotation amount:
521 if (basePtr.getOpcode() == ISD::ADD
522 && (CN = dyn_cast<ConstantSDNode > (basePtr.getOperand(1))) != 0) {
523 // Known offset into basePtr
524 int64_t offset = CN->getSExtValue();
525 int64_t rotamt = int64_t((offset & 0xf) - vtm->prefslot_byte);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000526
Scott Michelf0569be2008-12-27 04:51:36 +0000527 if (rotamt < 0)
528 rotamt += 16;
529
530 rotate = DAG.getConstant(rotamt, MVT::i16);
531
532 // Simplify the base pointer for this case:
533 basePtr = basePtr.getOperand(0);
534 if ((offset & ~0xf) > 0) {
535 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
536 basePtr,
537 DAG.getConstant((offset & ~0xf), PtrVT));
538 }
539 } else if ((basePtr.getOpcode() == SPUISD::AFormAddr)
540 || (basePtr.getOpcode() == SPUISD::IndirectAddr
541 && basePtr.getOperand(0).getOpcode() == SPUISD::Hi
542 && basePtr.getOperand(1).getOpcode() == SPUISD::Lo)) {
543 // Plain aligned a-form address: rotate into preferred slot
544 // Same for (SPUindirect (SPUhi ...), (SPUlo ...))
545 int64_t rotamt = -vtm->prefslot_byte;
546 if (rotamt < 0)
547 rotamt += 16;
548 rotate = DAG.getConstant(rotamt, MVT::i16);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000549 } else {
Scott Michelf0569be2008-12-27 04:51:36 +0000550 // Offset the rotate amount by the basePtr and the preferred slot
551 // byte offset
552 int64_t rotamt = -vtm->prefslot_byte;
553 if (rotamt < 0)
554 rotamt += 16;
555 rotate = DAG.getNode(ISD::ADD, PtrVT,
556 basePtr,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000557 DAG.getConstant(rotamt, PtrVT));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000558 }
Scott Michelf0569be2008-12-27 04:51:36 +0000559 } else {
560 // Unaligned load: must be more pessimistic about addressing modes:
561 if (basePtr.getOpcode() == ISD::ADD) {
562 MachineFunction &MF = DAG.getMachineFunction();
563 MachineRegisterInfo &RegInfo = MF.getRegInfo();
564 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
565 SDValue Flag;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000566
Scott Michelf0569be2008-12-27 04:51:36 +0000567 SDValue Op0 = basePtr.getOperand(0);
568 SDValue Op1 = basePtr.getOperand(1);
569
570 if (isa<ConstantSDNode>(Op1)) {
571 // Convert the (add <ptr>, <const>) to an indirect address contained
572 // in a register. Note that this is done because we need to avoid
573 // creating a 0(reg) d-form address due to the SPU's block loads.
574 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
575 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
576 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
577 } else {
578 // Convert the (add <arg1>, <arg2>) to an indirect address, which
579 // will likely be lowered as a reg(reg) x-form address.
580 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
581 }
582 } else {
583 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
584 basePtr,
585 DAG.getConstant(0, PtrVT));
586 }
587
588 // Offset the rotate amount by the basePtr and the preferred slot
589 // byte offset
590 rotate = DAG.getNode(ISD::ADD, PtrVT,
591 basePtr,
592 DAG.getConstant(-vtm->prefslot_byte, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +0000593 }
Scott Michel9de5d0d2008-01-11 02:53:15 +0000594
Scott Michelf0569be2008-12-27 04:51:36 +0000595 // Re-emit as a v16i8 vector load
596 result = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
597 LN->getSrcValue(), LN->getSrcValueOffset(),
598 LN->isVolatile(), 16);
599
600 // Update the chain
601 the_chain = result.getValue(1);
602
603 // Rotate into the preferred slot:
604 result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8,
605 result.getValue(0), rotate);
606
Scott Michel30ee7df2008-12-04 03:02:42 +0000607 // Convert the loaded v16i8 vector to the appropriate vector type
608 // specified by the operand:
609 MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits()));
610 result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT,
Scott Michel19c10e62009-01-26 03:37:41 +0000611 DAG.getNode(ISD::BIT_CONVERT, vecVT, result));
Scott Michel5af8f0e2008-07-16 17:17:29 +0000612
Scott Michel30ee7df2008-12-04 03:02:42 +0000613 // Handle extending loads by extending the scalar result:
614 if (ExtType == ISD::SEXTLOAD) {
615 result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result);
616 } else if (ExtType == ISD::ZEXTLOAD) {
617 result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result);
618 } else if (ExtType == ISD::EXTLOAD) {
619 unsigned NewOpc = ISD::ANY_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000620
Scott Michel30ee7df2008-12-04 03:02:42 +0000621 if (OutVT.isFloatingPoint())
Scott Michel19c10e62009-01-26 03:37:41 +0000622 NewOpc = ISD::FP_EXTEND;
Scott Michel9de5d0d2008-01-11 02:53:15 +0000623
Scott Michel30ee7df2008-12-04 03:02:42 +0000624 result = DAG.getNode(NewOpc, OutVT, result);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000625 }
626
Scott Michel30ee7df2008-12-04 03:02:42 +0000627 SDVTList retvts = DAG.getVTList(OutVT, MVT::Other);
Dan Gohman475871a2008-07-27 21:46:04 +0000628 SDValue retops[2] = {
Scott Michel58c58182008-01-17 20:38:41 +0000629 result,
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000630 the_chain
Scott Michel58c58182008-01-17 20:38:41 +0000631 };
Scott Michel9de5d0d2008-01-11 02:53:15 +0000632
Scott Michel58c58182008-01-17 20:38:41 +0000633 result = DAG.getNode(SPUISD::LDRESULT, retvts,
634 retops, sizeof(retops) / sizeof(retops[0]));
Scott Michel9de5d0d2008-01-11 02:53:15 +0000635 return result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000636 }
637 case ISD::PRE_INC:
638 case ISD::PRE_DEC:
639 case ISD::POST_INC:
640 case ISD::POST_DEC:
641 case ISD::LAST_INDEXED_MODE:
642 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
643 "UNINDEXED\n";
644 cerr << (unsigned) LN->getAddressingMode() << "\n";
645 abort();
646 /*NOTREACHED*/
647 }
648
Dan Gohman475871a2008-07-27 21:46:04 +0000649 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000650}
651
652/// Custom lower stores for CellSPU
653/*!
654 All CellSPU stores are aligned to 16-byte boundaries, so for elements
655 within a 16-byte block, we have to generate a shuffle to insert the
656 requested element into its place, then store the resulting block.
657 */
Dan Gohman475871a2008-07-27 21:46:04 +0000658static SDValue
659LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000660 StoreSDNode *SN = cast<StoreSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000661 SDValue Value = SN->getValue();
Duncan Sands83ec4b62008-06-06 12:08:01 +0000662 MVT VT = Value.getValueType();
663 MVT StVT = (!SN->isTruncatingStore() ? VT : SN->getMemoryVT());
664 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel9de5d0d2008-01-11 02:53:15 +0000665 unsigned alignment = SN->getAlignment();
Scott Michel266bc8f2007-12-04 22:23:35 +0000666
667 switch (SN->getAddressingMode()) {
668 case ISD::UNINDEXED: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000669 // The vector type we really want to load from the 16-byte chunk.
Scott Michel719b0e12008-11-19 17:45:08 +0000670 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())),
671 stVecVT = MVT::getVectorVT(StVT, (128 / StVT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +0000672
Scott Michelf0569be2008-12-27 04:51:36 +0000673 SDValue alignLoadVec;
674 SDValue basePtr = SN->getBasePtr();
675 SDValue the_chain = SN->getChain();
676 SDValue insertEltOffs;
Scott Michel266bc8f2007-12-04 22:23:35 +0000677
Scott Michelf0569be2008-12-27 04:51:36 +0000678 if (alignment == 16) {
679 ConstantSDNode *CN;
680
681 // Special cases for a known aligned load to simplify the base pointer
682 // and insertion byte:
683 if (basePtr.getOpcode() == ISD::ADD
684 && (CN = dyn_cast<ConstantSDNode>(basePtr.getOperand(1))) != 0) {
685 // Known offset into basePtr
686 int64_t offset = CN->getSExtValue();
687
688 // Simplify the base pointer for this case:
689 basePtr = basePtr.getOperand(0);
690 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
691 basePtr,
692 DAG.getConstant((offset & 0xf), PtrVT));
693
694 if ((offset & ~0xf) > 0) {
695 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
696 basePtr,
697 DAG.getConstant((offset & ~0xf), PtrVT));
698 }
699 } else {
700 // Otherwise, assume it's at byte 0 of basePtr
701 insertEltOffs = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
702 basePtr,
703 DAG.getConstant(0, PtrVT));
704 }
705 } else {
706 // Unaligned load: must be more pessimistic about addressing modes:
707 if (basePtr.getOpcode() == ISD::ADD) {
708 MachineFunction &MF = DAG.getMachineFunction();
709 MachineRegisterInfo &RegInfo = MF.getRegInfo();
710 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
711 SDValue Flag;
712
713 SDValue Op0 = basePtr.getOperand(0);
714 SDValue Op1 = basePtr.getOperand(1);
715
716 if (isa<ConstantSDNode>(Op1)) {
717 // Convert the (add <ptr>, <const>) to an indirect address contained
718 // in a register. Note that this is done because we need to avoid
719 // creating a 0(reg) d-form address due to the SPU's block loads.
720 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
721 the_chain = DAG.getCopyToReg(the_chain, VReg, basePtr, Flag);
722 basePtr = DAG.getCopyFromReg(the_chain, VReg, PtrVT);
723 } else {
724 // Convert the (add <arg1>, <arg2>) to an indirect address, which
725 // will likely be lowered as a reg(reg) x-form address.
726 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT, Op0, Op1);
727 }
728 } else {
729 basePtr = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
730 basePtr,
731 DAG.getConstant(0, PtrVT));
732 }
733
734 // Insertion point is solely determined by basePtr's contents
735 insertEltOffs = DAG.getNode(ISD::ADD, PtrVT,
736 basePtr,
737 DAG.getConstant(0, PtrVT));
738 }
739
740 // Re-emit as a v16i8 vector load
741 alignLoadVec = DAG.getLoad(MVT::v16i8, the_chain, basePtr,
742 SN->getSrcValue(), SN->getSrcValueOffset(),
743 SN->isVolatile(), 16);
744
745 // Update the chain
746 the_chain = alignLoadVec.getValue(1);
Scott Michel266bc8f2007-12-04 22:23:35 +0000747
Scott Michel9de5d0d2008-01-11 02:53:15 +0000748 LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
Dan Gohman475871a2008-07-27 21:46:04 +0000749 SDValue theValue = SN->getValue();
750 SDValue result;
Scott Michel266bc8f2007-12-04 22:23:35 +0000751
752 if (StVT != VT
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000753 && (theValue.getOpcode() == ISD::AssertZext
754 || theValue.getOpcode() == ISD::AssertSext)) {
Scott Michel266bc8f2007-12-04 22:23:35 +0000755 // Drill down and get the value for zero- and sign-extended
756 // quantities
Scott Michel5af8f0e2008-07-16 17:17:29 +0000757 theValue = theValue.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000758 }
759
Scott Michel9de5d0d2008-01-11 02:53:15 +0000760 // If the base pointer is already a D-form address, then just create
761 // a new D-form address with a slot offset and the orignal base pointer.
762 // Otherwise generate a D-form address with the slot offset relative
763 // to the stack pointer, which is always aligned.
Scott Michelf0569be2008-12-27 04:51:36 +0000764#if !defined(NDEBUG)
765 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
766 cerr << "CellSPU LowerSTORE: basePtr = ";
767 basePtr.getNode()->dump(&DAG);
768 cerr << "\n";
769 }
770#endif
Scott Michel9de5d0d2008-01-11 02:53:15 +0000771
Scott Michel430a5552008-11-19 15:24:16 +0000772 SDValue insertEltOp =
Scott Michelf0569be2008-12-27 04:51:36 +0000773 DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltOffs);
Scott Michel719b0e12008-11-19 17:45:08 +0000774 SDValue vectorizeOp =
775 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue);
Scott Michel430a5552008-11-19 15:24:16 +0000776
Scott Michel1a6cdb62008-12-01 17:56:02 +0000777 result = DAG.getNode(SPUISD::SHUFB, vecVT,
Scott Michel19c10e62009-01-26 03:37:41 +0000778 vectorizeOp, alignLoadVec,
779 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp));
Scott Michel266bc8f2007-12-04 22:23:35 +0000780
Scott Michel9de5d0d2008-01-11 02:53:15 +0000781 result = DAG.getStore(the_chain, result, basePtr,
Scott Michel266bc8f2007-12-04 22:23:35 +0000782 LN->getSrcValue(), LN->getSrcValueOffset(),
783 LN->isVolatile(), LN->getAlignment());
784
Scott Michel23f2ff72008-12-04 17:16:59 +0000785#if 0 && !defined(NDEBUG)
Scott Michel430a5552008-11-19 15:24:16 +0000786 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
787 const SDValue &currentRoot = DAG.getRoot();
788
789 DAG.setRoot(result);
790 cerr << "------- CellSPU:LowerStore result:\n";
791 DAG.dump();
792 cerr << "-------\n";
793 DAG.setRoot(currentRoot);
794 }
795#endif
Scott Michelb30e8f62008-12-02 19:53:53 +0000796
Scott Michel266bc8f2007-12-04 22:23:35 +0000797 return result;
798 /*UNREACHED*/
799 }
800 case ISD::PRE_INC:
801 case ISD::PRE_DEC:
802 case ISD::POST_INC:
803 case ISD::POST_DEC:
804 case ISD::LAST_INDEXED_MODE:
805 cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
806 "UNINDEXED\n";
807 cerr << (unsigned) SN->getAddressingMode() << "\n";
808 abort();
809 /*NOTREACHED*/
810 }
811
Dan Gohman475871a2008-07-27 21:46:04 +0000812 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000813}
814
Scott Michel94bd57e2009-01-15 04:41:47 +0000815//! Generate the address of a constant pool entry.
816SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000817LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000818 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000819 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
820 Constant *C = CP->getConstVal();
Dan Gohman475871a2008-07-27 21:46:04 +0000821 SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
822 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel9de5d0d2008-01-11 02:53:15 +0000823 const TargetMachine &TM = DAG.getTarget();
Scott Michel266bc8f2007-12-04 22:23:35 +0000824
825 if (TM.getRelocationModel() == Reloc::Static) {
826 if (!ST->usingLargeMem()) {
Dan Gohman475871a2008-07-27 21:46:04 +0000827 // Just return the SDValue with the constant pool address in it.
Scott Michel58c58182008-01-17 20:38:41 +0000828 return DAG.getNode(SPUISD::AFormAddr, PtrVT, CPI, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +0000829 } else {
Dan Gohman475871a2008-07-27 21:46:04 +0000830 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
831 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000832 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
Scott Michel266bc8f2007-12-04 22:23:35 +0000833 }
834 }
835
836 assert(0 &&
Gabor Greif93c53e52008-08-31 15:37:04 +0000837 "LowerConstantPool: Relocation model other than static"
838 " not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000839 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000840}
841
Scott Michel94bd57e2009-01-15 04:41:47 +0000842//! Alternate entry point for generating the address of a constant pool entry
843SDValue
844SPU::LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM) {
845 return ::LowerConstantPool(Op, DAG, TM.getSubtargetImpl());
846}
847
Dan Gohman475871a2008-07-27 21:46:04 +0000848static SDValue
849LowerJumpTable(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000850 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000851 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
Dan Gohman475871a2008-07-27 21:46:04 +0000852 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
853 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel266bc8f2007-12-04 22:23:35 +0000854 const TargetMachine &TM = DAG.getTarget();
855
856 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michela59d4692008-02-23 18:41:37 +0000857 if (!ST->usingLargeMem()) {
858 return DAG.getNode(SPUISD::AFormAddr, PtrVT, JTI, Zero);
859 } else {
Dan Gohman475871a2008-07-27 21:46:04 +0000860 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
861 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
Scott Michela59d4692008-02-23 18:41:37 +0000862 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
863 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000864 }
865
866 assert(0 &&
867 "LowerJumpTable: Relocation model other than static not supported.");
Dan Gohman475871a2008-07-27 21:46:04 +0000868 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000869}
870
Dan Gohman475871a2008-07-27 21:46:04 +0000871static SDValue
872LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000873 MVT PtrVT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000874 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
875 GlobalValue *GV = GSDN->getGlobal();
Dan Gohman475871a2008-07-27 21:46:04 +0000876 SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
Scott Michel266bc8f2007-12-04 22:23:35 +0000877 const TargetMachine &TM = DAG.getTarget();
Dan Gohman475871a2008-07-27 21:46:04 +0000878 SDValue Zero = DAG.getConstant(0, PtrVT);
Scott Michel5af8f0e2008-07-16 17:17:29 +0000879
Scott Michel266bc8f2007-12-04 22:23:35 +0000880 if (TM.getRelocationModel() == Reloc::Static) {
Scott Michel053c1da2008-01-29 02:16:57 +0000881 if (!ST->usingLargeMem()) {
882 return DAG.getNode(SPUISD::AFormAddr, PtrVT, GA, Zero);
883 } else {
Dan Gohman475871a2008-07-27 21:46:04 +0000884 SDValue Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
885 SDValue Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
Scott Michel053c1da2008-01-29 02:16:57 +0000886 return DAG.getNode(SPUISD::IndirectAddr, PtrVT, Hi, Lo);
887 }
Scott Michel266bc8f2007-12-04 22:23:35 +0000888 } else {
889 cerr << "LowerGlobalAddress: Relocation model other than static not "
Scott Michel7f9ba9b2008-01-30 02:55:46 +0000890 << "supported.\n";
Scott Michel266bc8f2007-12-04 22:23:35 +0000891 abort();
892 /*NOTREACHED*/
893 }
894
Dan Gohman475871a2008-07-27 21:46:04 +0000895 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000896}
897
Nate Begemanccef5802008-02-14 18:43:04 +0000898//! Custom lower double precision floating point constants
Dan Gohman475871a2008-07-27 21:46:04 +0000899static SDValue
900LowerConstantFP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000901 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +0000902
Nate Begemanccef5802008-02-14 18:43:04 +0000903 if (VT == MVT::f64) {
Scott Michel1a6cdb62008-12-01 17:56:02 +0000904 ConstantFPSDNode *FP = cast<ConstantFPSDNode>(Op.getNode());
905
906 assert((FP != 0) &&
907 "LowerConstantFP: Node is not ConstantFPSDNode");
Scott Michel1df30c42008-12-29 03:23:36 +0000908
Scott Michel170783a2007-12-19 20:15:47 +0000909 uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble());
Scott Michel1a6cdb62008-12-01 17:56:02 +0000910 SDValue T = DAG.getConstant(dbits, MVT::i64);
911 SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T);
912 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
913 DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec));
Scott Michel266bc8f2007-12-04 22:23:35 +0000914 }
915
Dan Gohman475871a2008-07-27 21:46:04 +0000916 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +0000917}
918
Dan Gohman475871a2008-07-27 21:46:04 +0000919static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +0000920LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
Scott Michel266bc8f2007-12-04 22:23:35 +0000921{
922 MachineFunction &MF = DAG.getMachineFunction();
923 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner84bc5422007-12-31 04:13:23 +0000924 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Micheld976c212008-10-30 01:51:48 +0000925 SmallVector<SDValue, 48> ArgValues;
Dan Gohman475871a2008-07-27 21:46:04 +0000926 SDValue Root = Op.getOperand(0);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000927 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
Scott Michel266bc8f2007-12-04 22:23:35 +0000928
929 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
930 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000931
Scott Michel266bc8f2007-12-04 22:23:35 +0000932 unsigned ArgOffset = SPUFrameInfo::minStackSize();
933 unsigned ArgRegIdx = 0;
934 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000935
Duncan Sands83ec4b62008-06-06 12:08:01 +0000936 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +0000937
Scott Michel266bc8f2007-12-04 22:23:35 +0000938 // Add DAG nodes to load the arguments or copy them out of registers.
Gabor Greif93c53e52008-08-31 15:37:04 +0000939 for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
940 ArgNo != e; ++ArgNo) {
Duncan Sands83ec4b62008-06-06 12:08:01 +0000941 MVT ObjectVT = Op.getValue(ArgNo).getValueType();
942 unsigned ObjSize = ObjectVT.getSizeInBits()/8;
Scott Micheld976c212008-10-30 01:51:48 +0000943 SDValue ArgVal;
Scott Michel266bc8f2007-12-04 22:23:35 +0000944
Scott Micheld976c212008-10-30 01:51:48 +0000945 if (ArgRegIdx < NumArgRegs) {
946 const TargetRegisterClass *ArgRegClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +0000947
Scott Micheld976c212008-10-30 01:51:48 +0000948 switch (ObjectVT.getSimpleVT()) {
949 default: {
Scott Michel9c0c6b22008-11-21 02:56:16 +0000950 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
951 << ObjectVT.getMVTString()
952 << "\n";
953 abort();
Scott Micheld976c212008-10-30 01:51:48 +0000954 }
955 case MVT::i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000956 ArgRegClass = &SPU::R8CRegClass;
957 break;
Scott Micheld976c212008-10-30 01:51:48 +0000958 case MVT::i16:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000959 ArgRegClass = &SPU::R16CRegClass;
960 break;
Scott Micheld976c212008-10-30 01:51:48 +0000961 case MVT::i32:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000962 ArgRegClass = &SPU::R32CRegClass;
963 break;
Scott Micheld976c212008-10-30 01:51:48 +0000964 case MVT::i64:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000965 ArgRegClass = &SPU::R64CRegClass;
966 break;
Scott Micheldd950092009-01-06 03:36:14 +0000967 case MVT::i128:
968 ArgRegClass = &SPU::GPRCRegClass;
969 break;
Scott Micheld976c212008-10-30 01:51:48 +0000970 case MVT::f32:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000971 ArgRegClass = &SPU::R32FPRegClass;
972 break;
Scott Micheld976c212008-10-30 01:51:48 +0000973 case MVT::f64:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000974 ArgRegClass = &SPU::R64FPRegClass;
975 break;
Scott Micheld976c212008-10-30 01:51:48 +0000976 case MVT::v2f64:
977 case MVT::v4f32:
978 case MVT::v2i64:
979 case MVT::v4i32:
980 case MVT::v8i16:
981 case MVT::v16i8:
Scott Michel9c0c6b22008-11-21 02:56:16 +0000982 ArgRegClass = &SPU::VECREGRegClass;
983 break;
Scott Micheld976c212008-10-30 01:51:48 +0000984 }
985
986 unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
987 RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
988 ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
989 ++ArgRegIdx;
990 } else {
991 // We need to load the argument to a virtual register if we determined
992 // above that we ran out of physical registers of the appropriate type
993 // or we're forced to do vararg
Chris Lattner9f72d1a2008-02-13 07:35:30 +0000994 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
Dan Gohman475871a2008-07-27 21:46:04 +0000995 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Chris Lattner9f72d1a2008-02-13 07:35:30 +0000996 ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
Scott Michel266bc8f2007-12-04 22:23:35 +0000997 ArgOffset += StackSlotSize;
998 }
Scott Michel5af8f0e2008-07-16 17:17:29 +0000999
Scott Michel266bc8f2007-12-04 22:23:35 +00001000 ArgValues.push_back(ArgVal);
Scott Micheld976c212008-10-30 01:51:48 +00001001 // Update the chain
1002 Root = ArgVal.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001003 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001004
Scott Micheld976c212008-10-30 01:51:48 +00001005 // vararg handling:
Scott Michel266bc8f2007-12-04 22:23:35 +00001006 if (isVarArg) {
Scott Micheld976c212008-10-30 01:51:48 +00001007 // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
1008 // We will spill (79-3)+1 registers to the stack
1009 SmallVector<SDValue, 79-3+1> MemOps;
1010
1011 // Create the frame slot
1012
Scott Michel266bc8f2007-12-04 22:23:35 +00001013 for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
Scott Micheld976c212008-10-30 01:51:48 +00001014 VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
1015 SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
1016 SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
1017 SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
1018 Root = Store.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001019 MemOps.push_back(Store);
Scott Micheld976c212008-10-30 01:51:48 +00001020
1021 // Increment address by stack slot size for the next stored argument
1022 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001023 }
1024 if (!MemOps.empty())
Scott Micheld976c212008-10-30 01:51:48 +00001025 Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001026 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001027
Scott Michel266bc8f2007-12-04 22:23:35 +00001028 ArgValues.push_back(Root);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001029
Scott Michel266bc8f2007-12-04 22:23:35 +00001030 // Return the new list of results.
Duncan Sandsaaffa052008-12-01 11:41:29 +00001031 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1032 &ArgValues[0], ArgValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001033}
1034
1035/// isLSAAddress - Return the immediate to use if the specified
1036/// value is representable as a LSA address.
Dan Gohman475871a2008-07-27 21:46:04 +00001037static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001038 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
Scott Michel266bc8f2007-12-04 22:23:35 +00001039 if (!C) return 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001040
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001041 int Addr = C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001042 if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
1043 (Addr << 14 >> 14) != Addr)
1044 return 0; // Top 14 bits have to be sext of immediate.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001045
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001046 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
Scott Michel266bc8f2007-12-04 22:23:35 +00001047}
1048
Scott Michel21213e72009-01-06 23:10:38 +00001049static SDValue
Dan Gohman475871a2008-07-27 21:46:04 +00001050LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
Dan Gohman095cc292008-09-13 01:54:27 +00001051 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
1052 SDValue Chain = TheCall->getChain();
Dan Gohman095cc292008-09-13 01:54:27 +00001053 SDValue Callee = TheCall->getCallee();
1054 unsigned NumOps = TheCall->getNumArgs();
Scott Michel266bc8f2007-12-04 22:23:35 +00001055 unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();
1056 const unsigned *ArgRegs = SPURegisterInfo::getArgRegs();
1057 const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs();
1058
1059 // Handy pointer type
Duncan Sands83ec4b62008-06-06 12:08:01 +00001060 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001061
Scott Michel266bc8f2007-12-04 22:23:35 +00001062 // Accumulate how many bytes are to be pushed on the stack, including the
1063 // linkage area, and parameter passing area. According to the SPU ABI,
1064 // we minimally need space for [LR] and [SP]
1065 unsigned NumStackBytes = SPUFrameInfo::minStackSize();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001066
Scott Michel266bc8f2007-12-04 22:23:35 +00001067 // Set up a copy of the stack pointer for use loading and storing any
1068 // arguments that may not fit in the registers available for argument
1069 // passing.
Dan Gohman475871a2008-07-27 21:46:04 +00001070 SDValue StackPtr = DAG.getRegister(SPU::R1, MVT::i32);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001071
Scott Michel266bc8f2007-12-04 22:23:35 +00001072 // Figure out which arguments are going to go in registers, and which in
1073 // memory.
1074 unsigned ArgOffset = SPUFrameInfo::minStackSize(); // Just below [LR]
1075 unsigned ArgRegIdx = 0;
1076
1077 // Keep track of registers passing arguments
Dan Gohman475871a2008-07-27 21:46:04 +00001078 std::vector<std::pair<unsigned, SDValue> > RegsToPass;
Scott Michel266bc8f2007-12-04 22:23:35 +00001079 // And the arguments passed on the stack
Dan Gohman475871a2008-07-27 21:46:04 +00001080 SmallVector<SDValue, 8> MemOpChains;
Scott Michel266bc8f2007-12-04 22:23:35 +00001081
1082 for (unsigned i = 0; i != NumOps; ++i) {
Dan Gohman095cc292008-09-13 01:54:27 +00001083 SDValue Arg = TheCall->getArg(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001084
Scott Michel266bc8f2007-12-04 22:23:35 +00001085 // PtrOff will be used to store the current argument to the stack if a
1086 // register cannot be found for it.
Dan Gohman475871a2008-07-27 21:46:04 +00001087 SDValue PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001088 PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
1089
Duncan Sands83ec4b62008-06-06 12:08:01 +00001090 switch (Arg.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001091 default: assert(0 && "Unexpected ValueType for argument!");
Scott Micheldd950092009-01-06 03:36:14 +00001092 case MVT::i8:
1093 case MVT::i16:
Scott Michel266bc8f2007-12-04 22:23:35 +00001094 case MVT::i32:
1095 case MVT::i64:
1096 case MVT::i128:
1097 if (ArgRegIdx != NumArgRegs) {
1098 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1099 } else {
1100 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001101 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001102 }
1103 break;
1104 case MVT::f32:
1105 case MVT::f64:
1106 if (ArgRegIdx != NumArgRegs) {
1107 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1108 } else {
1109 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001110 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001111 }
1112 break;
Scott Michelcc188272008-12-04 21:01:44 +00001113 case MVT::v2i64:
1114 case MVT::v2f64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001115 case MVT::v4f32:
1116 case MVT::v4i32:
1117 case MVT::v8i16:
1118 case MVT::v16i8:
1119 if (ArgRegIdx != NumArgRegs) {
1120 RegsToPass.push_back(std::make_pair(ArgRegs[ArgRegIdx++], Arg));
1121 } else {
1122 MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001123 ArgOffset += StackSlotSize;
Scott Michel266bc8f2007-12-04 22:23:35 +00001124 }
1125 break;
1126 }
1127 }
1128
1129 // Update number of stack bytes actually used, insert a call sequence start
1130 NumStackBytes = (ArgOffset - SPUFrameInfo::minStackSize());
Chris Lattnere563bbc2008-10-11 22:08:30 +00001131 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumStackBytes,
1132 true));
Scott Michel266bc8f2007-12-04 22:23:35 +00001133
1134 if (!MemOpChains.empty()) {
1135 // Adjust the stack pointer for the stack arguments.
1136 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
1137 &MemOpChains[0], MemOpChains.size());
1138 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001139
Scott Michel266bc8f2007-12-04 22:23:35 +00001140 // Build a sequence of copy-to-reg nodes chained together with token chain
1141 // and flag operands which copy the outgoing args into the appropriate regs.
Dan Gohman475871a2008-07-27 21:46:04 +00001142 SDValue InFlag;
Scott Michel266bc8f2007-12-04 22:23:35 +00001143 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1144 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
1145 InFlag);
1146 InFlag = Chain.getValue(1);
1147 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001148
Dan Gohman475871a2008-07-27 21:46:04 +00001149 SmallVector<SDValue, 8> Ops;
Scott Michel266bc8f2007-12-04 22:23:35 +00001150 unsigned CallOpc = SPUISD::CALL;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001151
Bill Wendling056292f2008-09-16 21:48:12 +00001152 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
1153 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
1154 // node so that legalize doesn't hack it.
Scott Michel19fd42a2008-11-11 03:06:06 +00001155 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001156 GlobalValue *GV = G->getGlobal();
Duncan Sands83ec4b62008-06-06 12:08:01 +00001157 MVT CalleeVT = Callee.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001158 SDValue Zero = DAG.getConstant(0, PtrVT);
1159 SDValue GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001160
Scott Michel9de5d0d2008-01-11 02:53:15 +00001161 if (!ST->usingLargeMem()) {
1162 // Turn calls to targets that are defined (i.e., have bodies) into BRSL
1163 // style calls, otherwise, external symbols are BRASL calls. This assumes
1164 // that declared/defined symbols are in the same compilation unit and can
1165 // be reached through PC-relative jumps.
1166 //
1167 // NOTE:
1168 // This may be an unsafe assumption for JIT and really large compilation
1169 // units.
1170 if (GV->isDeclaration()) {
1171 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
1172 } else {
1173 Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
1174 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001175 } else {
Scott Michel9de5d0d2008-01-11 02:53:15 +00001176 // "Large memory" mode: Turn all calls into indirect calls with a X-form
1177 // address pairs:
Scott Michel053c1da2008-01-29 02:16:57 +00001178 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, GA, Zero);
Scott Michel266bc8f2007-12-04 22:23:35 +00001179 }
Scott Michel1df30c42008-12-29 03:23:36 +00001180 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1181 MVT CalleeVT = Callee.getValueType();
1182 SDValue Zero = DAG.getConstant(0, PtrVT);
1183 SDValue ExtSym = DAG.getTargetExternalSymbol(S->getSymbol(),
1184 Callee.getValueType());
1185
1186 if (!ST->usingLargeMem()) {
1187 Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, ExtSym, Zero);
1188 } else {
1189 Callee = DAG.getNode(SPUISD::IndirectAddr, PtrVT, ExtSym, Zero);
1190 }
1191 } else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001192 // If this is an absolute destination address that appears to be a legal
1193 // local store address, use the munged value.
Dan Gohman475871a2008-07-27 21:46:04 +00001194 Callee = SDValue(Dest, 0);
Scott Michel9de5d0d2008-01-11 02:53:15 +00001195 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001196
1197 Ops.push_back(Chain);
1198 Ops.push_back(Callee);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001199
Scott Michel266bc8f2007-12-04 22:23:35 +00001200 // Add argument registers to the end of the list so that they are known live
1201 // into the call.
1202 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
Scott Michel5af8f0e2008-07-16 17:17:29 +00001203 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
Scott Michel266bc8f2007-12-04 22:23:35 +00001204 RegsToPass[i].second.getValueType()));
Scott Michel5af8f0e2008-07-16 17:17:29 +00001205
Gabor Greifba36cb52008-08-28 21:40:38 +00001206 if (InFlag.getNode())
Scott Michel266bc8f2007-12-04 22:23:35 +00001207 Ops.push_back(InFlag);
Duncan Sands4bdcb612008-07-02 17:40:58 +00001208 // Returns a chain and a flag for retval copy to use.
1209 Chain = DAG.getNode(CallOpc, DAG.getVTList(MVT::Other, MVT::Flag),
1210 &Ops[0], Ops.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001211 InFlag = Chain.getValue(1);
1212
Chris Lattnere563bbc2008-10-11 22:08:30 +00001213 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true),
1214 DAG.getIntPtrConstant(0, true), InFlag);
Dan Gohman095cc292008-09-13 01:54:27 +00001215 if (TheCall->getValueType(0) != MVT::Other)
Evan Chengebaaa912008-02-05 22:44:06 +00001216 InFlag = Chain.getValue(1);
1217
Dan Gohman475871a2008-07-27 21:46:04 +00001218 SDValue ResultVals[3];
Scott Michel266bc8f2007-12-04 22:23:35 +00001219 unsigned NumResults = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001220
Scott Michel266bc8f2007-12-04 22:23:35 +00001221 // If the call has results, copy the values out of the ret val registers.
Dan Gohman095cc292008-09-13 01:54:27 +00001222 switch (TheCall->getValueType(0).getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001223 default: assert(0 && "Unexpected ret value!");
1224 case MVT::Other: break;
1225 case MVT::i32:
Dan Gohman095cc292008-09-13 01:54:27 +00001226 if (TheCall->getValueType(1) == MVT::i32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001227 Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1);
1228 ResultVals[0] = Chain.getValue(0);
1229 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32,
1230 Chain.getValue(2)).getValue(1);
1231 ResultVals[1] = Chain.getValue(0);
1232 NumResults = 2;
Scott Michel266bc8f2007-12-04 22:23:35 +00001233 } else {
1234 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, InFlag).getValue(1);
1235 ResultVals[0] = Chain.getValue(0);
1236 NumResults = 1;
1237 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001238 break;
1239 case MVT::i64:
1240 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i64, InFlag).getValue(1);
1241 ResultVals[0] = Chain.getValue(0);
1242 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001243 break;
Scott Micheldd950092009-01-06 03:36:14 +00001244 case MVT::i128:
1245 Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
1246 ResultVals[0] = Chain.getValue(0);
1247 NumResults = 1;
1248 break;
Scott Michel266bc8f2007-12-04 22:23:35 +00001249 case MVT::f32:
1250 case MVT::f64:
Dan Gohman095cc292008-09-13 01:54:27 +00001251 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001252 InFlag).getValue(1);
1253 ResultVals[0] = Chain.getValue(0);
1254 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001255 break;
1256 case MVT::v2f64:
Scott Michelcc188272008-12-04 21:01:44 +00001257 case MVT::v2i64:
Scott Michel266bc8f2007-12-04 22:23:35 +00001258 case MVT::v4f32:
1259 case MVT::v4i32:
1260 case MVT::v8i16:
1261 case MVT::v16i8:
Dan Gohman095cc292008-09-13 01:54:27 +00001262 Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
Scott Michel266bc8f2007-12-04 22:23:35 +00001263 InFlag).getValue(1);
1264 ResultVals[0] = Chain.getValue(0);
1265 NumResults = 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00001266 break;
1267 }
Duncan Sands4bdcb612008-07-02 17:40:58 +00001268
Scott Michel266bc8f2007-12-04 22:23:35 +00001269 // If the function returns void, just return the chain.
1270 if (NumResults == 0)
1271 return Chain;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001272
Scott Michel266bc8f2007-12-04 22:23:35 +00001273 // Otherwise, merge everything together with a MERGE_VALUES node.
1274 ResultVals[NumResults++] = Chain;
Dan Gohman475871a2008-07-27 21:46:04 +00001275 SDValue Res = DAG.getMergeValues(ResultVals, NumResults);
Gabor Greif99a6cb92008-08-26 22:36:50 +00001276 return Res.getValue(Op.getResNo());
Scott Michel266bc8f2007-12-04 22:23:35 +00001277}
1278
Dan Gohman475871a2008-07-27 21:46:04 +00001279static SDValue
1280LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001281 SmallVector<CCValAssign, 16> RVLocs;
1282 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
1283 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
1284 CCState CCInfo(CC, isVarArg, TM, RVLocs);
Gabor Greifba36cb52008-08-28 21:40:38 +00001285 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001286
Scott Michel266bc8f2007-12-04 22:23:35 +00001287 // If this is the first return lowered for this function, add the regs to the
1288 // liveout set for the function.
Chris Lattner84bc5422007-12-31 04:13:23 +00001289 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001290 for (unsigned i = 0; i != RVLocs.size(); ++i)
Chris Lattner84bc5422007-12-31 04:13:23 +00001291 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
Scott Michel266bc8f2007-12-04 22:23:35 +00001292 }
1293
Dan Gohman475871a2008-07-27 21:46:04 +00001294 SDValue Chain = Op.getOperand(0);
1295 SDValue Flag;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001296
Scott Michel266bc8f2007-12-04 22:23:35 +00001297 // Copy the result values into the output registers.
1298 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1299 CCValAssign &VA = RVLocs[i];
1300 assert(VA.isRegLoc() && "Can only return in registers!");
1301 Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
1302 Flag = Chain.getValue(1);
1303 }
1304
Gabor Greifba36cb52008-08-28 21:40:38 +00001305 if (Flag.getNode())
Scott Michel266bc8f2007-12-04 22:23:35 +00001306 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain, Flag);
1307 else
1308 return DAG.getNode(SPUISD::RET_FLAG, MVT::Other, Chain);
1309}
1310
1311
1312//===----------------------------------------------------------------------===//
1313// Vector related lowering:
1314//===----------------------------------------------------------------------===//
1315
1316static ConstantSDNode *
1317getVecImm(SDNode *N) {
Dan Gohman475871a2008-07-27 21:46:04 +00001318 SDValue OpVal(0, 0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001319
Scott Michel266bc8f2007-12-04 22:23:35 +00001320 // Check to see if this buildvec has a single non-undef value in its elements.
1321 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
1322 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
Gabor Greifba36cb52008-08-28 21:40:38 +00001323 if (OpVal.getNode() == 0)
Scott Michel266bc8f2007-12-04 22:23:35 +00001324 OpVal = N->getOperand(i);
1325 else if (OpVal != N->getOperand(i))
1326 return 0;
1327 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001328
Gabor Greifba36cb52008-08-28 21:40:38 +00001329 if (OpVal.getNode() != 0) {
Scott Michel19fd42a2008-11-11 03:06:06 +00001330 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001331 return CN;
1332 }
1333 }
1334
1335 return 0; // All UNDEF: use implicit def.; not Constant node
1336}
1337
1338/// get_vec_i18imm - Test if this vector is a vector filled with the same value
1339/// and the value fits into an unsigned 18-bit constant, and if so, return the
1340/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001341SDValue SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001342 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001343 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001344 uint64_t Value = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001345 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001346 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001347 uint32_t upper = uint32_t(UValue >> 32);
1348 uint32_t lower = uint32_t(UValue);
1349 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001350 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001351 Value = Value >> 32;
1352 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001353 if (Value <= 0x3ffff)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001354 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001355 }
1356
Dan Gohman475871a2008-07-27 21:46:04 +00001357 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001358}
1359
1360/// get_vec_i16imm - Test if this vector is a vector filled with the same value
1361/// and the value fits into a signed 16-bit constant, and if so, return the
1362/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001363SDValue SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001364 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001365 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001366 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001367 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001368 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001369 uint32_t upper = uint32_t(UValue >> 32);
1370 uint32_t lower = uint32_t(UValue);
1371 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001372 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001373 Value = Value >> 32;
1374 }
Scott Michelad2715e2008-03-05 23:02:02 +00001375 if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001376 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001377 }
1378 }
1379
Dan Gohman475871a2008-07-27 21:46:04 +00001380 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001381}
1382
1383/// get_vec_i10imm - Test if this vector is a vector filled with the same value
1384/// and the value fits into a signed 10-bit constant, and if so, return the
1385/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001386SDValue SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001387 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001388 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohman7810bfe2008-09-26 21:54:37 +00001389 int64_t Value = CN->getSExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001390 if (ValueType == MVT::i64) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001391 uint64_t UValue = CN->getZExtValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001392 uint32_t upper = uint32_t(UValue >> 32);
1393 uint32_t lower = uint32_t(UValue);
1394 if (upper != lower)
Dan Gohman475871a2008-07-27 21:46:04 +00001395 return SDValue();
Scott Michel4cb8bd82008-03-06 04:02:54 +00001396 Value = Value >> 32;
1397 }
Scott Michelad2715e2008-03-05 23:02:02 +00001398 if (isS10Constant(Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001399 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001400 }
1401
Dan Gohman475871a2008-07-27 21:46:04 +00001402 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001403}
1404
1405/// get_vec_i8imm - Test if this vector is a vector filled with the same value
1406/// and the value fits into a signed 8-bit constant, and if so, return the
1407/// constant.
1408///
1409/// @note: The incoming vector is v16i8 because that's the only way we can load
1410/// constant vectors. Thus, we test to see if the upper and lower bytes are the
1411/// same value.
Dan Gohman475871a2008-07-27 21:46:04 +00001412SDValue SPU::get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001413 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001414 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001415 int Value = (int) CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001416 if (ValueType == MVT::i16
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001417 && Value <= 0xffff /* truncated from uint64_t */
1418 && ((short) Value >> 8) == ((short) Value & 0xff))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001419 return DAG.getTargetConstant(Value & 0xff, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001420 else if (ValueType == MVT::i8
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001421 && (Value & 0xff) == Value)
Dan Gohmanfa210d82008-11-05 02:06:09 +00001422 return DAG.getTargetConstant(Value, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001423 }
1424
Dan Gohman475871a2008-07-27 21:46:04 +00001425 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001426}
1427
1428/// get_ILHUvec_imm - Test if this vector is a vector filled with the same value
1429/// and the value fits into a signed 16-bit constant, and if so, return the
1430/// constant
Dan Gohman475871a2008-07-27 21:46:04 +00001431SDValue SPU::get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001432 MVT ValueType) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001433 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001434 uint64_t Value = CN->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001435 if ((ValueType == MVT::i32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001436 && ((unsigned) Value & 0xffff0000) == (unsigned) Value)
1437 || (ValueType == MVT::i64 && (Value & 0xffff0000) == Value))
Dan Gohmanfa210d82008-11-05 02:06:09 +00001438 return DAG.getTargetConstant(Value >> 16, ValueType);
Scott Michel266bc8f2007-12-04 22:23:35 +00001439 }
1440
Dan Gohman475871a2008-07-27 21:46:04 +00001441 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001442}
1443
1444/// get_v4i32_imm - Catch-all for general 32-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001445SDValue SPU::get_v4i32_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001446 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001447 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001448 }
1449
Dan Gohman475871a2008-07-27 21:46:04 +00001450 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001451}
1452
1453/// get_v4i32_imm - Catch-all for general 64-bit constant vectors
Dan Gohman475871a2008-07-27 21:46:04 +00001454SDValue SPU::get_v2i64_imm(SDNode *N, SelectionDAG &DAG) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001455 if (ConstantSDNode *CN = getVecImm(N)) {
Dan Gohmanfa210d82008-11-05 02:06:09 +00001456 return DAG.getTargetConstant((unsigned) CN->getZExtValue(), MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001457 }
1458
Dan Gohman475871a2008-07-27 21:46:04 +00001459 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001460}
1461
1462// If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel5af8f0e2008-07-16 17:17:29 +00001463// UndefBits is set if the corresponding element of the vector is an
Scott Michel266bc8f2007-12-04 22:23:35 +00001464// ISD::UNDEF value. For undefs, the corresponding VectorBits values are
1465// zero. Return true if this is not an array of constants, false if it is.
1466//
1467static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
1468 uint64_t UndefBits[2]) {
1469 // Start with zero'd results.
1470 VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001471
Duncan Sands83ec4b62008-06-06 12:08:01 +00001472 unsigned EltBitSize = BV->getOperand(0).getValueType().getSizeInBits();
Scott Michel266bc8f2007-12-04 22:23:35 +00001473 for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
Dan Gohman475871a2008-07-27 21:46:04 +00001474 SDValue OpVal = BV->getOperand(i);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001475
Scott Michel266bc8f2007-12-04 22:23:35 +00001476 unsigned PartNo = i >= e/2; // In the upper 128 bits?
1477 unsigned SlotNo = e/2 - (i & (e/2-1))-1; // Which subpiece of the uint64_t.
1478
1479 uint64_t EltBits = 0;
1480 if (OpVal.getOpcode() == ISD::UNDEF) {
1481 uint64_t EltUndefBits = ~0ULL >> (64-EltBitSize);
1482 UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
1483 continue;
Scott Michel19fd42a2008-11-11 03:06:06 +00001484 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001485 EltBits = CN->getZExtValue() & (~0ULL >> (64-EltBitSize));
Scott Michel19fd42a2008-11-11 03:06:06 +00001486 } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001487 const APFloat &apf = CN->getValueAPF();
1488 EltBits = (CN->getValueType(0) == MVT::f32
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001489 ? FloatToBits(apf.convertToFloat())
1490 : DoubleToBits(apf.convertToDouble()));
Scott Michel266bc8f2007-12-04 22:23:35 +00001491 } else {
1492 // Nonconstant element.
1493 return true;
1494 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001495
Scott Michel266bc8f2007-12-04 22:23:35 +00001496 VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
1497 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001498
1499 //printf("%llx %llx %llx %llx\n",
Scott Michel266bc8f2007-12-04 22:23:35 +00001500 // VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
1501 return false;
1502}
1503
1504/// If this is a splat (repetition) of a value across the whole vector, return
1505/// the smallest size that splats it. For example, "0x01010101010101..." is a
Scott Michel5af8f0e2008-07-16 17:17:29 +00001506/// splat of 0x01, 0x0101, and 0x01010101. We return SplatBits = 0x01 and
Scott Michel266bc8f2007-12-04 22:23:35 +00001507/// SplatSize = 1 byte.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001508static bool isConstantSplat(const uint64_t Bits128[2],
Scott Michel266bc8f2007-12-04 22:23:35 +00001509 const uint64_t Undef128[2],
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001510 int MinSplatBits,
Scott Michel266bc8f2007-12-04 22:23:35 +00001511 uint64_t &SplatBits, uint64_t &SplatUndef,
1512 int &SplatSize) {
1513 // Don't let undefs prevent splats from matching. See if the top 64-bits are
1514 // the same as the lower 64-bits, ignoring undefs.
1515 uint64_t Bits64 = Bits128[0] | Bits128[1];
1516 uint64_t Undef64 = Undef128[0] & Undef128[1];
1517 uint32_t Bits32 = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
1518 uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
1519 uint16_t Bits16 = uint16_t(Bits32) | uint16_t(Bits32 >> 16);
1520 uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
1521
1522 if ((Bits128[0] & ~Undef128[1]) == (Bits128[1] & ~Undef128[0])) {
1523 if (MinSplatBits < 64) {
Scott Michel5af8f0e2008-07-16 17:17:29 +00001524
Scott Michel266bc8f2007-12-04 22:23:35 +00001525 // Check that the top 32-bits are the same as the lower 32-bits, ignoring
1526 // undefs.
1527 if ((Bits64 & (~Undef64 >> 32)) == ((Bits64 >> 32) & ~Undef64)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001528 if (MinSplatBits < 32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001529
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001530 // If the top 16-bits are different than the lower 16-bits, ignoring
1531 // undefs, we have an i32 splat.
1532 if ((Bits32 & (~Undef32 >> 16)) == ((Bits32 >> 16) & ~Undef32)) {
1533 if (MinSplatBits < 16) {
1534 // If the top 8-bits are different than the lower 8-bits, ignoring
1535 // undefs, we have an i16 splat.
Gabor Greif93c53e52008-08-31 15:37:04 +00001536 if ((Bits16 & (uint16_t(~Undef16) >> 8))
1537 == ((Bits16 >> 8) & ~Undef16)) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001538 // Otherwise, we have an 8-bit splat.
1539 SplatBits = uint8_t(Bits16) | uint8_t(Bits16 >> 8);
1540 SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
1541 SplatSize = 1;
1542 return true;
1543 }
1544 } else {
1545 SplatBits = Bits16;
1546 SplatUndef = Undef16;
1547 SplatSize = 2;
1548 return true;
1549 }
1550 }
1551 } else {
1552 SplatBits = Bits32;
1553 SplatUndef = Undef32;
1554 SplatSize = 4;
1555 return true;
1556 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001557 }
1558 } else {
1559 SplatBits = Bits128[0];
1560 SplatUndef = Undef128[0];
1561 SplatSize = 8;
1562 return true;
1563 }
1564 }
1565
1566 return false; // Can't be a splat if two pieces don't match.
1567}
1568
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001569//! Lower a BUILD_VECTOR instruction creatively:
1570SDValue
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001571LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001572 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001573 // If this is a vector of constants or undefs, get the bits. A bit in
Scott Michel5af8f0e2008-07-16 17:17:29 +00001574 // UndefBits is set if the corresponding element of the vector is an
Scott Michel266bc8f2007-12-04 22:23:35 +00001575 // ISD::UNDEF value. For undefs, the corresponding VectorBits values are
Scott Michel5af8f0e2008-07-16 17:17:29 +00001576 // zero.
Scott Michel266bc8f2007-12-04 22:23:35 +00001577 uint64_t VectorBits[2];
1578 uint64_t UndefBits[2];
1579 uint64_t SplatBits, SplatUndef;
1580 int SplatSize;
Gabor Greifba36cb52008-08-28 21:40:38 +00001581 if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits)
Scott Michel266bc8f2007-12-04 22:23:35 +00001582 || !isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00001583 VT.getVectorElementType().getSizeInBits(),
Scott Michel266bc8f2007-12-04 22:23:35 +00001584 SplatBits, SplatUndef, SplatSize))
Dan Gohman475871a2008-07-27 21:46:04 +00001585 return SDValue(); // Not a constant vector, not a splat.
Scott Michel5af8f0e2008-07-16 17:17:29 +00001586
Duncan Sands83ec4b62008-06-06 12:08:01 +00001587 switch (VT.getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001588 default:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00001589 cerr << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
1590 << VT.getMVTString()
1591 << "\n";
1592 abort();
1593 /*NOTREACHED*/
Scott Michel266bc8f2007-12-04 22:23:35 +00001594 case MVT::v4f32: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001595 uint32_t Value32 = uint32_t(SplatBits);
Scott Michel266bc8f2007-12-04 22:23:35 +00001596 assert(SplatSize == 4
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001597 && "LowerBUILD_VECTOR: Unexpected floating point vector element.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001598 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001599 SDValue T = DAG.getConstant(Value32, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00001600 return DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001601 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, T, T, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001602 break;
1603 }
1604 case MVT::v2f64: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001605 uint64_t f64val = uint64_t(SplatBits);
Scott Michel266bc8f2007-12-04 22:23:35 +00001606 assert(SplatSize == 8
Scott Michel104de432008-11-24 17:11:17 +00001607 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes.");
Scott Michel266bc8f2007-12-04 22:23:35 +00001608 // NOTE: pretend the constant is an integer. LLVM won't load FP constants
Dan Gohman475871a2008-07-27 21:46:04 +00001609 SDValue T = DAG.getConstant(f64val, MVT::i64);
Scott Michel266bc8f2007-12-04 22:23:35 +00001610 return DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001611 DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
Scott Michel266bc8f2007-12-04 22:23:35 +00001612 break;
1613 }
1614 case MVT::v16i8: {
1615 // 8-bit constants have to be expanded to 16-bits
1616 unsigned short Value16 = SplatBits | (SplatBits << 8);
Dan Gohman475871a2008-07-27 21:46:04 +00001617 SDValue Ops[8];
Scott Michel266bc8f2007-12-04 22:23:35 +00001618 for (int i = 0; i < 8; ++i)
1619 Ops[i] = DAG.getConstant(Value16, MVT::i16);
1620 return DAG.getNode(ISD::BIT_CONVERT, VT,
1621 DAG.getNode(ISD::BUILD_VECTOR, MVT::v8i16, Ops, 8));
1622 }
1623 case MVT::v8i16: {
1624 unsigned short Value16;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001625 if (SplatSize == 2)
Scott Michel266bc8f2007-12-04 22:23:35 +00001626 Value16 = (unsigned short) (SplatBits & 0xffff);
1627 else
1628 Value16 = (unsigned short) (SplatBits | (SplatBits << 8));
Dan Gohman475871a2008-07-27 21:46:04 +00001629 SDValue T = DAG.getConstant(Value16, VT.getVectorElementType());
1630 SDValue Ops[8];
Scott Michel266bc8f2007-12-04 22:23:35 +00001631 for (int i = 0; i < 8; ++i) Ops[i] = T;
1632 return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops, 8);
1633 }
1634 case MVT::v4i32: {
1635 unsigned int Value = SplatBits;
Dan Gohman475871a2008-07-27 21:46:04 +00001636 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
Scott Michel266bc8f2007-12-04 22:23:35 +00001637 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
1638 }
Scott Michel21213e72009-01-06 23:10:38 +00001639 case MVT::v2i32: {
1640 unsigned int Value = SplatBits;
1641 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
1642 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
1643 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001644 case MVT::v2i64: {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001645 return SPU::LowerSplat_v2i64(VT, DAG, SplatBits);
Scott Michel266bc8f2007-12-04 22:23:35 +00001646 }
1647 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001648
Dan Gohman475871a2008-07-27 21:46:04 +00001649 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001650}
1651
Scott Michelc9c8b2a2009-01-26 03:31:40 +00001652SDValue
1653SPU::LowerSplat_v2i64(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal) {
1654 uint32_t upper = uint32_t(SplatVal >> 32);
1655 uint32_t lower = uint32_t(SplatVal);
1656
1657 if (upper == lower) {
1658 // Magic constant that can be matched by IL, ILA, et. al.
1659 SDValue Val = DAG.getTargetConstant(upper, MVT::i32);
1660 return DAG.getNode(ISD::BIT_CONVERT, OpVT,
1661 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1662 Val, Val, Val, Val));
1663 } else {
1664 SDValue LO32;
1665 SDValue HI32;
1666 SmallVector<SDValue, 16> ShufBytes;
1667 SDValue Result;
1668 bool upper_special, lower_special;
1669
1670 // NOTE: This code creates common-case shuffle masks that can be easily
1671 // detected as common expressions. It is not attempting to create highly
1672 // specialized masks to replace any and all 0's, 0xff's and 0x80's.
1673
1674 // Detect if the upper or lower half is a special shuffle mask pattern:
1675 upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000);
1676 lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000);
1677
1678 // Create lower vector if not a special pattern
1679 if (!lower_special) {
1680 SDValue LO32C = DAG.getConstant(lower, MVT::i32);
1681 LO32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
1682 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1683 LO32C, LO32C, LO32C, LO32C));
1684 }
1685
1686 // Create upper vector if not a special pattern
1687 if (!upper_special) {
1688 SDValue HI32C = DAG.getConstant(upper, MVT::i32);
1689 HI32 = DAG.getNode(ISD::BIT_CONVERT, OpVT,
1690 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1691 HI32C, HI32C, HI32C, HI32C));
1692 }
1693
1694 // If either upper or lower are special, then the two input operands are
1695 // the same (basically, one of them is a "don't care")
1696 if (lower_special)
1697 LO32 = HI32;
1698 if (upper_special)
1699 HI32 = LO32;
1700 if (lower_special && upper_special) {
1701 // Unhappy situation... both upper and lower are special, so punt with
1702 // a target constant:
1703 SDValue Zero = DAG.getConstant(0, MVT::i32);
1704 HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero,
1705 Zero, Zero);
1706 }
1707
1708 for (int i = 0; i < 4; ++i) {
1709 uint64_t val = 0;
1710 for (int j = 0; j < 4; ++j) {
1711 SDValue V;
1712 bool process_upper, process_lower;
1713 val <<= 8;
1714 process_upper = (upper_special && (i & 1) == 0);
1715 process_lower = (lower_special && (i & 1) == 1);
1716
1717 if (process_upper || process_lower) {
1718 if ((process_upper && upper == 0)
1719 || (process_lower && lower == 0))
1720 val |= 0x80;
1721 else if ((process_upper && upper == 0xffffffff)
1722 || (process_lower && lower == 0xffffffff))
1723 val |= 0xc0;
1724 else if ((process_upper && upper == 0x80000000)
1725 || (process_lower && lower == 0x80000000))
1726 val |= (j == 0 ? 0xe0 : 0x80);
1727 } else
1728 val |= i * 4 + j + ((i & 1) * 16);
1729 }
1730
1731 ShufBytes.push_back(DAG.getConstant(val, MVT::i32));
1732 }
1733
1734 return DAG.getNode(SPUISD::SHUFB, OpVT, HI32, LO32,
1735 DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1736 &ShufBytes[0], ShufBytes.size()));
1737 }
1738}
1739
Scott Michel266bc8f2007-12-04 22:23:35 +00001740/// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on
1741/// which the Cell can operate. The code inspects V3 to ascertain whether the
1742/// permutation vector, V3, is monotonically increasing with one "exception"
1743/// element, e.g., (0, 1, _, 3). If this is the case, then generate a
Scott Michel7a1c9e92008-11-22 23:50:42 +00001744/// SHUFFLE_MASK synthetic instruction. Otherwise, spill V3 to the constant pool.
Scott Michel266bc8f2007-12-04 22:23:35 +00001745/// In either case, the net result is going to eventually invoke SHUFB to
1746/// permute/shuffle the bytes from V1 and V2.
1747/// \note
Scott Michel7a1c9e92008-11-22 23:50:42 +00001748/// SHUFFLE_MASK is eventually selected as one of the C*D instructions, generate
Scott Michel266bc8f2007-12-04 22:23:35 +00001749/// control word for byte/halfword/word insertion. This takes care of a single
1750/// element move from V2 into V1.
1751/// \note
1752/// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions.
Dan Gohman475871a2008-07-27 21:46:04 +00001753static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
1754 SDValue V1 = Op.getOperand(0);
1755 SDValue V2 = Op.getOperand(1);
1756 SDValue PermMask = Op.getOperand(2);
Scott Michel5af8f0e2008-07-16 17:17:29 +00001757
Scott Michel266bc8f2007-12-04 22:23:35 +00001758 if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001759
Scott Michel266bc8f2007-12-04 22:23:35 +00001760 // If we have a single element being moved from V1 to V2, this can be handled
1761 // using the C*[DX] compute mask instructions, but the vector elements have
1762 // to be monotonically increasing with one exception element.
Scott Michelcc188272008-12-04 21:01:44 +00001763 MVT VecVT = V1.getValueType();
1764 MVT EltVT = VecVT.getVectorElementType();
Scott Michel266bc8f2007-12-04 22:23:35 +00001765 unsigned EltsFromV2 = 0;
1766 unsigned V2Elt = 0;
1767 unsigned V2EltIdx0 = 0;
1768 unsigned CurrElt = 0;
Scott Michelcc188272008-12-04 21:01:44 +00001769 unsigned MaxElts = VecVT.getVectorNumElements();
1770 unsigned PrevElt = 0;
1771 unsigned V0Elt = 0;
Scott Michel266bc8f2007-12-04 22:23:35 +00001772 bool monotonic = true;
Scott Michelcc188272008-12-04 21:01:44 +00001773 bool rotate = true;
1774
1775 if (EltVT == MVT::i8) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001776 V2EltIdx0 = 16;
Scott Michelcc188272008-12-04 21:01:44 +00001777 } else if (EltVT == MVT::i16) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001778 V2EltIdx0 = 8;
Scott Michelcc188272008-12-04 21:01:44 +00001779 } else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001780 V2EltIdx0 = 4;
Scott Michelcc188272008-12-04 21:01:44 +00001781 } else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
1782 V2EltIdx0 = 2;
1783 } else
Scott Michel266bc8f2007-12-04 22:23:35 +00001784 assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
1785
Scott Michelcc188272008-12-04 21:01:44 +00001786 for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) {
1787 if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) {
1788 unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001789
Scott Michelcc188272008-12-04 21:01:44 +00001790 if (monotonic) {
1791 if (SrcElt >= V2EltIdx0) {
1792 if (1 >= (++EltsFromV2)) {
1793 V2Elt = (V2EltIdx0 - SrcElt) << 2;
1794 }
1795 } else if (CurrElt != SrcElt) {
1796 monotonic = false;
1797 }
1798
1799 ++CurrElt;
1800 }
1801
1802 if (rotate) {
1803 if (PrevElt > 0 && SrcElt < MaxElts) {
1804 if ((PrevElt == SrcElt - 1)
1805 || (PrevElt == MaxElts - 1 && SrcElt == 0)) {
1806 PrevElt = SrcElt;
1807 if (SrcElt == 0)
1808 V0Elt = i;
1809 } else {
1810 rotate = false;
1811 }
1812 } else if (PrevElt == 0) {
1813 // First time through, need to keep track of previous element
1814 PrevElt = SrcElt;
1815 } else {
1816 // This isn't a rotation, takes elements from vector 2
1817 rotate = false;
1818 }
1819 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001820 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001821 }
1822
1823 if (EltsFromV2 == 1 && monotonic) {
1824 // Compute mask and shuffle
1825 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00001826 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1827 unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Duncan Sands83ec4b62008-06-06 12:08:01 +00001828 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00001829 // Initialize temporary register to 0
Dan Gohman475871a2008-07-27 21:46:04 +00001830 SDValue InitTempReg =
Scott Michel266bc8f2007-12-04 22:23:35 +00001831 DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT));
Scott Michel7a1c9e92008-11-22 23:50:42 +00001832 // Copy register's contents as index in SHUFFLE_MASK:
Dan Gohman475871a2008-07-27 21:46:04 +00001833 SDValue ShufMaskOp =
Scott Michel1a6cdb62008-12-01 17:56:02 +00001834 DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001835 DAG.getTargetConstant(V2Elt, MVT::i32),
1836 DAG.getCopyFromReg(InitTempReg, VReg, PtrVT));
Scott Michel266bc8f2007-12-04 22:23:35 +00001837 // Use shuffle mask in SHUFB synthetic instruction:
1838 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp);
Scott Michelcc188272008-12-04 21:01:44 +00001839 } else if (rotate) {
1840 int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8;
Scott Michel1df30c42008-12-29 03:23:36 +00001841
Scott Michelcc188272008-12-04 21:01:44 +00001842 return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(),
1843 V1, DAG.getConstant(rotamt, MVT::i16));
Scott Michel266bc8f2007-12-04 22:23:35 +00001844 } else {
Gabor Greif93c53e52008-08-31 15:37:04 +00001845 // Convert the SHUFFLE_VECTOR mask's input element units to the
1846 // actual bytes.
Duncan Sands83ec4b62008-06-06 12:08:01 +00001847 unsigned BytesPerElement = EltVT.getSizeInBits()/8;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001848
Dan Gohman475871a2008-07-27 21:46:04 +00001849 SmallVector<SDValue, 16> ResultMask;
Scott Michel266bc8f2007-12-04 22:23:35 +00001850 for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
1851 unsigned SrcElt;
1852 if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001853 SrcElt = 0;
Scott Michel5af8f0e2008-07-16 17:17:29 +00001854 else
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001855 SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
Scott Michel5af8f0e2008-07-16 17:17:29 +00001856
Scott Michela59d4692008-02-23 18:41:37 +00001857 for (unsigned j = 0; j < BytesPerElement; ++j) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001858 ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
1859 MVT::i8));
Scott Michel266bc8f2007-12-04 22:23:35 +00001860 }
1861 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00001862
Dan Gohman475871a2008-07-27 21:46:04 +00001863 SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
Scott Michel1a6cdb62008-12-01 17:56:02 +00001864 &ResultMask[0], ResultMask.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001865 return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask);
1866 }
1867}
1868
Dan Gohman475871a2008-07-27 21:46:04 +00001869static SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) {
1870 SDValue Op0 = Op.getOperand(0); // Op0 = the scalar
Scott Michel266bc8f2007-12-04 22:23:35 +00001871
Gabor Greifba36cb52008-08-28 21:40:38 +00001872 if (Op0.getNode()->getOpcode() == ISD::Constant) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001873 // For a constant, build the appropriate constant vector, which will
1874 // eventually simplify to a vector register load.
1875
Gabor Greifba36cb52008-08-28 21:40:38 +00001876 ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getNode());
Dan Gohman475871a2008-07-27 21:46:04 +00001877 SmallVector<SDValue, 16> ConstVecValues;
Duncan Sands83ec4b62008-06-06 12:08:01 +00001878 MVT VT;
Scott Michel266bc8f2007-12-04 22:23:35 +00001879 size_t n_copies;
1880
1881 // Create a constant vector:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001882 switch (Op.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001883 default: assert(0 && "Unexpected constant value type in "
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001884 "LowerSCALAR_TO_VECTOR");
Scott Michel266bc8f2007-12-04 22:23:35 +00001885 case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
1886 case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
1887 case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
1888 case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
1889 case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
1890 case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
1891 }
1892
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00001893 SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
Scott Michel266bc8f2007-12-04 22:23:35 +00001894 for (size_t j = 0; j < n_copies; ++j)
1895 ConstVecValues.push_back(CValue);
1896
1897 return DAG.getNode(ISD::BUILD_VECTOR, Op.getValueType(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00001898 &ConstVecValues[0], ConstVecValues.size());
Scott Michel266bc8f2007-12-04 22:23:35 +00001899 } else {
1900 // Otherwise, copy the value from one register to another:
Duncan Sands83ec4b62008-06-06 12:08:01 +00001901 switch (Op0.getValueType().getSimpleVT()) {
Scott Michel266bc8f2007-12-04 22:23:35 +00001902 default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
1903 case MVT::i8:
1904 case MVT::i16:
1905 case MVT::i32:
1906 case MVT::i64:
1907 case MVT::f32:
1908 case MVT::f64:
Scott Michelf0569be2008-12-27 04:51:36 +00001909 return DAG.getNode(SPUISD::PREFSLOT2VEC, Op.getValueType(), Op0, Op0);
Scott Michel266bc8f2007-12-04 22:23:35 +00001910 }
1911 }
1912
Dan Gohman475871a2008-07-27 21:46:04 +00001913 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001914}
1915
Dan Gohman475871a2008-07-27 21:46:04 +00001916static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00001917 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +00001918 SDValue N = Op.getOperand(0);
1919 SDValue Elt = Op.getOperand(1);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001920 SDValue retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00001921
Scott Michel7a1c9e92008-11-22 23:50:42 +00001922 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Elt)) {
1923 // Constant argument:
1924 int EltNo = (int) C->getZExtValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00001925
Scott Michel7a1c9e92008-11-22 23:50:42 +00001926 // sanity checks:
1927 if (VT == MVT::i8 && EltNo >= 16)
1928 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
1929 else if (VT == MVT::i16 && EltNo >= 8)
1930 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
1931 else if (VT == MVT::i32 && EltNo >= 4)
1932 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
1933 else if (VT == MVT::i64 && EltNo >= 2)
1934 assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
Scott Michel266bc8f2007-12-04 22:23:35 +00001935
Scott Michel7a1c9e92008-11-22 23:50:42 +00001936 if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
1937 // i32 and i64: Element 0 is the preferred slot
Scott Michel104de432008-11-24 17:11:17 +00001938 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, N);
Scott Michel7a1c9e92008-11-22 23:50:42 +00001939 }
Scott Michel266bc8f2007-12-04 22:23:35 +00001940
Scott Michel7a1c9e92008-11-22 23:50:42 +00001941 // Need to generate shuffle mask and extract:
1942 int prefslot_begin = -1, prefslot_end = -1;
1943 int elt_byte = EltNo * VT.getSizeInBits() / 8;
1944
1945 switch (VT.getSimpleVT()) {
1946 default:
1947 assert(false && "Invalid value type!");
1948 case MVT::i8: {
1949 prefslot_begin = prefslot_end = 3;
1950 break;
1951 }
1952 case MVT::i16: {
1953 prefslot_begin = 2; prefslot_end = 3;
1954 break;
1955 }
1956 case MVT::i32:
1957 case MVT::f32: {
1958 prefslot_begin = 0; prefslot_end = 3;
1959 break;
1960 }
1961 case MVT::i64:
1962 case MVT::f64: {
1963 prefslot_begin = 0; prefslot_end = 7;
1964 break;
1965 }
1966 }
1967
1968 assert(prefslot_begin != -1 && prefslot_end != -1 &&
1969 "LowerEXTRACT_VECTOR_ELT: preferred slots uninitialized");
1970
1971 unsigned int ShufBytes[16];
1972 for (int i = 0; i < 16; ++i) {
1973 // zero fill uppper part of preferred slot, don't care about the
1974 // other slots:
1975 unsigned int mask_val;
1976 if (i <= prefslot_end) {
1977 mask_val =
1978 ((i < prefslot_begin)
1979 ? 0x80
1980 : elt_byte + (i - prefslot_begin));
1981
1982 ShufBytes[i] = mask_val;
1983 } else
1984 ShufBytes[i] = ShufBytes[i % (prefslot_end + 1)];
1985 }
1986
1987 SDValue ShufMask[4];
1988 for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) {
Scott Michelcc188272008-12-04 21:01:44 +00001989 unsigned bidx = i * 4;
Scott Michel7a1c9e92008-11-22 23:50:42 +00001990 unsigned int bits = ((ShufBytes[bidx] << 24) |
1991 (ShufBytes[bidx+1] << 16) |
1992 (ShufBytes[bidx+2] << 8) |
1993 ShufBytes[bidx+3]);
1994 ShufMask[i] = DAG.getConstant(bits, MVT::i32);
1995 }
1996
1997 SDValue ShufMaskVec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
1998 &ShufMask[0],
1999 sizeof(ShufMask) / sizeof(ShufMask[0]));
2000
Scott Michel104de432008-11-24 17:11:17 +00002001 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel7a1c9e92008-11-22 23:50:42 +00002002 DAG.getNode(SPUISD::SHUFB, N.getValueType(),
2003 N, N, ShufMaskVec));
2004 } else {
2005 // Variable index: Rotate the requested element into slot 0, then replicate
2006 // slot 0 across the vector
2007 MVT VecVT = N.getValueType();
2008 if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
2009 cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
2010 abort();
2011 }
2012
2013 // Make life easier by making sure the index is zero-extended to i32
2014 if (Elt.getValueType() != MVT::i32)
2015 Elt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Elt);
2016
2017 // Scale the index to a bit/byte shift quantity
2018 APInt scaleFactor =
Scott Michel104de432008-11-24 17:11:17 +00002019 APInt(32, uint64_t(16 / N.getValueType().getVectorNumElements()), false);
2020 unsigned scaleShift = scaleFactor.logBase2();
Scott Michel7a1c9e92008-11-22 23:50:42 +00002021 SDValue vecShift;
Scott Michel7a1c9e92008-11-22 23:50:42 +00002022
Scott Michel104de432008-11-24 17:11:17 +00002023 if (scaleShift > 0) {
2024 // Scale the shift factor:
Scott Michel7a1c9e92008-11-22 23:50:42 +00002025 Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002026 DAG.getConstant(scaleShift, MVT::i32));
Scott Michel7a1c9e92008-11-22 23:50:42 +00002027 }
2028
Scott Michel104de432008-11-24 17:11:17 +00002029 vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt);
2030
2031 // Replicate the bytes starting at byte 0 across the entire vector (for
2032 // consistency with the notion of a unified register set)
Scott Michel7a1c9e92008-11-22 23:50:42 +00002033 SDValue replicate;
2034
2035 switch (VT.getSimpleVT()) {
2036 default:
2037 cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
2038 abort();
2039 /*NOTREACHED*/
2040 case MVT::i8: {
Scott Michel104de432008-11-24 17:11:17 +00002041 SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002042 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2043 factor, factor);
2044 break;
2045 }
2046 case MVT::i16: {
Scott Michel104de432008-11-24 17:11:17 +00002047 SDValue factor = DAG.getConstant(0x00010001, MVT::i32);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002048 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2049 factor, factor);
2050 break;
2051 }
2052 case MVT::i32:
2053 case MVT::f32: {
2054 SDValue factor = DAG.getConstant(0x00010203, MVT::i32);
2055 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, factor, factor,
2056 factor, factor);
2057 break;
2058 }
2059 case MVT::i64:
2060 case MVT::f64: {
2061 SDValue loFactor = DAG.getConstant(0x00010203, MVT::i32);
2062 SDValue hiFactor = DAG.getConstant(0x04050607, MVT::i32);
2063 replicate = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, loFactor, hiFactor,
2064 loFactor, hiFactor);
2065 break;
2066 }
2067 }
2068
Scott Michel104de432008-11-24 17:11:17 +00002069 retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
Scott Michel1a6cdb62008-12-01 17:56:02 +00002070 DAG.getNode(SPUISD::SHUFB, VecVT,
2071 vecShift, vecShift, replicate));
Scott Michel266bc8f2007-12-04 22:23:35 +00002072 }
2073
Scott Michel7a1c9e92008-11-22 23:50:42 +00002074 return retval;
Scott Michel266bc8f2007-12-04 22:23:35 +00002075}
2076
Dan Gohman475871a2008-07-27 21:46:04 +00002077static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
2078 SDValue VecOp = Op.getOperand(0);
2079 SDValue ValOp = Op.getOperand(1);
2080 SDValue IdxOp = Op.getOperand(2);
Duncan Sands83ec4b62008-06-06 12:08:01 +00002081 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002082
2083 ConstantSDNode *CN = cast<ConstantSDNode>(IdxOp);
2084 assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!");
2085
Duncan Sands83ec4b62008-06-06 12:08:01 +00002086 MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
Scott Michel1a6cdb62008-12-01 17:56:02 +00002087 // Use $sp ($1) because it's always 16-byte aligned and it's available:
2088 SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT,
2089 DAG.getRegister(SPU::R1, PtrVT),
2090 DAG.getConstant(CN->getSExtValue(), PtrVT));
2091 SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer);
Scott Michel266bc8f2007-12-04 22:23:35 +00002092
Dan Gohman475871a2008-07-27 21:46:04 +00002093 SDValue result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002094 DAG.getNode(SPUISD::SHUFB, VT,
2095 DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp),
Scott Michel1df30c42008-12-29 03:23:36 +00002096 VecOp,
Scott Michel19c10e62009-01-26 03:37:41 +00002097 DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask));
Scott Michel266bc8f2007-12-04 22:23:35 +00002098
2099 return result;
2100}
2101
Scott Michelf0569be2008-12-27 04:51:36 +00002102static SDValue LowerI8Math(SDValue Op, SelectionDAG &DAG, unsigned Opc,
2103 const TargetLowering &TLI)
Scott Michela59d4692008-02-23 18:41:37 +00002104{
Dan Gohman475871a2008-07-27 21:46:04 +00002105 SDValue N0 = Op.getOperand(0); // Everything has at least one operand
Scott Michelf0569be2008-12-27 04:51:36 +00002106 MVT ShiftVT = TLI.getShiftAmountTy();
Scott Michel266bc8f2007-12-04 22:23:35 +00002107
2108 assert(Op.getValueType() == MVT::i8);
2109 switch (Opc) {
2110 default:
2111 assert(0 && "Unhandled i8 math operator");
2112 /*NOTREACHED*/
2113 break;
Scott Michel02d711b2008-12-30 23:28:25 +00002114 case ISD::ADD: {
2115 // 8-bit addition: Promote the arguments up to 16-bits and truncate
2116 // the result:
2117 SDValue N1 = Op.getOperand(1);
2118 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2119 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
2120 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
2121 DAG.getNode(Opc, MVT::i16, N0, N1));
2122
2123 }
2124
Scott Michel266bc8f2007-12-04 22:23:35 +00002125 case ISD::SUB: {
2126 // 8-bit subtraction: Promote the arguments up to 16-bits and truncate
2127 // the result:
Dan Gohman475871a2008-07-27 21:46:04 +00002128 SDValue N1 = Op.getOperand(1);
Scott Michel02d711b2008-12-30 23:28:25 +00002129 N0 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0);
2130 N1 = DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N1);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002131 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002132 DAG.getNode(Opc, MVT::i16, N0, N1));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002133 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002134 case ISD::ROTR:
2135 case ISD::ROTL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002136 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002137 unsigned N1Opc;
2138 N0 = (N0.getOpcode() != ISD::Constant
2139 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002140 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2141 MVT::i16));
Scott Michelf0569be2008-12-27 04:51:36 +00002142 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002143 ? ISD::ZERO_EXTEND
2144 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002145 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002146 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002147 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002148 TLI.getShiftAmountTy()));
Dan Gohman475871a2008-07-27 21:46:04 +00002149 SDValue ExpandArg =
Scott Michel266bc8f2007-12-04 22:23:35 +00002150 DAG.getNode(ISD::OR, MVT::i16, N0,
2151 DAG.getNode(ISD::SHL, MVT::i16,
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002152 N0, DAG.getConstant(8, MVT::i32)));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002153 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002154 DAG.getNode(Opc, MVT::i16, ExpandArg, N1));
2155 }
2156 case ISD::SRL:
2157 case ISD::SHL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002158 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002159 unsigned N1Opc;
2160 N0 = (N0.getOpcode() != ISD::Constant
2161 ? DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002162 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002163 MVT::i32));
2164 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002165 ? ISD::ZERO_EXTEND
2166 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002167 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002168 ? DAG.getNode(N1Opc, ShiftVT, N1)
2169 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(), ShiftVT));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002170 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002171 DAG.getNode(Opc, MVT::i16, N0, N1));
2172 }
2173 case ISD::SRA: {
Dan Gohman475871a2008-07-27 21:46:04 +00002174 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002175 unsigned N1Opc;
2176 N0 = (N0.getOpcode() != ISD::Constant
2177 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Scott Michelf0569be2008-12-27 04:51:36 +00002178 : DAG.getConstant(cast<ConstantSDNode>(N0)->getSExtValue(),
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002179 MVT::i16));
Scott Michelf0569be2008-12-27 04:51:36 +00002180 N1Opc = N1.getValueType().bitsLT(ShiftVT)
Gabor Greif93c53e52008-08-31 15:37:04 +00002181 ? ISD::SIGN_EXTEND
2182 : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002183 N1 = (N1.getOpcode() != ISD::Constant
Scott Michelf0569be2008-12-27 04:51:36 +00002184 ? DAG.getNode(N1Opc, ShiftVT, N1)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002185 : DAG.getConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
Scott Michelf0569be2008-12-27 04:51:36 +00002186 ShiftVT));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002187 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002188 DAG.getNode(Opc, MVT::i16, N0, N1));
2189 }
2190 case ISD::MUL: {
Dan Gohman475871a2008-07-27 21:46:04 +00002191 SDValue N1 = Op.getOperand(1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002192 unsigned N1Opc;
2193 N0 = (N0.getOpcode() != ISD::Constant
2194 ? DAG.getNode(ISD::SIGN_EXTEND, MVT::i16, N0)
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002195 : DAG.getConstant(cast<ConstantSDNode>(N0)->getZExtValue(),
2196 MVT::i16));
Duncan Sands8e4eb092008-06-08 20:54:56 +00002197 N1Opc = N1.getValueType().bitsLT(MVT::i16) ? ISD::SIGN_EXTEND : ISD::TRUNCATE;
Scott Michel266bc8f2007-12-04 22:23:35 +00002198 N1 = (N1.getOpcode() != ISD::Constant
2199 ? DAG.getNode(N1Opc, MVT::i16, N1)
Scott Michelf0569be2008-12-27 04:51:36 +00002200 : DAG.getConstant(cast<ConstantSDNode>(N1)->getSExtValue(),
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +00002201 MVT::i16));
Scott Michel5af8f0e2008-07-16 17:17:29 +00002202 return DAG.getNode(ISD::TRUNCATE, MVT::i8,
Scott Michel266bc8f2007-12-04 22:23:35 +00002203 DAG.getNode(Opc, MVT::i16, N0, N1));
2204 break;
2205 }
2206 }
2207
Dan Gohman475871a2008-07-27 21:46:04 +00002208 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002209}
2210
Scott Michel94bd57e2009-01-15 04:41:47 +00002211//! Generate the carry-generate shuffle mask.
2212SDValue SPU::getCarryGenerateShufMask(SelectionDAG &DAG) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002213 SmallVector<SDValue, 16 > ShufBytes;
Scott Michela59d4692008-02-23 18:41:37 +00002214
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002215 // Create the shuffle mask for "rotating" the borrow up one register slot
2216 // once the borrow is generated.
2217 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2218 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
2219 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2220 ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
Scott Michela59d4692008-02-23 18:41:37 +00002221
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002222 return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2223 &ShufBytes[0], ShufBytes.size());
Scott Michel94bd57e2009-01-15 04:41:47 +00002224}
Scott Michela59d4692008-02-23 18:41:37 +00002225
Scott Michel94bd57e2009-01-15 04:41:47 +00002226//! Generate the borrow-generate shuffle mask
2227SDValue SPU::getBorrowGenerateShufMask(SelectionDAG &DAG) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002228 SmallVector<SDValue, 16 > ShufBytes;
Scott Michela59d4692008-02-23 18:41:37 +00002229
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002230 // Create the shuffle mask for "rotating" the borrow up one register slot
2231 // once the borrow is generated.
2232 ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
2233 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2234 ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
2235 ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
Scott Michel045a1452008-11-24 18:20:46 +00002236
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002237 return DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2238 &ShufBytes[0], ShufBytes.size());
Scott Michela59d4692008-02-23 18:41:37 +00002239}
2240
Scott Michel266bc8f2007-12-04 22:23:35 +00002241//! Lower byte immediate operations for v16i8 vectors:
Dan Gohman475871a2008-07-27 21:46:04 +00002242static SDValue
2243LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
2244 SDValue ConstVec;
2245 SDValue Arg;
Duncan Sands83ec4b62008-06-06 12:08:01 +00002246 MVT VT = Op.getValueType();
Scott Michel266bc8f2007-12-04 22:23:35 +00002247
2248 ConstVec = Op.getOperand(0);
2249 Arg = Op.getOperand(1);
Gabor Greifba36cb52008-08-28 21:40:38 +00002250 if (ConstVec.getNode()->getOpcode() != ISD::BUILD_VECTOR) {
2251 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002252 ConstVec = ConstVec.getOperand(0);
2253 } else {
2254 ConstVec = Op.getOperand(1);
2255 Arg = Op.getOperand(0);
Gabor Greifba36cb52008-08-28 21:40:38 +00002256 if (ConstVec.getNode()->getOpcode() == ISD::BIT_CONVERT) {
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002257 ConstVec = ConstVec.getOperand(0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002258 }
2259 }
2260 }
2261
Gabor Greifba36cb52008-08-28 21:40:38 +00002262 if (ConstVec.getNode()->getOpcode() == ISD::BUILD_VECTOR) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002263 uint64_t VectorBits[2];
2264 uint64_t UndefBits[2];
2265 uint64_t SplatBits, SplatUndef;
2266 int SplatSize;
2267
Gabor Greifba36cb52008-08-28 21:40:38 +00002268 if (!GetConstantBuildVectorBits(ConstVec.getNode(), VectorBits, UndefBits)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002269 && isConstantSplat(VectorBits, UndefBits,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002270 VT.getVectorElementType().getSizeInBits(),
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002271 SplatBits, SplatUndef, SplatSize)) {
Dan Gohman475871a2008-07-27 21:46:04 +00002272 SDValue tcVec[16];
2273 SDValue tc = DAG.getTargetConstant(SplatBits & 0xff, MVT::i8);
Scott Michel266bc8f2007-12-04 22:23:35 +00002274 const size_t tcVecSize = sizeof(tcVec) / sizeof(tcVec[0]);
2275
2276 // Turn the BUILD_VECTOR into a set of target constants:
2277 for (size_t i = 0; i < tcVecSize; ++i)
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002278 tcVec[i] = tc;
Scott Michel266bc8f2007-12-04 22:23:35 +00002279
Gabor Greifba36cb52008-08-28 21:40:38 +00002280 return DAG.getNode(Op.getNode()->getOpcode(), VT, Arg,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002281 DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
Scott Michel266bc8f2007-12-04 22:23:35 +00002282 }
2283 }
Scott Michel9de57a92009-01-26 22:33:37 +00002284
Nate Begeman24dc3462008-07-29 19:07:27 +00002285 // These operations (AND, OR, XOR) are legal, they just couldn't be custom
2286 // lowered. Return the operation, rather than a null SDValue.
2287 return Op;
Scott Michel266bc8f2007-12-04 22:23:35 +00002288}
2289
Scott Michel266bc8f2007-12-04 22:23:35 +00002290//! Custom lowering for CTPOP (count population)
2291/*!
2292 Custom lowering code that counts the number ones in the input
2293 operand. SPU has such an instruction, but it counts the number of
2294 ones per byte, which then have to be accumulated.
2295*/
Dan Gohman475871a2008-07-27 21:46:04 +00002296static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
Duncan Sands83ec4b62008-06-06 12:08:01 +00002297 MVT VT = Op.getValueType();
2298 MVT vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
Scott Michel266bc8f2007-12-04 22:23:35 +00002299
Duncan Sands83ec4b62008-06-06 12:08:01 +00002300 switch (VT.getSimpleVT()) {
2301 default:
2302 assert(false && "Invalid value type!");
Scott Michel266bc8f2007-12-04 22:23:35 +00002303 case MVT::i8: {
Dan Gohman475871a2008-07-27 21:46:04 +00002304 SDValue N = Op.getOperand(0);
2305 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002306
Scott Michelf0569be2008-12-27 04:51:36 +00002307 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002308 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002309
2310 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i8, CNTB, Elt0);
2311 }
2312
2313 case MVT::i16: {
2314 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002315 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002316
Chris Lattner84bc5422007-12-31 04:13:23 +00002317 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002318
Dan Gohman475871a2008-07-27 21:46:04 +00002319 SDValue N = Op.getOperand(0);
2320 SDValue Elt0 = DAG.getConstant(0, MVT::i16);
2321 SDValue Mask0 = DAG.getConstant(0x0f, MVT::i16);
Duncan Sandsfa7935f2008-10-30 19:24:28 +00002322 SDValue Shift1 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002323
Scott Michelf0569be2008-12-27 04:51:36 +00002324 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002325 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002326
2327 // CNTB_result becomes the chain to which all of the virtual registers
2328 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002329 SDValue CNTB_result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002330 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002331
Dan Gohman475871a2008-07-27 21:46:04 +00002332 SDValue CNTB_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002333 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2334
Dan Gohman475871a2008-07-27 21:46:04 +00002335 SDValue Tmp1 = DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i16);
Scott Michel266bc8f2007-12-04 22:23:35 +00002336
2337 return DAG.getNode(ISD::AND, MVT::i16,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002338 DAG.getNode(ISD::ADD, MVT::i16,
2339 DAG.getNode(ISD::SRL, MVT::i16,
2340 Tmp1, Shift1),
2341 Tmp1),
2342 Mask0);
Scott Michel266bc8f2007-12-04 22:23:35 +00002343 }
2344
2345 case MVT::i32: {
2346 MachineFunction &MF = DAG.getMachineFunction();
Chris Lattner84bc5422007-12-31 04:13:23 +00002347 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Scott Michel266bc8f2007-12-04 22:23:35 +00002348
Chris Lattner84bc5422007-12-31 04:13:23 +00002349 unsigned CNTB_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
2350 unsigned SUM1_reg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
Scott Michel266bc8f2007-12-04 22:23:35 +00002351
Dan Gohman475871a2008-07-27 21:46:04 +00002352 SDValue N = Op.getOperand(0);
2353 SDValue Elt0 = DAG.getConstant(0, MVT::i32);
2354 SDValue Mask0 = DAG.getConstant(0xff, MVT::i32);
2355 SDValue Shift1 = DAG.getConstant(16, MVT::i32);
2356 SDValue Shift2 = DAG.getConstant(8, MVT::i32);
Scott Michel266bc8f2007-12-04 22:23:35 +00002357
Scott Michelf0569be2008-12-27 04:51:36 +00002358 SDValue Promote = DAG.getNode(SPUISD::PREFSLOT2VEC, vecVT, N, N);
Dan Gohman475871a2008-07-27 21:46:04 +00002359 SDValue CNTB = DAG.getNode(SPUISD::CNTB, vecVT, Promote);
Scott Michel266bc8f2007-12-04 22:23:35 +00002360
2361 // CNTB_result becomes the chain to which all of the virtual registers
2362 // CNTB_reg, SUM1_reg become associated:
Dan Gohman475871a2008-07-27 21:46:04 +00002363 SDValue CNTB_result =
Scott Michel266bc8f2007-12-04 22:23:35 +00002364 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32, CNTB, Elt0);
Scott Michel5af8f0e2008-07-16 17:17:29 +00002365
Dan Gohman475871a2008-07-27 21:46:04 +00002366 SDValue CNTB_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002367 DAG.getCopyToReg(CNTB_result, CNTB_reg, CNTB_result);
2368
Dan Gohman475871a2008-07-27 21:46:04 +00002369 SDValue Comp1 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002370 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002371 DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32), Shift1);
Scott Michel266bc8f2007-12-04 22:23:35 +00002372
Dan Gohman475871a2008-07-27 21:46:04 +00002373 SDValue Sum1 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002374 DAG.getNode(ISD::ADD, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002375 Comp1, DAG.getCopyFromReg(CNTB_rescopy, CNTB_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002376
Dan Gohman475871a2008-07-27 21:46:04 +00002377 SDValue Sum1_rescopy =
Scott Michel266bc8f2007-12-04 22:23:35 +00002378 DAG.getCopyToReg(CNTB_result, SUM1_reg, Sum1);
2379
Dan Gohman475871a2008-07-27 21:46:04 +00002380 SDValue Comp2 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002381 DAG.getNode(ISD::SRL, MVT::i32,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002382 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32),
2383 Shift2);
Dan Gohman475871a2008-07-27 21:46:04 +00002384 SDValue Sum2 =
Scott Michel266bc8f2007-12-04 22:23:35 +00002385 DAG.getNode(ISD::ADD, MVT::i32, Comp2,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00002386 DAG.getCopyFromReg(Sum1_rescopy, SUM1_reg, MVT::i32));
Scott Michel266bc8f2007-12-04 22:23:35 +00002387
2388 return DAG.getNode(ISD::AND, MVT::i32, Sum2, Mask0);
2389 }
2390
2391 case MVT::i64:
2392 break;
2393 }
2394
Dan Gohman475871a2008-07-27 21:46:04 +00002395 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002396}
2397
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002398//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002399/*!
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002400 f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall.
2401 All conversions to i64 are expanded to a libcall.
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002402 */
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002403static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
2404 SPUTargetLowering &TLI) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002405 MVT OpVT = Op.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002406 SDValue Op0 = Op.getOperand(0);
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002407 MVT Op0VT = Op0.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002408
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002409 if ((OpVT == MVT::i32 && Op0VT == MVT::f64)
2410 || OpVT == MVT::i64) {
2411 // Convert f32 / f64 to i32 / i64 via libcall.
2412 RTLIB::Libcall LC =
2413 (Op.getOpcode() == ISD::FP_TO_SINT)
2414 ? RTLIB::getFPTOSINT(Op0VT, OpVT)
2415 : RTLIB::getFPTOUINT(Op0VT, OpVT);
2416 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!");
2417 SDValue Dummy;
2418 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2419 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002420
Scott Michel9de57a92009-01-26 22:33:37 +00002421 return Op; // return unmolested, legalized op
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002422}
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002423
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002424//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
2425/*!
2426 i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall.
2427 All conversions from i64 are expanded to a libcall.
2428 */
2429static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
2430 SPUTargetLowering &TLI) {
2431 MVT OpVT = Op.getValueType();
2432 SDValue Op0 = Op.getOperand(0);
2433 MVT Op0VT = Op0.getValueType();
2434
2435 if ((OpVT == MVT::f64 && Op0VT == MVT::i32)
2436 || Op0VT == MVT::i64) {
2437 // Convert i32, i64 to f64 via libcall:
2438 RTLIB::Libcall LC =
2439 (Op.getOpcode() == ISD::SINT_TO_FP)
2440 ? RTLIB::getSINTTOFP(Op0VT, OpVT)
2441 : RTLIB::getUINTTOFP(Op0VT, OpVT);
2442 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!");
2443 SDValue Dummy;
2444 return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
2445 }
2446
Scott Michel9de57a92009-01-26 22:33:37 +00002447 return Op; // return unmolested, legalized
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002448}
2449
2450//! Lower ISD::SETCC
2451/*!
2452 This handles MVT::f64 (double floating point) condition lowering
2453 */
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002454static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG,
2455 const TargetLowering &TLI) {
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002456 CondCodeSDNode *CC = dyn_cast<CondCodeSDNode>(Op.getOperand(2));
2457 assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n");
2458
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002459 SDValue lhs = Op.getOperand(0);
2460 SDValue rhs = Op.getOperand(1);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002461 MVT lhsVT = lhs.getValueType();
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002462 assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n");
2463
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002464 MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType());
2465 APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2466 MVT IntVT(MVT::i64);
2467
2468 // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently
2469 // selected to a NOP:
2470 SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, lhs);
2471 SDValue lhsHi32 =
2472 DAG.getNode(ISD::TRUNCATE, MVT::i32,
2473 DAG.getNode(ISD::SRL, IntVT,
2474 i64lhs, DAG.getConstant(32, MVT::i32)));
2475 SDValue lhsHi32abs =
2476 DAG.getNode(ISD::AND, MVT::i32,
2477 lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32));
2478 SDValue lhsLo32 =
2479 DAG.getNode(ISD::TRUNCATE, MVT::i32, i64lhs);
2480
2481 // SETO and SETUO only use the lhs operand:
2482 if (CC->get() == ISD::SETO) {
2483 // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of
2484 // SETUO
2485 APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits());
2486 return DAG.getNode(ISD::XOR, ccResultVT,
2487 DAG.getSetCC(ccResultVT,
2488 lhs, DAG.getConstantFP(0.0, lhsVT),
2489 ISD::SETUO),
2490 DAG.getConstant(ccResultAllOnes, ccResultVT));
2491 } else if (CC->get() == ISD::SETUO) {
2492 // Evaluates to true if Op0 is [SQ]NaN
2493 return DAG.getNode(ISD::AND, ccResultVT,
2494 DAG.getSetCC(ccResultVT,
2495 lhsHi32abs,
2496 DAG.getConstant(0x7ff00000, MVT::i32),
2497 ISD::SETGE),
2498 DAG.getSetCC(ccResultVT,
2499 lhsLo32,
2500 DAG.getConstant(0, MVT::i32),
2501 ISD::SETGT));
2502 }
2503
2504 SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, rhs);
2505 SDValue rhsHi32 =
2506 DAG.getNode(ISD::TRUNCATE, MVT::i32,
2507 DAG.getNode(ISD::SRL, IntVT,
2508 i64rhs, DAG.getConstant(32, MVT::i32)));
2509
2510 // If a value is negative, subtract from the sign magnitude constant:
2511 SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT);
2512
2513 // Convert the sign-magnitude representation into 2's complement:
2514 SDValue lhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT,
2515 lhsHi32, DAG.getConstant(31, MVT::i32));
2516 SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64lhs);
2517 SDValue lhsSelect =
2518 DAG.getNode(ISD::SELECT, IntVT,
2519 lhsSelectMask, lhsSignMag2TC, i64lhs);
2520
2521 SDValue rhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT,
2522 rhsHi32, DAG.getConstant(31, MVT::i32));
2523 SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64rhs);
2524 SDValue rhsSelect =
2525 DAG.getNode(ISD::SELECT, IntVT,
2526 rhsSelectMask, rhsSignMag2TC, i64rhs);
2527
2528 unsigned compareOp;
2529
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002530 switch (CC->get()) {
2531 case ISD::SETOEQ:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002532 case ISD::SETUEQ:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002533 compareOp = ISD::SETEQ; break;
2534 case ISD::SETOGT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002535 case ISD::SETUGT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002536 compareOp = ISD::SETGT; break;
2537 case ISD::SETOGE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002538 case ISD::SETUGE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002539 compareOp = ISD::SETGE; break;
2540 case ISD::SETOLT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002541 case ISD::SETULT:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002542 compareOp = ISD::SETLT; break;
2543 case ISD::SETOLE:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002544 case ISD::SETULE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002545 compareOp = ISD::SETLE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002546 case ISD::SETUNE:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002547 case ISD::SETONE:
2548 compareOp = ISD::SETNE; break;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002549 default:
2550 cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
2551 abort();
2552 break;
2553 }
2554
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002555 SDValue result =
2556 DAG.getSetCC(ccResultVT, lhsSelect, rhsSelect, (ISD::CondCode) compareOp);
2557
2558 if ((CC->get() & 0x8) == 0) {
2559 // Ordered comparison:
2560 SDValue lhsNaN = DAG.getSetCC(ccResultVT,
2561 lhs, DAG.getConstantFP(0.0, MVT::f64),
2562 ISD::SETO);
2563 SDValue rhsNaN = DAG.getSetCC(ccResultVT,
2564 rhs, DAG.getConstantFP(0.0, MVT::f64),
2565 ISD::SETO);
2566 SDValue ordered = DAG.getNode(ISD::AND, ccResultVT, lhsNaN, rhsNaN);
2567
2568 result = DAG.getNode(ISD::AND, ccResultVT, ordered, result);
2569 }
2570
2571 return result;
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002572}
2573
Scott Michel7a1c9e92008-11-22 23:50:42 +00002574//! Lower ISD::SELECT_CC
2575/*!
2576 ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
2577 SELB instruction.
2578
2579 \note Need to revisit this in the future: if the code path through the true
2580 and false value computations is longer than the latency of a branch (6
2581 cycles), then it would be more advantageous to branch and insert a new basic
2582 block and branch on the condition. However, this code does not make that
2583 assumption, given the simplisitc uses so far.
2584 */
2585
Scott Michelf0569be2008-12-27 04:51:36 +00002586static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
2587 const TargetLowering &TLI) {
Scott Michel7a1c9e92008-11-22 23:50:42 +00002588 MVT VT = Op.getValueType();
2589 SDValue lhs = Op.getOperand(0);
2590 SDValue rhs = Op.getOperand(1);
2591 SDValue trueval = Op.getOperand(2);
2592 SDValue falseval = Op.getOperand(3);
2593 SDValue condition = Op.getOperand(4);
2594
Scott Michelf0569be2008-12-27 04:51:36 +00002595 // NOTE: SELB's arguments: $rA, $rB, $mask
2596 //
2597 // SELB selects bits from $rA where bits in $mask are 0, bits from $rB
2598 // where bits in $mask are 1. CCond will be inverted, having 1s where the
2599 // condition was true and 0s where the condition was false. Hence, the
2600 // arguments to SELB get reversed.
2601
Scott Michel7a1c9e92008-11-22 23:50:42 +00002602 // Note: Really should be ISD::SELECT instead of SPUISD::SELB, but LLVM's
2603 // legalizer insists on combining SETCC/SELECT into SELECT_CC, so we end up
2604 // with another "cannot select select_cc" assert:
2605
Duncan Sands5480c042009-01-01 15:52:00 +00002606 SDValue compare = DAG.getNode(ISD::SETCC,
2607 TLI.getSetCCResultType(Op.getValueType()),
Scott Michelf0569be2008-12-27 04:51:36 +00002608 lhs, rhs, condition);
2609 return DAG.getNode(SPUISD::SELB, VT, falseval, trueval, compare);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002610}
2611
Scott Michelb30e8f62008-12-02 19:53:53 +00002612//! Custom lower ISD::TRUNCATE
2613static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG)
2614{
2615 MVT VT = Op.getValueType();
2616 MVT::SimpleValueType simpleVT = VT.getSimpleVT();
2617 MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits()));
2618
2619 SDValue Op0 = Op.getOperand(0);
2620 MVT Op0VT = Op0.getValueType();
2621 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
2622
Scott Michelf0569be2008-12-27 04:51:36 +00002623 if (Op0VT.getSimpleVT() == MVT::i128 && simpleVT == MVT::i64) {
Scott Michel52d00012009-01-03 00:27:53 +00002624 // Create shuffle mask, least significant doubleword of quadword
Scott Michelf0569be2008-12-27 04:51:36 +00002625 unsigned maskHigh = 0x08090a0b;
2626 unsigned maskLow = 0x0c0d0e0f;
2627 // Use a shuffle to perform the truncation
2628 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
2629 DAG.getConstant(maskHigh, MVT::i32),
2630 DAG.getConstant(maskLow, MVT::i32),
2631 DAG.getConstant(maskHigh, MVT::i32),
2632 DAG.getConstant(maskLow, MVT::i32));
2633
2634
2635 SDValue PromoteScalar = DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
2636
2637 SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
2638 PromoteScalar, PromoteScalar, shufMask);
2639
2640 return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
2641 DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle));
Scott Michelb30e8f62008-12-02 19:53:53 +00002642 }
2643
Scott Michelf0569be2008-12-27 04:51:36 +00002644 return SDValue(); // Leave the truncate unmolested
Scott Michelb30e8f62008-12-02 19:53:53 +00002645}
2646
Scott Michel7a1c9e92008-11-22 23:50:42 +00002647//! Custom (target-specific) lowering entry point
2648/*!
2649 This is where LLVM's DAG selection process calls to do target-specific
2650 lowering of nodes.
2651 */
Dan Gohman475871a2008-07-27 21:46:04 +00002652SDValue
2653SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
Scott Michel266bc8f2007-12-04 22:23:35 +00002654{
Scott Michela59d4692008-02-23 18:41:37 +00002655 unsigned Opc = (unsigned) Op.getOpcode();
Duncan Sands83ec4b62008-06-06 12:08:01 +00002656 MVT VT = Op.getValueType();
Scott Michela59d4692008-02-23 18:41:37 +00002657
2658 switch (Opc) {
Scott Michel266bc8f2007-12-04 22:23:35 +00002659 default: {
2660 cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
Scott Michela59d4692008-02-23 18:41:37 +00002661 cerr << "Op.getOpcode() = " << Opc << "\n";
Gabor Greifba36cb52008-08-28 21:40:38 +00002662 cerr << "*Op.getNode():\n";
2663 Op.getNode()->dump();
Scott Michel266bc8f2007-12-04 22:23:35 +00002664 abort();
2665 }
2666 case ISD::LOAD:
Scott Michelb30e8f62008-12-02 19:53:53 +00002667 case ISD::EXTLOAD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002668 case ISD::SEXTLOAD:
2669 case ISD::ZEXTLOAD:
2670 return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl());
2671 case ISD::STORE:
2672 return LowerSTORE(Op, DAG, SPUTM.getSubtargetImpl());
2673 case ISD::ConstantPool:
2674 return LowerConstantPool(Op, DAG, SPUTM.getSubtargetImpl());
2675 case ISD::GlobalAddress:
2676 return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl());
2677 case ISD::JumpTable:
2678 return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002679 case ISD::ConstantFP:
2680 return LowerConstantFP(Op, DAG);
2681 case ISD::FORMAL_ARGUMENTS:
Scott Michel58c58182008-01-17 20:38:41 +00002682 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
Scott Michel266bc8f2007-12-04 22:23:35 +00002683 case ISD::CALL:
Scott Michel9de5d0d2008-01-11 02:53:15 +00002684 return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
Scott Michel266bc8f2007-12-04 22:23:35 +00002685 case ISD::RET:
2686 return LowerRET(Op, DAG, getTargetMachine());
2687
Scott Michel02d711b2008-12-30 23:28:25 +00002688 // i8, i64 math ops:
Scott Michel8bf61e82008-06-02 22:18:03 +00002689 case ISD::ADD:
Scott Michel266bc8f2007-12-04 22:23:35 +00002690 case ISD::SUB:
2691 case ISD::ROTR:
2692 case ISD::ROTL:
2693 case ISD::SRL:
2694 case ISD::SHL:
Scott Michel8bf61e82008-06-02 22:18:03 +00002695 case ISD::SRA: {
Scott Michela59d4692008-02-23 18:41:37 +00002696 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002697 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michela59d4692008-02-23 18:41:37 +00002698 break;
Scott Michel8bf61e82008-06-02 22:18:03 +00002699 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002700
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002701 case ISD::FP_TO_SINT:
2702 case ISD::FP_TO_UINT:
2703 return LowerFP_TO_INT(Op, DAG, *this);
2704
2705 case ISD::SINT_TO_FP:
2706 case ISD::UINT_TO_FP:
2707 return LowerINT_TO_FP(Op, DAG, *this);
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002708
Scott Michel266bc8f2007-12-04 22:23:35 +00002709 // Vector-related lowering.
2710 case ISD::BUILD_VECTOR:
Scott Michelc9c8b2a2009-01-26 03:31:40 +00002711 return LowerBUILD_VECTOR(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002712 case ISD::SCALAR_TO_VECTOR:
2713 return LowerSCALAR_TO_VECTOR(Op, DAG);
2714 case ISD::VECTOR_SHUFFLE:
2715 return LowerVECTOR_SHUFFLE(Op, DAG);
2716 case ISD::EXTRACT_VECTOR_ELT:
2717 return LowerEXTRACT_VECTOR_ELT(Op, DAG);
2718 case ISD::INSERT_VECTOR_ELT:
2719 return LowerINSERT_VECTOR_ELT(Op, DAG);
2720
2721 // Look for ANDBI, ORBI and XORBI opportunities and lower appropriately:
2722 case ISD::AND:
2723 case ISD::OR:
2724 case ISD::XOR:
2725 return LowerByteImmed(Op, DAG);
2726
2727 // Vector and i8 multiply:
2728 case ISD::MUL:
Scott Michel02d711b2008-12-30 23:28:25 +00002729 if (VT == MVT::i8)
Scott Michelf0569be2008-12-27 04:51:36 +00002730 return LowerI8Math(Op, DAG, Opc, *this);
Scott Michel266bc8f2007-12-04 22:23:35 +00002731
Scott Michel266bc8f2007-12-04 22:23:35 +00002732 case ISD::CTPOP:
2733 return LowerCTPOP(Op, DAG);
Scott Michel7a1c9e92008-11-22 23:50:42 +00002734
2735 case ISD::SELECT_CC:
Scott Michelf0569be2008-12-27 04:51:36 +00002736 return LowerSELECT_CC(Op, DAG, *this);
Scott Michelb30e8f62008-12-02 19:53:53 +00002737
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002738 case ISD::SETCC:
2739 return LowerSETCC(Op, DAG, *this);
2740
Scott Michelb30e8f62008-12-02 19:53:53 +00002741 case ISD::TRUNCATE:
2742 return LowerTRUNCATE(Op, DAG);
Scott Michel266bc8f2007-12-04 22:23:35 +00002743 }
2744
Dan Gohman475871a2008-07-27 21:46:04 +00002745 return SDValue();
Scott Michel266bc8f2007-12-04 22:23:35 +00002746}
2747
Duncan Sands1607f052008-12-01 11:39:25 +00002748void SPUTargetLowering::ReplaceNodeResults(SDNode *N,
2749 SmallVectorImpl<SDValue>&Results,
2750 SelectionDAG &DAG)
Scott Michel73ce1c52008-11-10 23:43:06 +00002751{
2752#if 0
2753 unsigned Opc = (unsigned) N->getOpcode();
2754 MVT OpVT = N->getValueType(0);
2755
2756 switch (Opc) {
2757 default: {
2758 cerr << "SPUTargetLowering::ReplaceNodeResults(): need to fix this!\n";
2759 cerr << "Op.getOpcode() = " << Opc << "\n";
2760 cerr << "*Op.getNode():\n";
2761 N->dump();
2762 abort();
2763 /*NOTREACHED*/
2764 }
2765 }
2766#endif
2767
2768 /* Otherwise, return unchanged */
Scott Michel73ce1c52008-11-10 23:43:06 +00002769}
2770
Scott Michel266bc8f2007-12-04 22:23:35 +00002771//===----------------------------------------------------------------------===//
Scott Michel266bc8f2007-12-04 22:23:35 +00002772// Target Optimization Hooks
2773//===----------------------------------------------------------------------===//
2774
Dan Gohman475871a2008-07-27 21:46:04 +00002775SDValue
Scott Michel266bc8f2007-12-04 22:23:35 +00002776SPUTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
2777{
2778#if 0
2779 TargetMachine &TM = getTargetMachine();
Scott Michel053c1da2008-01-29 02:16:57 +00002780#endif
2781 const SPUSubtarget *ST = SPUTM.getSubtargetImpl();
Scott Michel266bc8f2007-12-04 22:23:35 +00002782 SelectionDAG &DAG = DCI.DAG;
Scott Michel1a6cdb62008-12-01 17:56:02 +00002783 SDValue Op0 = N->getOperand(0); // everything has at least one operand
2784 MVT NodeVT = N->getValueType(0); // The node's value type
Scott Michelf0569be2008-12-27 04:51:36 +00002785 MVT Op0VT = Op0.getValueType(); // The first operand's result
Scott Michel1a6cdb62008-12-01 17:56:02 +00002786 SDValue Result; // Initially, empty result
Scott Michel266bc8f2007-12-04 22:23:35 +00002787
2788 switch (N->getOpcode()) {
2789 default: break;
Scott Michel053c1da2008-01-29 02:16:57 +00002790 case ISD::ADD: {
Dan Gohman475871a2008-07-27 21:46:04 +00002791 SDValue Op1 = N->getOperand(1);
Scott Michel053c1da2008-01-29 02:16:57 +00002792
Scott Michelf0569be2008-12-27 04:51:36 +00002793 if (Op0.getOpcode() == SPUISD::IndirectAddr
2794 || Op1.getOpcode() == SPUISD::IndirectAddr) {
2795 // Normalize the operands to reduce repeated code
2796 SDValue IndirectArg = Op0, AddArg = Op1;
Scott Michel1df30c42008-12-29 03:23:36 +00002797
Scott Michelf0569be2008-12-27 04:51:36 +00002798 if (Op1.getOpcode() == SPUISD::IndirectAddr) {
2799 IndirectArg = Op1;
2800 AddArg = Op0;
2801 }
2802
2803 if (isa<ConstantSDNode>(AddArg)) {
2804 ConstantSDNode *CN0 = cast<ConstantSDNode > (AddArg);
2805 SDValue IndOp1 = IndirectArg.getOperand(1);
2806
2807 if (CN0->isNullValue()) {
2808 // (add (SPUindirect <arg>, <arg>), 0) ->
2809 // (SPUindirect <arg>, <arg>)
Scott Michel053c1da2008-01-29 02:16:57 +00002810
Scott Michel23f2ff72008-12-04 17:16:59 +00002811#if !defined(NDEBUG)
Scott Michelf0569be2008-12-27 04:51:36 +00002812 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002813 cerr << "\n"
Scott Michelf0569be2008-12-27 04:51:36 +00002814 << "Replace: (add (SPUindirect <arg>, <arg>), 0)\n"
2815 << "With: (SPUindirect <arg>, <arg>)\n";
2816 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002817#endif
2818
Scott Michelf0569be2008-12-27 04:51:36 +00002819 return IndirectArg;
2820 } else if (isa<ConstantSDNode>(IndOp1)) {
2821 // (add (SPUindirect <arg>, <const>), <const>) ->
2822 // (SPUindirect <arg>, <const + const>)
2823 ConstantSDNode *CN1 = cast<ConstantSDNode > (IndOp1);
2824 int64_t combinedConst = CN0->getSExtValue() + CN1->getSExtValue();
2825 SDValue combinedValue = DAG.getConstant(combinedConst, Op0VT);
Scott Michel053c1da2008-01-29 02:16:57 +00002826
Scott Michelf0569be2008-12-27 04:51:36 +00002827#if !defined(NDEBUG)
2828 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2829 cerr << "\n"
2830 << "Replace: (add (SPUindirect <arg>, " << CN1->getSExtValue()
2831 << "), " << CN0->getSExtValue() << ")\n"
2832 << "With: (SPUindirect <arg>, "
2833 << combinedConst << ")\n";
2834 }
2835#endif
Scott Michel053c1da2008-01-29 02:16:57 +00002836
Scott Michelf0569be2008-12-27 04:51:36 +00002837 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2838 IndirectArg, combinedValue);
2839 }
Scott Michel053c1da2008-01-29 02:16:57 +00002840 }
2841 }
Scott Michela59d4692008-02-23 18:41:37 +00002842 break;
2843 }
2844 case ISD::SIGN_EXTEND:
2845 case ISD::ZERO_EXTEND:
2846 case ISD::ANY_EXTEND: {
Scott Michel1a6cdb62008-12-01 17:56:02 +00002847 if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) {
Scott Michela59d4692008-02-23 18:41:37 +00002848 // (any_extend (SPUextract_elt0 <arg>)) ->
2849 // (SPUextract_elt0 <arg>)
2850 // Types must match, however...
Scott Michel23f2ff72008-12-04 17:16:59 +00002851#if !defined(NDEBUG)
2852 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
Scott Michel30ee7df2008-12-04 03:02:42 +00002853 cerr << "\nReplace: ";
2854 N->dump(&DAG);
2855 cerr << "\nWith: ";
2856 Op0.getNode()->dump(&DAG);
2857 cerr << "\n";
Scott Michel23f2ff72008-12-04 17:16:59 +00002858 }
Scott Michel30ee7df2008-12-04 03:02:42 +00002859#endif
Scott Michela59d4692008-02-23 18:41:37 +00002860
2861 return Op0;
2862 }
2863 break;
2864 }
2865 case SPUISD::IndirectAddr: {
2866 if (!ST->usingLargeMem() && Op0.getOpcode() == SPUISD::AFormAddr) {
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002867 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1));
2868 if (CN != 0 && CN->getZExtValue() == 0) {
Scott Michela59d4692008-02-23 18:41:37 +00002869 // (SPUindirect (SPUaform <addr>, 0), 0) ->
2870 // (SPUaform <addr>, 0)
2871
2872 DEBUG(cerr << "Replace: ");
2873 DEBUG(N->dump(&DAG));
2874 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002875 DEBUG(Op0.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002876 DEBUG(cerr << "\n");
2877
2878 return Op0;
2879 }
Scott Michelf0569be2008-12-27 04:51:36 +00002880 } else if (Op0.getOpcode() == ISD::ADD) {
2881 SDValue Op1 = N->getOperand(1);
2882 if (ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(Op1)) {
2883 // (SPUindirect (add <arg>, <arg>), 0) ->
2884 // (SPUindirect <arg>, <arg>)
2885 if (CN1->isNullValue()) {
2886
2887#if !defined(NDEBUG)
2888 if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) {
2889 cerr << "\n"
2890 << "Replace: (SPUindirect (add <arg>, <arg>), 0)\n"
2891 << "With: (SPUindirect <arg>, <arg>)\n";
2892 }
2893#endif
2894
2895 return DAG.getNode(SPUISD::IndirectAddr, Op0VT,
2896 Op0.getOperand(0), Op0.getOperand(1));
2897 }
2898 }
Scott Michela59d4692008-02-23 18:41:37 +00002899 }
2900 break;
2901 }
2902 case SPUISD::SHLQUAD_L_BITS:
2903 case SPUISD::SHLQUAD_L_BYTES:
2904 case SPUISD::VEC_SHL:
2905 case SPUISD::VEC_SRL:
2906 case SPUISD::VEC_SRA:
Scott Michelf0569be2008-12-27 04:51:36 +00002907 case SPUISD::ROTBYTES_LEFT: {
Dan Gohman475871a2008-07-27 21:46:04 +00002908 SDValue Op1 = N->getOperand(1);
Scott Michela59d4692008-02-23 18:41:37 +00002909
Scott Michelf0569be2008-12-27 04:51:36 +00002910 // Kill degenerate vector shifts:
2911 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
2912 if (CN->isNullValue()) {
Scott Michela59d4692008-02-23 18:41:37 +00002913 Result = Op0;
2914 }
2915 }
2916 break;
2917 }
Scott Michelf0569be2008-12-27 04:51:36 +00002918 case SPUISD::PREFSLOT2VEC: {
Scott Michela59d4692008-02-23 18:41:37 +00002919 switch (Op0.getOpcode()) {
2920 default:
2921 break;
2922 case ISD::ANY_EXTEND:
2923 case ISD::ZERO_EXTEND:
2924 case ISD::SIGN_EXTEND: {
Scott Michel1df30c42008-12-29 03:23:36 +00002925 // (SPUprefslot2vec (any|zero|sign_extend (SPUvec2prefslot <arg>))) ->
Scott Michela59d4692008-02-23 18:41:37 +00002926 // <arg>
Scott Michel1df30c42008-12-29 03:23:36 +00002927 // but only if the SPUprefslot2vec and <arg> types match.
Dan Gohman475871a2008-07-27 21:46:04 +00002928 SDValue Op00 = Op0.getOperand(0);
Scott Michel104de432008-11-24 17:11:17 +00002929 if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) {
Dan Gohman475871a2008-07-27 21:46:04 +00002930 SDValue Op000 = Op00.getOperand(0);
Scott Michel1a6cdb62008-12-01 17:56:02 +00002931 if (Op000.getValueType() == NodeVT) {
Scott Michela59d4692008-02-23 18:41:37 +00002932 Result = Op000;
2933 }
2934 }
2935 break;
2936 }
Scott Michel104de432008-11-24 17:11:17 +00002937 case SPUISD::VEC2PREFSLOT: {
Scott Michel1df30c42008-12-29 03:23:36 +00002938 // (SPUprefslot2vec (SPUvec2prefslot <arg>)) ->
Scott Michela59d4692008-02-23 18:41:37 +00002939 // <arg>
2940 Result = Op0.getOperand(0);
2941 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002942 }
Scott Michela59d4692008-02-23 18:41:37 +00002943 }
2944 break;
Scott Michel053c1da2008-01-29 02:16:57 +00002945 }
2946 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00002947
Scott Michel58c58182008-01-17 20:38:41 +00002948 // Otherwise, return unchanged.
Scott Michel1a6cdb62008-12-01 17:56:02 +00002949#ifndef NDEBUG
Gabor Greifba36cb52008-08-28 21:40:38 +00002950 if (Result.getNode()) {
Scott Michela59d4692008-02-23 18:41:37 +00002951 DEBUG(cerr << "\nReplace.SPU: ");
2952 DEBUG(N->dump(&DAG));
2953 DEBUG(cerr << "\nWith: ");
Gabor Greifba36cb52008-08-28 21:40:38 +00002954 DEBUG(Result.getNode()->dump(&DAG));
Scott Michela59d4692008-02-23 18:41:37 +00002955 DEBUG(cerr << "\n");
2956 }
2957#endif
2958
2959 return Result;
Scott Michel266bc8f2007-12-04 22:23:35 +00002960}
2961
2962//===----------------------------------------------------------------------===//
2963// Inline Assembly Support
2964//===----------------------------------------------------------------------===//
2965
2966/// getConstraintType - Given a constraint letter, return the type of
2967/// constraint it is for this target.
Scott Michel5af8f0e2008-07-16 17:17:29 +00002968SPUTargetLowering::ConstraintType
Scott Michel266bc8f2007-12-04 22:23:35 +00002969SPUTargetLowering::getConstraintType(const std::string &ConstraintLetter) const {
2970 if (ConstraintLetter.size() == 1) {
2971 switch (ConstraintLetter[0]) {
2972 default: break;
2973 case 'b':
2974 case 'r':
2975 case 'f':
2976 case 'v':
2977 case 'y':
2978 return C_RegisterClass;
Scott Michel5af8f0e2008-07-16 17:17:29 +00002979 }
Scott Michel266bc8f2007-12-04 22:23:35 +00002980 }
2981 return TargetLowering::getConstraintType(ConstraintLetter);
2982}
2983
Scott Michel5af8f0e2008-07-16 17:17:29 +00002984std::pair<unsigned, const TargetRegisterClass*>
Scott Michel266bc8f2007-12-04 22:23:35 +00002985SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Duncan Sands83ec4b62008-06-06 12:08:01 +00002986 MVT VT) const
Scott Michel266bc8f2007-12-04 22:23:35 +00002987{
2988 if (Constraint.size() == 1) {
2989 // GCC RS6000 Constraint Letters
2990 switch (Constraint[0]) {
2991 case 'b': // R1-R31
2992 case 'r': // R0-R31
2993 if (VT == MVT::i64)
2994 return std::make_pair(0U, SPU::R64CRegisterClass);
2995 return std::make_pair(0U, SPU::R32CRegisterClass);
2996 case 'f':
2997 if (VT == MVT::f32)
2998 return std::make_pair(0U, SPU::R32FPRegisterClass);
2999 else if (VT == MVT::f64)
3000 return std::make_pair(0U, SPU::R64FPRegisterClass);
3001 break;
Scott Michel5af8f0e2008-07-16 17:17:29 +00003002 case 'v':
Scott Michel266bc8f2007-12-04 22:23:35 +00003003 return std::make_pair(0U, SPU::GPRCRegisterClass);
3004 }
3005 }
Scott Michel5af8f0e2008-07-16 17:17:29 +00003006
Scott Michel266bc8f2007-12-04 22:23:35 +00003007 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
3008}
3009
Scott Michela59d4692008-02-23 18:41:37 +00003010//! Compute used/known bits for a SPU operand
Scott Michel266bc8f2007-12-04 22:23:35 +00003011void
Dan Gohman475871a2008-07-27 21:46:04 +00003012SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
Dan Gohman977a76f2008-02-13 22:28:48 +00003013 const APInt &Mask,
Scott Michel5af8f0e2008-07-16 17:17:29 +00003014 APInt &KnownZero,
Dan Gohmanfd29e0e2008-02-13 00:35:47 +00003015 APInt &KnownOne,
Scott Michel7f9ba9b2008-01-30 02:55:46 +00003016 const SelectionDAG &DAG,
3017 unsigned Depth ) const {
Scott Michel203b2d62008-04-30 00:30:08 +00003018#if 0
Scott Michela59d4692008-02-23 18:41:37 +00003019 const uint64_t uint64_sizebits = sizeof(uint64_t) * 8;
3020
3021 switch (Op.getOpcode()) {
3022 default:
3023 // KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);
3024 break;
Scott Michela59d4692008-02-23 18:41:37 +00003025 case CALL:
3026 case SHUFB:
Scott Michel7a1c9e92008-11-22 23:50:42 +00003027 case SHUFFLE_MASK:
Scott Michela59d4692008-02-23 18:41:37 +00003028 case CNTB:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00003029 case SPUISD::PREFSLOT2VEC:
Scott Michela59d4692008-02-23 18:41:37 +00003030 case SPUISD::LDRESULT:
Scott Micheld1e8d9c2009-01-21 04:58:48 +00003031 case SPUISD::VEC2PREFSLOT:
Scott Michel203b2d62008-04-30 00:30:08 +00003032 case SPUISD::SHLQUAD_L_BITS:
3033 case SPUISD::SHLQUAD_L_BYTES:
3034 case SPUISD::VEC_SHL:
3035 case SPUISD::VEC_SRL:
3036 case SPUISD::VEC_SRA:
3037 case SPUISD::VEC_ROTL:
3038 case SPUISD::VEC_ROTR:
Scott Michel203b2d62008-04-30 00:30:08 +00003039 case SPUISD::ROTBYTES_LEFT:
Scott Michel8bf61e82008-06-02 22:18:03 +00003040 case SPUISD::SELECT_MASK:
3041 case SPUISD::SELB:
Scott Michela59d4692008-02-23 18:41:37 +00003042 }
Scott Micheld1e8d9c2009-01-21 04:58:48 +00003043#endif
Scott Michel266bc8f2007-12-04 22:23:35 +00003044}
Scott Michel02d711b2008-12-30 23:28:25 +00003045
Scott Michelf0569be2008-12-27 04:51:36 +00003046unsigned
3047SPUTargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
3048 unsigned Depth) const {
3049 switch (Op.getOpcode()) {
3050 default:
3051 return 1;
Scott Michel266bc8f2007-12-04 22:23:35 +00003052
Scott Michelf0569be2008-12-27 04:51:36 +00003053 case ISD::SETCC: {
3054 MVT VT = Op.getValueType();
3055
3056 if (VT != MVT::i8 && VT != MVT::i16 && VT != MVT::i32) {
3057 VT = MVT::i32;
3058 }
3059 return VT.getSizeInBits();
3060 }
3061 }
3062}
Scott Michel1df30c42008-12-29 03:23:36 +00003063
Scott Michel203b2d62008-04-30 00:30:08 +00003064// LowerAsmOperandForConstraint
3065void
Dan Gohman475871a2008-07-27 21:46:04 +00003066SPUTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Scott Michel203b2d62008-04-30 00:30:08 +00003067 char ConstraintLetter,
Evan Chengda43bcf2008-09-24 00:05:32 +00003068 bool hasMemory,
Dan Gohman475871a2008-07-27 21:46:04 +00003069 std::vector<SDValue> &Ops,
Scott Michel203b2d62008-04-30 00:30:08 +00003070 SelectionDAG &DAG) const {
3071 // Default, for the time being, to the base class handler
Evan Chengda43bcf2008-09-24 00:05:32 +00003072 TargetLowering::LowerAsmOperandForConstraint(Op, ConstraintLetter, hasMemory,
3073 Ops, DAG);
Scott Michel203b2d62008-04-30 00:30:08 +00003074}
3075
Scott Michel266bc8f2007-12-04 22:23:35 +00003076/// isLegalAddressImmediate - Return true if the integer value can be used
3077/// as the offset of the target addressing mode.
Gabor Greif93c53e52008-08-31 15:37:04 +00003078bool SPUTargetLowering::isLegalAddressImmediate(int64_t V,
3079 const Type *Ty) const {
Scott Michel266bc8f2007-12-04 22:23:35 +00003080 // SPU's addresses are 256K:
3081 return (V > -(1 << 18) && V < (1 << 18) - 1);
3082}
3083
3084bool SPUTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
Scott Michel5af8f0e2008-07-16 17:17:29 +00003085 return false;
Scott Michel266bc8f2007-12-04 22:23:35 +00003086}
Dan Gohman6520e202008-10-18 02:06:02 +00003087
3088bool
3089SPUTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
3090 // The SPU target isn't yet aware of offsets.
3091 return false;
3092}