blob: 1965f7602a9ea49af5bc1806c06534c30c5ab9d4 [file] [log] [blame]
Misha Brukman2a8350a2005-02-05 02:24:26 +00001//===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
Andrew Lenharth304d0f32005-01-22 23:41:55 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a pattern matching instruction selector for Alpha.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Alpha.h"
Andrew Lenharth304d0f32005-01-22 23:41:55 +000015#include "AlphaRegisterInfo.h"
16#include "llvm/Constants.h" // FIXME: REMOVE
17#include "llvm/Function.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineFrameInfo.h"
22#include "llvm/CodeGen/SelectionDAG.h"
23#include "llvm/CodeGen/SelectionDAGISel.h"
24#include "llvm/CodeGen/SSARegMap.h"
25#include "llvm/Target/TargetData.h"
26#include "llvm/Target/TargetLowering.h"
27#include "llvm/Support/MathExtras.h"
28#include "llvm/ADT/Statistic.h"
Andrew Lenharth032f2352005-02-22 21:59:48 +000029#include "llvm/Support/Debug.h"
Andrew Lenharth304d0f32005-01-22 23:41:55 +000030#include <set>
Andrew Lenharth684f2292005-01-30 00:35:27 +000031#include <algorithm>
Andrew Lenharth304d0f32005-01-22 23:41:55 +000032using namespace llvm;
33
34//===----------------------------------------------------------------------===//
35// AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
36namespace {
37 class AlphaTargetLowering : public TargetLowering {
38 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
39 unsigned GP; //GOT vreg
40 public:
41 AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
42 // Set up the TargetLowering object.
Andrew Lenharth3d65d312005-01-27 03:49:45 +000043 //I am having problems with shr n ubyte 1
Andrew Lenharth879ef222005-02-02 17:00:21 +000044 setShiftAmountType(MVT::i64);
45 setSetCCResultType(MVT::i64);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000046
Andrew Lenharth304d0f32005-01-22 23:41:55 +000047 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
48 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000049 addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000050
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000051 setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote);
Andrew Lenharth33819132005-03-04 20:09:23 +000052 setOperationAction(ISD::EXTLOAD , MVT::f32 , Promote);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000053
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000054 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000055 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000056
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000057 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000058 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
59 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
60
Andrew Lenharth9818c052005-02-05 13:19:12 +000061 setOperationAction(ISD::SREM , MVT::f32 , Expand);
62 setOperationAction(ISD::SREM , MVT::f64 , Expand);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +000063
Andrew Lenharth8d163d22005-02-02 05:49:42 +000064 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
Andrew Lenharth9818c052005-02-05 13:19:12 +000065 setOperationAction(ISD::MEMSET , MVT::Other, Expand);
66 setOperationAction(ISD::MEMCPY , MVT::Other, Expand);
67
Andrew Lenharth33819132005-03-04 20:09:23 +000068 //Doesn't work yet
Andrew Lenharth572af902005-02-14 05:41:43 +000069 setOperationAction(ISD::SETCC , MVT::f32, Promote);
70
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000071 computeRegisterProperties();
Andrew Lenharth304d0f32005-01-22 23:41:55 +000072
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000073 addLegalFPImmediate(+0.0); //F31
74 addLegalFPImmediate(-0.0); //-F31
Andrew Lenharth304d0f32005-01-22 23:41:55 +000075 }
76
77 /// LowerArguments - This hook must be implemented to indicate how we should
78 /// lower the arguments for the specified function, into the specified DAG.
79 virtual std::vector<SDOperand>
80 LowerArguments(Function &F, SelectionDAG &DAG);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000081
Andrew Lenharth304d0f32005-01-22 23:41:55 +000082 /// LowerCallTo - This hook lowers an abstract call to a function into an
83 /// actual call.
84 virtual std::pair<SDOperand, SDOperand>
85 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
86 ArgListTy &Args, SelectionDAG &DAG);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000087
Andrew Lenharth304d0f32005-01-22 23:41:55 +000088 virtual std::pair<SDOperand, SDOperand>
89 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +000090
Andrew Lenharth304d0f32005-01-22 23:41:55 +000091 virtual std::pair<SDOperand,SDOperand>
92 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
93 const Type *ArgTy, SelectionDAG &DAG);
94
95 virtual std::pair<SDOperand, SDOperand>
96 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
97 SelectionDAG &DAG);
98
99 void restoreGP(MachineBasicBlock* BB)
100 {
101 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
102 }
103 };
104}
105
106//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
107
108//For now, just use variable size stack frame format
109
110//In a standard call, the first six items are passed in registers $16
111//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
112//of argument-to-register correspondence.) The remaining items are
113//collected in a memory argument list that is a naturally aligned
114//array of quadwords. In a standard call, this list, if present, must
115//be passed at 0(SP).
116//7 ... n 0(SP) ... (n-7)*8(SP)
117
118std::vector<SDOperand>
119AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
120{
121 std::vector<SDOperand> ArgValues;
122
123 // //#define FP $15
124 // //#define RA $26
125 // //#define PV $27
126 // //#define GP $29
127 // //#define SP $30
128
129 // assert(0 && "TODO");
130 MachineFunction &MF = DAG.getMachineFunction();
Andrew Lenharth05380342005-02-07 05:07:00 +0000131 MachineFrameInfo*MFI = MF.getFrameInfo();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000132
133 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
134 MachineBasicBlock& BB = MF.front();
135
136 //Handle the return address
137 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
138
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000139 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
140 Alpha::R19, Alpha::R20, Alpha::R21};
141 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
142 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth2c9e38c2005-02-06 21:07:31 +0000143 unsigned argVreg[6];
144 unsigned argPreg[6];
145 unsigned argOpc[6];
146
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000147 int count = 0;
Andrew Lenharth2c9e38c2005-02-06 21:07:31 +0000148
Chris Lattnere4d5c442005-03-15 04:54:21 +0000149 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000150 {
151 SDOperand newroot, argt;
152 if (count < 6) {
153 switch (getValueType(I->getType())) {
154 default:
155 std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n";
156 abort();
157 case MVT::f64:
158 case MVT::f32:
159 BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
160 argVreg[count] =
161 MF.getSSARegMap()->createVirtualRegister(
Andrew Lenharth032f2352005-02-22 21:59:48 +0000162 getRegClassFor(getValueType(I->getType())));
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000163 argPreg[count] = args_float[count];
164 argOpc[count] = Alpha::CPYS;
165 argt = newroot = DAG.getCopyFromReg(argVreg[count],
166 getValueType(I->getType()),
167 DAG.getRoot());
168 break;
169 case MVT::i1:
170 case MVT::i8:
171 case MVT::i16:
172 case MVT::i32:
173 case MVT::i64:
174 BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
175 argVreg[count] =
176 MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
177 argPreg[count] = args_int[count];
178 argOpc[count] = Alpha::BIS;
179 argt = newroot =
180 DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
181 if (getValueType(I->getType()) != MVT::i64)
182 argt =
183 DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
184 break;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000185 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000186 } else { //more args
187 // Create the frame index object for this incoming parameter...
188 int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
189
190 // Create the SelectionDAG nodes corresponding to a load
191 //from this parameter
192 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
193 argt = newroot = DAG.getLoad(getValueType(I->getType()),
194 DAG.getEntryNode(), FIN);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000195 }
Andrew Lenharth032f2352005-02-22 21:59:48 +0000196 ++count;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000197 DAG.setRoot(newroot.getValue(1));
198 ArgValues.push_back(argt);
199 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000200
201 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
202 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
Andrew Lenharth032f2352005-02-22 21:59:48 +0000203 for (int i = 0; i < count && i < 6; ++i) {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000204 BuildMI(&BB, argOpc[i], 2,
205 argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
206 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000207
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000208 return ArgValues;
209}
210
211std::pair<SDOperand, SDOperand>
212AlphaTargetLowering::LowerCallTo(SDOperand Chain,
213 const Type *RetTy, SDOperand Callee,
214 ArgListTy &Args, SelectionDAG &DAG) {
215 int NumBytes = 0;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000216 if (Args.size() > 6)
217 NumBytes = (Args.size() - 6) * 8;
218
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000219 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
220 DAG.getConstant(NumBytes, getPointerTy()));
221 std::vector<SDOperand> args_to_use;
222 for (unsigned i = 0, e = Args.size(); i != e; ++i)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000223 {
224 switch (getValueType(Args[i].second)) {
225 default: assert(0 && "Unexpected ValueType for argument!");
226 case MVT::i1:
227 case MVT::i8:
228 case MVT::i16:
229 case MVT::i32:
230 // Promote the integer to 64 bits. If the input type is signed use a
231 // sign extend, otherwise use a zero extend.
232 if (Args[i].second->isSigned())
233 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
234 else
235 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
236 break;
237 case MVT::i64:
238 case MVT::f64:
239 case MVT::f32:
240 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000241 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000242 args_to_use.push_back(Args[i].first);
243 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000244
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000245 std::vector<MVT::ValueType> RetVals;
246 MVT::ValueType RetTyVT = getValueType(RetTy);
247 if (RetTyVT != MVT::isVoid)
248 RetVals.push_back(RetTyVT);
249 RetVals.push_back(MVT::Other);
250
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000251 SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
252 Chain, Callee, args_to_use), 0);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000253 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
254 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
255 DAG.getConstant(NumBytes, getPointerTy()));
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000256 return std::make_pair(TheCall, Chain);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000257}
258
259std::pair<SDOperand, SDOperand>
260AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
261 //vastart just returns the address of the VarArgsFrameIndex slot.
262 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
263}
264
265std::pair<SDOperand,SDOperand> AlphaTargetLowering::
266LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000267 const Type *ArgTy, SelectionDAG &DAG) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000268 abort();
269}
270
271
272std::pair<SDOperand, SDOperand> AlphaTargetLowering::
273LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
274 SelectionDAG &DAG) {
275 abort();
276}
277
278
279
280
281
282namespace {
283
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000284//===--------------------------------------------------------------------===//
285/// ISel - Alpha specific code to select Alpha machine instructions for
286/// SelectionDAG operations.
287//===--------------------------------------------------------------------===//
288class ISel : public SelectionDAGISel {
289
290 /// AlphaLowering - This object fully describes how to lower LLVM code to an
291 /// Alpha-specific SelectionDAG.
292 AlphaTargetLowering AlphaLowering;
293
294
295 /// ExprMap - As shared expressions are codegen'd, we keep track of which
296 /// vreg the value is produced in, so we only emit one copy of each compiled
297 /// tree.
298 static const unsigned notIn = (unsigned)(-1);
299 std::map<SDOperand, unsigned> ExprMap;
300
301 //CCInvMap sometimes (SetNE) we have the inverse CC code for free
302 std::map<SDOperand, unsigned> CCInvMap;
303
304public:
305 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
306 {}
307
308 /// InstructionSelectBasicBlock - This callback is invoked by
309 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
310 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
Andrew Lenharth032f2352005-02-22 21:59:48 +0000311 DEBUG(BB->dump());
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000312 // Codegen the basic block.
313 Select(DAG.getRoot());
314
315 // Clear state used for selection.
316 ExprMap.clear();
317 CCInvMap.clear();
318 }
319
320 unsigned SelectExpr(SDOperand N);
321 unsigned SelectExprFP(SDOperand N, unsigned Result);
322 void Select(SDOperand N);
323
324 void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
325 void SelectBranchCC(SDOperand N);
326};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000327}
328
Andrew Lenharthe87f6c32005-03-11 17:48:05 +0000329//These describe LDAx
330static const int64_t IMM_LOW = 0xffffffffffff8000LL;
331static const int IMM_HIGH = 0x0000000000007fffLL;
332static const int IMM_MULT = 65536;
333
334static long getUpper16(long l)
335{
336 long y = l / IMM_MULT;
337 if (l % IMM_MULT > IMM_HIGH)
338 ++y;
339 return y;
340}
341
342static long getLower16(long l)
343{
344 long h = getUpper16(l);
345 return l - h * IMM_MULT;
346}
347
Andrew Lenharth65838902005-02-06 16:22:15 +0000348static unsigned GetSymVersion(unsigned opcode)
349{
350 switch (opcode) {
351 default: assert(0 && "unknown load or store"); return 0;
352 case Alpha::LDQ: return Alpha::LDQ_SYM;
353 case Alpha::LDS: return Alpha::LDS_SYM;
354 case Alpha::LDT: return Alpha::LDT_SYM;
355 case Alpha::LDL: return Alpha::LDL_SYM;
356 case Alpha::LDBU: return Alpha::LDBU_SYM;
357 case Alpha::LDWU: return Alpha::LDWU_SYM;
358 case Alpha::LDW: return Alpha::LDW_SYM;
359 case Alpha::LDB: return Alpha::LDB_SYM;
360 case Alpha::STQ: return Alpha::STQ_SYM;
361 case Alpha::STS: return Alpha::STS_SYM;
362 case Alpha::STT: return Alpha::STT_SYM;
363 case Alpha::STL: return Alpha::STL_SYM;
364 case Alpha::STW: return Alpha::STW_SYM;
365 case Alpha::STB: return Alpha::STB_SYM;
366 }
367}
368
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000369//Check to see if the load is a constant offset from a base register
370void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
371{
372 unsigned opcode = N.getOpcode();
373 if (opcode == ISD::ADD) {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000374 if(N.getOperand(1).getOpcode() == ISD::Constant &&
375 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
376 { //Normal imm add
377 Reg = SelectExpr(N.getOperand(0));
378 offset = cast<ConstantSDNode>(N.getOperand(1))->getValue();
379 return;
380 }
381 else if(N.getOperand(0).getOpcode() == ISD::Constant &&
382 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 32767)
383 {
384 Reg = SelectExpr(N.getOperand(1));
385 offset = cast<ConstantSDNode>(N.getOperand(0))->getValue();
386 return;
387 }
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000388 }
389 Reg = SelectExpr(N);
390 offset = 0;
391 return;
392}
393
Andrew Lenharth445171a2005-02-08 00:40:03 +0000394void ISel::SelectBranchCC(SDOperand N)
395{
396 assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000397 MachineBasicBlock *Dest =
398 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
399 unsigned Opc = Alpha::WTF;
400
Andrew Lenharth445171a2005-02-08 00:40:03 +0000401 Select(N.getOperand(0)); //chain
402 SDOperand CC = N.getOperand(1);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000403
Andrew Lenharth445171a2005-02-08 00:40:03 +0000404 if (CC.getOpcode() == ISD::SETCC)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000405 {
406 SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
407 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
408 //Dropping the CC is only useful if we are comparing to 0
409 bool isZero0 = false;
410 bool isZero1 = false;
411 bool isNE = false;
Andrew Lenharth445171a2005-02-08 00:40:03 +0000412
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000413 if(SetCC->getOperand(0).getOpcode() == ISD::Constant &&
414 cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
415 isZero0 = true;
416 if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
417 cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
418 isZero1 = true;
419 if(SetCC->getCondition() == ISD::SETNE)
420 isNE = true;
Andrew Lenharth445171a2005-02-08 00:40:03 +0000421
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000422 if (isZero0) {
Andrew Lenharth445171a2005-02-08 00:40:03 +0000423 switch (SetCC->getCondition()) {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000424 default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
425 case ISD::SETEQ: Opc = Alpha::BEQ; break;
426 case ISD::SETLT: Opc = Alpha::BGT; break;
427 case ISD::SETLE: Opc = Alpha::BGE; break;
428 case ISD::SETGT: Opc = Alpha::BLT; break;
429 case ISD::SETGE: Opc = Alpha::BLE; break;
430 case ISD::SETULT: Opc = Alpha::BNE; break;
431 case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break;
432 case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break;
433 case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC
434 case ISD::SETNE: Opc = Alpha::BNE; break;
Andrew Lenharth445171a2005-02-08 00:40:03 +0000435 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000436 unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
437 BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
438 return;
439 } else if (isZero1) {
440 switch (SetCC->getCondition()) {
441 default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
442 case ISD::SETEQ: Opc = Alpha::BEQ; break;
443 case ISD::SETLT: Opc = Alpha::BLT; break;
444 case ISD::SETLE: Opc = Alpha::BLE; break;
445 case ISD::SETGT: Opc = Alpha::BGT; break;
446 case ISD::SETGE: Opc = Alpha::BGE; break;
447 case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
448 case ISD::SETUGT: Opc = Alpha::BNE; break;
449 case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
450 case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
451 case ISD::SETNE: Opc = Alpha::BNE; break;
452 }
453 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
454 BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
455 return;
456 } else {
457 unsigned Tmp1 = SelectExpr(CC);
458 if (isNE)
459 BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
460 else
461 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
Andrew Lenharth445171a2005-02-08 00:40:03 +0000462 return;
463 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000464 } else { //FP
465 //Any comparison between 2 values should be codegened as an folded branch, as moving
466 //CC to the integer register is very expensive
467 //for a cmp b: c = a - b;
468 //a = b: c = 0
469 //a < b: c < 0
470 //a > b: c > 0
Andrew Lenharth2b6c4f52005-02-25 22:55:15 +0000471
472 bool invTest = false;
473 unsigned Tmp3;
474
475 ConstantFPSDNode *CN;
476 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
477 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
478 Tmp3 = SelectExpr(SetCC->getOperand(0));
479 else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
480 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
481 {
482 Tmp3 = SelectExpr(SetCC->getOperand(1));
483 invTest = true;
484 }
485 else
486 {
487 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
488 unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
489 bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
490 Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
491 BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
492 .addReg(Tmp1).addReg(Tmp2);
493 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000494
495 switch (SetCC->getCondition()) {
496 default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
Andrew Lenharth2b6c4f52005-02-25 22:55:15 +0000497 case ISD::SETEQ: Opc = invTest ? Alpha::FBNE : Alpha::FBEQ; break;
498 case ISD::SETLT: Opc = invTest ? Alpha::FBGT : Alpha::FBLT; break;
499 case ISD::SETLE: Opc = invTest ? Alpha::FBGE : Alpha::FBLE; break;
500 case ISD::SETGT: Opc = invTest ? Alpha::FBLT : Alpha::FBGT; break;
501 case ISD::SETGE: Opc = invTest ? Alpha::FBLE : Alpha::FBGE; break;
502 case ISD::SETNE: Opc = invTest ? Alpha::FBEQ : Alpha::FBNE; break;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000503 }
504 BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
Andrew Lenharth445171a2005-02-08 00:40:03 +0000505 return;
506 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000507 abort(); //Should never be reached
508 } else {
509 //Giveup and do the stupid thing
510 unsigned Tmp1 = SelectExpr(CC);
511 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
512 return;
513 }
Andrew Lenharth445171a2005-02-08 00:40:03 +0000514 abort(); //Should never be reached
515}
516
Andrew Lenharth40831c52005-01-28 06:57:18 +0000517unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
518{
519 unsigned Tmp1, Tmp2, Tmp3;
520 unsigned Opc = 0;
521 SDNode *Node = N.Val;
522 MVT::ValueType DestType = N.getValueType();
523 unsigned opcode = N.getOpcode();
524
525 switch (opcode) {
526 default:
527 Node->dump();
528 assert(0 && "Node not handled!\n");
Andrew Lenharth2c594352005-01-29 15:42:07 +0000529
Andrew Lenharth9818c052005-02-05 13:19:12 +0000530 case ISD::SELECT:
531 {
Andrew Lenharth45859692005-03-03 21:47:53 +0000532 //Tmp1 = SelectExpr(N.getOperand(0)); //Cond
533 unsigned TV = SelectExpr(N.getOperand(1)); //Use if TRUE
534 unsigned FV = SelectExpr(N.getOperand(2)); //Use if FALSE
535
536 SDOperand CC = N.getOperand(0);
537 SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
538
539 if (CC.getOpcode() == ISD::SETCC &&
540 !MVT::isInteger(SetCC->getOperand(0).getValueType()))
541 { //FP Setcc -> Select yay!
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000542
543
Andrew Lenharth45859692005-03-03 21:47:53 +0000544 //for a cmp b: c = a - b;
545 //a = b: c = 0
546 //a < b: c < 0
547 //a > b: c > 0
548
549 bool invTest = false;
550 unsigned Tmp3;
551
552 ConstantFPSDNode *CN;
553 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
554 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
555 Tmp3 = SelectExpr(SetCC->getOperand(0));
556 else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
557 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
558 {
559 Tmp3 = SelectExpr(SetCC->getOperand(1));
560 invTest = true;
561 }
562 else
563 {
564 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
565 unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
566 bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
567 Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
568 BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
569 .addReg(Tmp1).addReg(Tmp2);
570 }
571
572 switch (SetCC->getCondition()) {
573 default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
574 case ISD::SETEQ: Opc = invTest ? Alpha::FCMOVNE : Alpha::FCMOVEQ; break;
575 case ISD::SETLT: Opc = invTest ? Alpha::FCMOVGT : Alpha::FCMOVLT; break;
576 case ISD::SETLE: Opc = invTest ? Alpha::FCMOVGE : Alpha::FCMOVLE; break;
577 case ISD::SETGT: Opc = invTest ? Alpha::FCMOVLT : Alpha::FCMOVGT; break;
578 case ISD::SETGE: Opc = invTest ? Alpha::FCMOVLE : Alpha::FCMOVGE; break;
579 case ISD::SETNE: Opc = invTest ? Alpha::FCMOVEQ : Alpha::FCMOVNE; break;
580 }
Andrew Lenharth33819132005-03-04 20:09:23 +0000581 BuildMI(BB, Opc, 3, Result).addReg(FV).addReg(TV).addReg(Tmp3);
Andrew Lenharth45859692005-03-03 21:47:53 +0000582 return Result;
583 }
584 else
585 {
586 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
587 // Spill the cond to memory and reload it from there.
588 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
589 MachineFunction *F = BB->getParent();
590 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
591 unsigned Tmp4 = MakeReg(MVT::f64);
592 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
593 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
594 //now ideally, we don't have to do anything to the flag...
595 // Get the condition into the zero flag.
596 BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4);
597 return Result;
598 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000599 }
600
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000601 case ISD::FP_ROUND:
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000602 assert (DestType == MVT::f32 &&
603 N.getOperand(0).getValueType() == MVT::f64 &&
604 "only f64 to f32 conversion supported here");
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000605 Tmp1 = SelectExpr(N.getOperand(0));
606 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
607 return Result;
608
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000609 case ISD::FP_EXTEND:
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000610 assert (DestType == MVT::f64 &&
611 N.getOperand(0).getValueType() == MVT::f32 &&
612 "only f32 to f64 conversion supported here");
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000613 Tmp1 = SelectExpr(N.getOperand(0));
614 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
615 return Result;
616
Andrew Lenharth2c594352005-01-29 15:42:07 +0000617 case ISD::CopyFromReg:
618 {
619 // Make sure we generate both values.
620 if (Result != notIn)
621 ExprMap[N.getValue(1)] = notIn; // Generate the token
622 else
623 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
624
625 SDOperand Chain = N.getOperand(0);
626
627 Select(Chain);
628 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
629 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
630 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
631 return Result;
632 }
633
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000634 case ISD::LOAD:
635 {
636 // Make sure we generate both values.
637 if (Result != notIn)
638 ExprMap[N.getValue(1)] = notIn; // Generate the token
639 else
640 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000641
Andrew Lenharth29219162005-02-07 06:31:44 +0000642 DestType = N.getValue(0).getValueType();
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000643
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000644 SDOperand Chain = N.getOperand(0);
645 SDOperand Address = N.getOperand(1);
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000646 Select(Chain);
Andrew Lenharth65838902005-02-06 16:22:15 +0000647 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
648
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000649 if (Address.getOpcode() == ISD::GlobalAddress) {
650 AlphaLowering.restoreGP(BB);
651 Opc = GetSymVersion(Opc);
652 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
653 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000654 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000655 AlphaLowering.restoreGP(BB);
Andrew Lenharth65838902005-02-06 16:22:15 +0000656 Opc = GetSymVersion(Opc);
Andrew Lenharth97127a12005-02-05 17:41:39 +0000657 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000658 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000659 else if(Address.getOpcode() == ISD::FrameIndex) {
Andrew Lenharth032f2352005-02-22 21:59:48 +0000660 BuildMI(BB, Opc, 2, Result)
661 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
662 .addReg(Alpha::F31);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000663 } else {
664 long offset;
665 SelectAddr(Address, Tmp1, offset);
666 BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
667 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000668 return Result;
669 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000670 case ISD::ConstantFP:
671 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
672 if (CN->isExactlyValue(+0.0)) {
673 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000674 } else if ( CN->isExactlyValue(-0.0)) {
675 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000676 } else {
677 abort();
678 }
679 }
680 return Result;
681
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000682 case ISD::SDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000683 case ISD::MUL:
684 case ISD::ADD:
685 case ISD::SUB:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000686 switch( opcode ) {
687 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
688 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
689 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
690 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
691 };
Andrew Lenharth2b6c4f52005-02-25 22:55:15 +0000692
693 ConstantFPSDNode *CN;
694 if (opcode == ISD::SUB
695 && (CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
696 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
697 {
698 Tmp2 = SelectExpr(N.getOperand(1));
699 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2);
700 } else {
701 Tmp1 = SelectExpr(N.getOperand(0));
702 Tmp2 = SelectExpr(N.getOperand(1));
703 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
704 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000705 return Result;
706
Andrew Lenharth2c594352005-01-29 15:42:07 +0000707 case ISD::EXTLOAD:
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000708 {
709 //include a conversion sequence for float loads to double
710 if (Result != notIn)
711 ExprMap[N.getValue(1)] = notIn; // Generate the token
712 else
713 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
714
Andrew Lenhartha549deb2005-02-07 05:33:15 +0000715 Tmp1 = MakeReg(MVT::f32);
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000716
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000717 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 &&
718 "EXTLOAD not from f32");
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000719 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
720
721 SDOperand Chain = N.getOperand(0);
722 SDOperand Address = N.getOperand(1);
723 Select(Chain);
724
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000725 if (Address.getOpcode() == ISD::GlobalAddress) {
726 AlphaLowering.restoreGP(BB);
727 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
728 }
729 else if (ConstantPoolSDNode *CP =
730 dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
731 {
732 AlphaLowering.restoreGP(BB);
733 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
734 }
735 else if(Address.getOpcode() == ISD::FrameIndex) {
736 Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
Andrew Lenharth032f2352005-02-22 21:59:48 +0000737 BuildMI(BB, Alpha::LDS, 2, Tmp1)
738 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
739 .addReg(Alpha::F31);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000740 } else {
741 long offset;
742 SelectAddr(Address, Tmp2, offset);
743 BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2);
744 }
Andrew Lenharth29219162005-02-07 06:31:44 +0000745 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000746 return Result;
747 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000748
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000749 case ISD::UINT_TO_FP:
750 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000751 {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000752 assert (N.getOperand(0).getValueType() == MVT::i64
753 && "only quads can be loaded from");
Andrew Lenharth40831c52005-01-28 06:57:18 +0000754 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000755 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000756
757 //The hard way:
758 // Spill the integer to memory and reload it from there.
759 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
760 MachineFunction *F = BB->getParent();
761 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
762
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000763 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
764 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
765 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
766 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000767
768 //The easy way: doesn't work
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000769 // //so these instructions are not supported on ev56
770 // Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
771 // BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
772 // Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
773 // BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000774
Andrew Lenharth40831c52005-01-28 06:57:18 +0000775 return Result;
776 }
777 }
778 assert(0 && "should not get here");
779 return 0;
780}
781
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000782unsigned ISel::SelectExpr(SDOperand N) {
783 unsigned Result;
784 unsigned Tmp1, Tmp2, Tmp3;
785 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000786 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000787
788 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000789 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000790
791 unsigned &Reg = ExprMap[N];
792 if (Reg) return Reg;
793
794 if (N.getOpcode() != ISD::CALL)
795 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000796 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000797 else {
798 // If this is a call instruction, make sure to prepare ALL of the result
799 // values as well as the chain.
800 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000801 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000802 else {
803 Result = MakeReg(Node->getValueType(0));
804 ExprMap[N.getValue(0)] = Result;
805 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
806 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000807 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000808 }
809 }
810
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000811 if (DestType == MVT::f64 || DestType == MVT::f32 ||
Andrew Lenharth06342c32005-02-07 06:21:37 +0000812 (
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000813 (opcode == ISD::LOAD || opcode == ISD::CopyFromReg ||
814 opcode == ISD::EXTLOAD) &&
815 (N.getValue(0).getValueType() == MVT::f32 ||
816 N.getValue(0).getValueType() == MVT::f64)
Andrew Lenharth06342c32005-02-07 06:21:37 +0000817 )
818 )
Andrew Lenharth40831c52005-01-28 06:57:18 +0000819 return SelectExprFP(N, Result);
820
821 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000822 default:
823 Node->dump();
824 assert(0 && "Node not handled!\n");
825
Andrew Lenharth032f2352005-02-22 21:59:48 +0000826 case ISD::DYNAMIC_STACKALLOC:
827 // Generate both result values.
Andrew Lenharth3a7118d2005-02-23 17:33:42 +0000828 if (Result != notIn)
829 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth032f2352005-02-22 21:59:48 +0000830 else
831 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
832
833 // FIXME: We are currently ignoring the requested alignment for handling
834 // greater than the stack alignment. This will need to be revisited at some
835 // point. Align = N.getOperand(2);
836
837 if (!isa<ConstantSDNode>(N.getOperand(2)) ||
838 cast<ConstantSDNode>(N.getOperand(2))->getValue() != 0) {
839 std::cerr << "Cannot allocate stack object with greater alignment than"
840 << " the stack alignment yet!";
841 abort();
842 }
843
844 Select(N.getOperand(0));
845 if (ConstantSDNode* CN = dyn_cast<ConstantSDNode>(N.getOperand(1)))
846 {
847 if (CN->getValue() < 32000)
848 {
849 BuildMI(BB, Alpha::LDA, 2, Alpha::R30)
850 .addImm(-CN->getValue()).addReg(Alpha::R30);
851 } else {
852 Tmp1 = SelectExpr(N.getOperand(1));
853 // Subtract size from stack pointer, thereby allocating some space.
854 BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
855 }
856 } else {
857 Tmp1 = SelectExpr(N.getOperand(1));
858 // Subtract size from stack pointer, thereby allocating some space.
859 BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
860 }
861
862 // Put a pointer to the space into the result register, by copying the stack
863 // pointer.
Andrew Lenharth7bc47022005-02-22 23:29:25 +0000864 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R30).addReg(Alpha::R30);
Andrew Lenharth032f2352005-02-22 21:59:48 +0000865 return Result;
866
Andrew Lenharth33819132005-03-04 20:09:23 +0000867// case ISD::ConstantPool:
868// Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
869// AlphaLowering.restoreGP(BB);
870// BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(Tmp1);
871// return Result;
Andrew Lenharth2c594352005-01-29 15:42:07 +0000872
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000873 case ISD::FrameIndex:
Andrew Lenharth032f2352005-02-22 21:59:48 +0000874 BuildMI(BB, Alpha::LDA, 2, Result)
875 .addFrameIndex(cast<FrameIndexSDNode>(N)->getIndex())
876 .addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000877 return Result;
878
879 case ISD::EXTLOAD:
Andrew Lenharthf311e8b2005-02-07 05:18:02 +0000880 case ISD::ZEXTLOAD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000881 case ISD::SEXTLOAD:
Andrew Lenhartha549deb2005-02-07 05:33:15 +0000882 case ISD::LOAD:
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000883 {
884 // Make sure we generate both values.
885 if (Result != notIn)
886 ExprMap[N.getValue(1)] = notIn; // Generate the token
887 else
888 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000889
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000890 SDOperand Chain = N.getOperand(0);
891 SDOperand Address = N.getOperand(1);
892 Select(Chain);
893
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000894 assert(Node->getValueType(0) == MVT::i64 &&
895 "Unknown type to sign extend to.");
Andrew Lenharth03824012005-02-07 05:55:55 +0000896 if (opcode == ISD::LOAD)
897 Opc = Alpha::LDQ;
898 else
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000899 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
900 default: Node->dump(); assert(0 && "Bad sign extend!");
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000901 case MVT::i32: Opc = Alpha::LDL;
902 assert(opcode != ISD::ZEXTLOAD && "Not sext"); break;
903 case MVT::i16: Opc = Alpha::LDWU;
904 assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
Andrew Lenharthf311e8b2005-02-07 05:18:02 +0000905 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000906 case MVT::i8: Opc = Alpha::LDBU;
907 assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000908 }
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000909
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000910 if (Address.getOpcode() == ISD::GlobalAddress) {
911 AlphaLowering.restoreGP(BB);
912 Opc = GetSymVersion(Opc);
913 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
914 }
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000915 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
916 AlphaLowering.restoreGP(BB);
Andrew Lenharth65838902005-02-06 16:22:15 +0000917 Opc = GetSymVersion(Opc);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000918 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000919 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000920 else if(Address.getOpcode() == ISD::FrameIndex) {
Andrew Lenharth032f2352005-02-22 21:59:48 +0000921 BuildMI(BB, Opc, 2, Result)
922 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
923 .addReg(Alpha::F31);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000924 } else {
925 long offset;
926 SelectAddr(Address, Tmp1, offset);
927 BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
928 }
Andrew Lenharth9e8d1092005-02-06 15:40:40 +0000929 return Result;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000930 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000931
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000932 case ISD::GlobalAddress:
933 AlphaLowering.restoreGP(BB);
934 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
935 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
936 return Result;
937
938 case ISD::CALL:
939 {
940 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000941
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000942 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000943 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000944
945 //grab the arguments
946 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000947 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000948 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000949 argvregs.push_back(SelectExpr(N.getOperand(i)));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000950
Andrew Lenharth684f2292005-01-30 00:35:27 +0000951 //in reg args
952 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000953 {
954 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
955 Alpha::R19, Alpha::R20, Alpha::R21};
956 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
957 Alpha::F19, Alpha::F20, Alpha::F21};
958 switch(N.getOperand(i+2).getValueType()) {
959 default:
960 Node->dump();
961 N.getOperand(i).Val->dump();
962 std::cerr << "Type for " << i << " is: " <<
963 N.getOperand(i+2).getValueType() << "\n";
964 assert(0 && "Unknown value type for call");
965 case MVT::i1:
966 case MVT::i8:
967 case MVT::i16:
968 case MVT::i32:
969 case MVT::i64:
970 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
971 break;
972 case MVT::f32:
973 case MVT::f64:
974 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
975 break;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000976 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000977 }
Andrew Lenharth684f2292005-01-30 00:35:27 +0000978 //in mem args
979 for (int i = 6, e = argvregs.size(); i < e; ++i)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000980 {
981 switch(N.getOperand(i+2).getValueType()) {
982 default:
983 Node->dump();
984 N.getOperand(i).Val->dump();
985 std::cerr << "Type for " << i << " is: " <<
986 N.getOperand(i+2).getValueType() << "\n";
987 assert(0 && "Unknown value type for call");
988 case MVT::i1:
989 case MVT::i8:
990 case MVT::i16:
991 case MVT::i32:
992 case MVT::i64:
993 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
994 break;
995 case MVT::f32:
996 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
997 break;
998 case MVT::f64:
999 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
1000 break;
Andrew Lenharth684f2292005-01-30 00:35:27 +00001001 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001002 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001003 //build the right kind of call
1004 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +00001005 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001006 {
Andrew Lenharth3e315922005-02-10 20:10:38 +00001007 //if (GASD->getGlobal()->isExternal()) {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001008 //use safe calling convention
Andrew Lenharth7b2a5272005-01-30 20:42:36 +00001009 AlphaLowering.restoreGP(BB);
1010 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
Andrew Lenharth3e315922005-02-10 20:10:38 +00001011 //} else {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001012 //use PC relative branch call
Andrew Lenharth3e315922005-02-10 20:10:38 +00001013 //BuildMI(BB, Alpha::BSR, 1, Alpha::R26).addGlobalAddress(GASD->getGlobal(),true);
1014 //}
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001015 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001016 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +00001017 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001018 {
1019 AlphaLowering.restoreGP(BB);
1020 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
1021 } else {
1022 //no need to restore GP as we are doing an indirect call
1023 Tmp1 = SelectExpr(N.getOperand(1));
1024 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
1025 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
1026 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001027
1028 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001029
1030 switch (Node->getValueType(0)) {
1031 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001032 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001033 case MVT::i1:
1034 case MVT::i8:
1035 case MVT::i16:
1036 case MVT::i32:
1037 case MVT::i64:
1038 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
1039 break;
1040 case MVT::f32:
1041 case MVT::f64:
1042 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
1043 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001044 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001045 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001046 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001047
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001048 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001049 abort();
1050
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001051 case ISD::SIGN_EXTEND_INREG:
1052 {
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001053 //do SDIV opt for all levels of ints
1054 if (N.getOperand(0).getOpcode() == ISD::SDIV)
1055 {
1056 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1057 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1058 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1059 MachineFunction *F = BB->getParent();
1060 int FrameIdxL = F->getFrameInfo()->CreateStackObject(Size, 8);
1061 int FrameIdxR = F->getFrameInfo()->CreateStackObject(Size, 8);
1062 int FrameIdxF = F->getFrameInfo()->CreateStackObject(Size, 8);
1063 unsigned Tmp4 = MakeReg(MVT::f64);
1064 unsigned Tmp5 = MakeReg(MVT::f64);
1065 unsigned Tmp6 = MakeReg(MVT::f64);
1066 unsigned Tmp7 = MakeReg(MVT::f64);
1067 unsigned Tmp8 = MakeReg(MVT::f64);
1068 unsigned Tmp9 = MakeReg(MVT::f64);
1069
1070 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxL).addReg(Alpha::F31);
Andrew Lenharthcc59ed52005-03-23 15:20:01 +00001071 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp2).addFrameIndex(FrameIdxR).addReg(Alpha::F31);
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001072 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdxL).addReg(Alpha::F31);
1073 BuildMI(BB, Alpha::LDT, 2, Tmp5).addFrameIndex(FrameIdxR).addReg(Alpha::F31);
1074 BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4);
1075 BuildMI(BB, Alpha::CVTQT, 1, Tmp7).addReg(Tmp5);
1076 BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7);
1077 BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8);
1078 BuildMI(BB, Alpha::STT, 3).addReg(Tmp9).addFrameIndex(FrameIdxF).addReg(Alpha::F31);
Andrew Lenharthcc59ed52005-03-23 15:20:01 +00001079 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31);
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001080 return Result;
1081 }
1082
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001083 //Alpha has instructions for a bunch of signed 32 bit stuff
1084 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001085 {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001086 switch (N.getOperand(0).getOpcode()) {
1087 case ISD::ADD:
1088 case ISD::SUB:
1089 case ISD::MUL:
1090 {
1091 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
1092 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
1093 //FIXME: first check for Scaled Adds and Subs!
1094 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
1095 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
1096 { //Normal imm add/sub
1097 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
Andrew Lenharth093f3272005-02-12 21:11:17 +00001098 //if the value was really originally a i32, skip the up conversion
1099 if (N.getOperand(0).getOperand(0).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1100 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(0).Val)
1101 ->getExtraValueType() == MVT::i32)
1102 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
1103 else
1104 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001105 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
1106 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001107 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001108 else
1109 { //Normal add/sub
1110 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
Andrew Lenharth093f3272005-02-12 21:11:17 +00001111 //if the value was really originally a i32, skip the up conversion
1112 if (N.getOperand(0).getOperand(0).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1113 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(0).Val)
1114 ->getExtraValueType() == MVT::i32)
1115 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
1116 else
1117 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1118 //if the value was really originally a i32, skip the up conversion
1119 if (N.getOperand(0).getOperand(1).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1120 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(1).Val)
1121 ->getExtraValueType() == MVT::i32)
1122 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
1123 else
1124 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1125
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001126 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1127 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1128 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1129 }
1130 return Result;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001131 }
Andrew Lenharth74d00d82005-03-02 17:23:03 +00001132 case ISD::SEXTLOAD:
1133 //SelectionDag isn't deleting the signextend after sextloads
1134 Reg = Result = SelectExpr(N.getOperand(0));
1135 return Result;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001136 default: break; //Fall Though;
1137 }
1138 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001139 Tmp1 = SelectExpr(N.getOperand(0));
1140 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001141 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001142 switch(MVN->getExtraValueType())
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001143 {
1144 default:
1145 Node->dump();
1146 assert(0 && "Sign Extend InReg not there yet");
1147 break;
1148 case MVT::i32:
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001149 {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001150 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001151 break;
1152 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001153 case MVT::i16:
1154 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
1155 break;
1156 case MVT::i8:
1157 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
1158 break;
Andrew Lenharthebce5042005-02-12 19:35:12 +00001159 case MVT::i1:
1160 Tmp2 = MakeReg(MVT::i64);
1161 BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1);
Andrew Lenharth7536eea2005-02-12 20:42:09 +00001162 BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::F31).addReg(Tmp2);
Andrew Lenharthebce5042005-02-12 19:35:12 +00001163 break;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001164 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001165 return Result;
1166 }
1167 case ISD::ZERO_EXTEND_INREG:
1168 {
1169 Tmp1 = SelectExpr(N.getOperand(0));
1170 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001171 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001172 switch(MVN->getExtraValueType())
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001173 {
1174 default:
1175 Node->dump();
1176 assert(0 && "Zero Extend InReg not there yet");
1177 break;
1178 case MVT::i32: Tmp2 = 0xf0; break;
1179 case MVT::i16: Tmp2 = 0xfc; break;
1180 case MVT::i8: Tmp2 = 0xfe; break;
1181 case MVT::i1: //handle this one special
1182 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
1183 return Result;
1184 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001185 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001186 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001187 }
1188
1189 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001190 {
1191 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
1192 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
1193 bool isConst1 = false;
1194 bool isConst2 = false;
1195 int dir;
Andrew Lenharth9818c052005-02-05 13:19:12 +00001196
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001197 //Tmp1 = SelectExpr(N.getOperand(0));
1198 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001199 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
1200 isConst1 = true;
1201 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001202 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1203 isConst2 = true;
1204
1205 switch (SetCC->getCondition()) {
1206 default: Node->dump(); assert(0 && "Unknown integer comparison!");
1207 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001208 case ISD::SETLT:
1209 Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
1210 case ISD::SETLE:
1211 Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
1212 case ISD::SETGT:
1213 Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
1214 case ISD::SETGE:
1215 Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
1216 case ISD::SETULT:
1217 Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
1218 case ISD::SETUGT:
1219 Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
1220 case ISD::SETULE:
1221 Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
1222 case ISD::SETUGE:
1223 Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +00001224 case ISD::SETNE: {//Handle this one special
1225 //std::cerr << "Alpha does not have a setne.\n";
1226 //abort();
1227 Tmp1 = SelectExpr(N.getOperand(0));
1228 Tmp2 = SelectExpr(N.getOperand(1));
1229 Tmp3 = MakeReg(MVT::i64);
1230 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth445171a2005-02-08 00:40:03 +00001231 //Remeber we have the Inv for this CC
1232 CCInvMap[N] = Tmp3;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +00001233 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001234 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +00001235 return Result;
1236 }
1237 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001238 if (dir == 1) {
1239 Tmp1 = SelectExpr(N.getOperand(0));
1240 if (isConst2) {
1241 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1242 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1243 } else {
1244 Tmp2 = SelectExpr(N.getOperand(1));
1245 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1246 }
1247 } else if (dir == 2) {
1248 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001249 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001250 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
1251 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1252 } else {
1253 Tmp2 = SelectExpr(N.getOperand(0));
1254 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1255 }
1256 } else { //dir == 0
1257 if (isConst1) {
1258 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
1259 Tmp2 = SelectExpr(N.getOperand(1));
1260 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
1261 } else if (isConst2) {
1262 Tmp1 = SelectExpr(N.getOperand(0));
1263 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1264 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
1265 } else {
1266 Tmp1 = SelectExpr(N.getOperand(0));
1267 Tmp2 = SelectExpr(N.getOperand(1));
1268 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
1269 }
Andrew Lenharthd4bdd542005-02-05 16:41:03 +00001270 }
1271 } else {
1272 //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
1273 bool rev = false;
1274 bool inv = false;
1275
1276 switch (SetCC->getCondition()) {
1277 default: Node->dump(); assert(0 && "Unknown FP comparison!");
1278 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
1279 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
1280 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
1281 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
1282 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
1283 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
1284 }
1285
Andrew Lenharthca3d59b2005-03-14 19:23:45 +00001286 //FIXME: check for constant 0.0
1287 ConstantFPSDNode *CN;
1288 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
1289 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
1290 Tmp1 = Alpha::F31;
1291 else
1292 Tmp1 = SelectExpr(N.getOperand(0));
1293
1294 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
1295 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
1296 Tmp2 = Alpha::F31;
1297 else
1298 Tmp2 = SelectExpr(N.getOperand(1));
1299
Andrew Lenharthd4bdd542005-02-05 16:41:03 +00001300 //Can only compare doubles, and dag won't promote for me
1301 if (SetCC->getOperand(0).getValueType() == MVT::f32)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001302 {
Andrew Lenharth032f2352005-02-22 21:59:48 +00001303 //assert(0 && "Setcc On float?\n");
1304 std::cerr << "Setcc on float!\n";
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001305 Tmp3 = MakeReg(MVT::f64);
1306 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
1307 Tmp1 = Tmp3;
1308 }
Andrew Lenharthd4bdd542005-02-05 16:41:03 +00001309 if (SetCC->getOperand(1).getValueType() == MVT::f32)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001310 {
Andrew Lenharth032f2352005-02-22 21:59:48 +00001311 //assert (0 && "Setcc On float?\n");
1312 std::cerr << "Setcc on float!\n";
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001313 Tmp3 = MakeReg(MVT::f64);
1314 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
Andrew Lenharth572af902005-02-14 05:41:43 +00001315 Tmp2 = Tmp3;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001316 }
Andrew Lenharth9818c052005-02-05 13:19:12 +00001317
Andrew Lenharthd4bdd542005-02-05 16:41:03 +00001318 if (rev) std::swap(Tmp1, Tmp2);
1319 Tmp3 = MakeReg(MVT::f64);
1320 //do the comparison
1321 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
1322
1323 //now arrange for Result (int) to have a 1 or 0
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001324 unsigned Tmp4 = MakeReg(MVT::i64);
1325 BuildMI(BB, Alpha::ADDQi, 2, Tmp4).addReg(Alpha::R31).addImm(1);
1326 Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP;
1327 BuildMI(BB, Opc, 3, Result).addReg(Tmp4).addImm(0).addReg(Tmp3);
1328// Opc = inv?Alpha::CC2INT_INV:Alpha::CC2INT;
1329// BuildMI(BB, Opc, 1, Result).addReg(Tmp3);
Andrew Lenharthca3d59b2005-03-14 19:23:45 +00001330
1331// // Spill the FP to memory and reload it from there.
1332// unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1333// MachineFunction *F = BB->getParent();
1334// int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1335// unsigned Tmp4 = MakeReg(MVT::f64);
1336// BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
1337// BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1338// unsigned Tmp5 = MakeReg(MVT::i64);
1339// BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
Andrew Lenharth9818c052005-02-05 13:19:12 +00001340
Andrew Lenharthca3d59b2005-03-14 19:23:45 +00001341// //now, set result based on Tmp5
1342// //Set Tmp6 if fp cmp was false
1343// unsigned Tmp6 = MakeReg(MVT::i64);
1344// BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
1345// //and invert
1346// BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
Andrew Lenharthd4bdd542005-02-05 16:41:03 +00001347
1348 }
1349 // else
1350 // {
1351 // Node->dump();
1352 // assert(0 && "Not a setcc in setcc");
1353 // }
Andrew Lenharth9818c052005-02-05 13:19:12 +00001354 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001355 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001356 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +00001357
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001358 case ISD::CopyFromReg:
1359 {
Andrew Lenharth40831c52005-01-28 06:57:18 +00001360 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001361 if (Result != notIn)
1362 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +00001363 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001364 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +00001365
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001366 SDOperand Chain = N.getOperand(0);
1367
1368 Select(Chain);
1369 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
1370 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
1371 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
1372 return Result;
1373 }
1374
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001375 //Most of the plain arithmetic and logic share the same form, and the same
1376 //constant immediate test
1377 case ISD::AND:
1378 case ISD::OR:
1379 case ISD::XOR:
1380 case ISD::SHL:
1381 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +00001382 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001383 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001384 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
1385 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001386 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001387 {
1388 switch(opcode) {
1389 case ISD::AND: Opc = Alpha::ANDi; break;
1390 case ISD::OR: Opc = Alpha::BISi; break;
1391 case ISD::XOR: Opc = Alpha::XORi; break;
1392 case ISD::SHL: Opc = Alpha::SLi; break;
1393 case ISD::SRL: Opc = Alpha::SRLi; break;
1394 case ISD::SRA: Opc = Alpha::SRAi; break;
1395 case ISD::MUL: Opc = Alpha::MULQi; break;
1396 };
1397 Tmp1 = SelectExpr(N.getOperand(0));
1398 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1399 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1400 } else {
1401 switch(opcode) {
1402 case ISD::AND: Opc = Alpha::AND; break;
1403 case ISD::OR: Opc = Alpha::BIS; break;
1404 case ISD::XOR: Opc = Alpha::XOR; break;
1405 case ISD::SHL: Opc = Alpha::SL; break;
1406 case ISD::SRL: Opc = Alpha::SRL; break;
1407 case ISD::SRA: Opc = Alpha::SRA; break;
1408 case ISD::MUL: Opc = Alpha::MULQ; break;
1409 };
1410 Tmp1 = SelectExpr(N.getOperand(0));
1411 Tmp2 = SelectExpr(N.getOperand(1));
1412 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1413 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001414 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +00001415
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001416 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001417 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001418 {
Andrew Lenharth40831c52005-01-28 06:57:18 +00001419 bool isAdd = opcode == ISD::ADD;
1420
1421 //FIXME: first check for Scaled Adds and Subs!
1422 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001423 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001424 { //Normal imm add/sub
1425 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
1426 Tmp1 = SelectExpr(N.getOperand(0));
1427 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1428 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1429 }
Andrew Lenharth40831c52005-01-28 06:57:18 +00001430 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth74d00d82005-03-02 17:23:03 +00001431 (cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767 ||
1432 (long)cast<ConstantSDNode>(N.getOperand(1))->getValue() >= -32767))
1433 { //LDA
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001434 Tmp1 = SelectExpr(N.getOperand(0));
Andrew Lenharth74d00d82005-03-02 17:23:03 +00001435 Tmp2 = (long)cast<ConstantSDNode>(N.getOperand(1))->getValue();
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001436 if (!isAdd)
1437 Tmp2 = -Tmp2;
1438 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1439 } else {
1440 //Normal add/sub
1441 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1442 Tmp1 = SelectExpr(N.getOperand(0));
1443 Tmp2 = SelectExpr(N.getOperand(1));
1444 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1445 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001446 return Result;
1447 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001448
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001449 case ISD::SDIV:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001450 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001451 case ISD::SREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001452 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001453 //FIXME: alpha really doesn't support any of these operations,
1454 // the ops are expanded into special library calls with
1455 // special calling conventions
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001456 //Restore GP because it is a call after all...
Andrew Lenharth40831c52005-01-28 06:57:18 +00001457 switch(opcode) {
Andrew Lenharth2b6c4f52005-02-25 22:55:15 +00001458 case ISD::UREM: Opc = Alpha::REMQU; break;
1459 case ISD::SREM: Opc = Alpha::REMQ; break;
1460 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1461 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001462 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001463 Tmp1 = SelectExpr(N.getOperand(0));
1464 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth33819132005-03-04 20:09:23 +00001465 //set up regs explicitly (helps Reg alloc)
1466 BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp1).addReg(Tmp1);
1467 BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp2).addReg(Tmp2);
Andrew Lenharth2b6c4f52005-02-25 22:55:15 +00001468 AlphaLowering.restoreGP(BB);
Andrew Lenharth33819132005-03-04 20:09:23 +00001469 BuildMI(BB, Opc, 2).addReg(Alpha::R24).addReg(Alpha::R25);
1470 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R27).addReg(Alpha::R27);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001471 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001472
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001473 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001474 case ISD::FP_TO_SINT:
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001475 {
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001476 assert (DestType == MVT::i64 && "only quads can be loaded to");
1477 MVT::ValueType SrcType = N.getOperand(0).getValueType();
Andrew Lenharth03824012005-02-07 05:55:55 +00001478 assert (SrcType == MVT::f32 || SrcType == MVT::f64);
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001479 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1480
1481 //The hard way:
1482 // Spill the integer to memory and reload it from there.
1483 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1484 MachineFunction *F = BB->getParent();
1485 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1486
1487 //CVTTQ STT LDQ
1488 //CVTST CVTTQ STT LDQ
1489 if (SrcType == MVT::f32)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001490 {
1491 Tmp2 = MakeReg(MVT::f64);
1492 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1493 Tmp1 = Tmp2;
1494 }
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001495 Tmp2 = MakeReg(MVT::f64);
1496 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1497 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1498 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1499
1500 return Result;
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001501 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001502
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001503 // // case ISD::FP_TO_UINT:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001504
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001505 case ISD::SELECT:
1506 {
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +00001507 //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) and can save stack use
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001508 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001509 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1510 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001511 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001512 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001513 return Result;
1514 }
1515
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001516 case ISD::Constant:
1517 {
Andrew Lenharthe87f6c32005-03-11 17:48:05 +00001518 int64_t val = (long)cast<ConstantSDNode>(N)->getValue();
1519 if (val <= IMM_HIGH && val >= IMM_LOW) {
1520 BuildMI(BB, Alpha::LDA, 2, Result).addImm(val).addReg(Alpha::R31);
1521 }
1522 else if (val <= (int64_t)IMM_HIGH + (int64_t)IMM_HIGH * (int64_t)IMM_MULT &&
1523 val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT) {
1524 Tmp1 = MakeReg(MVT::i64);
1525 BuildMI(BB, Alpha::LDAH, 2, Tmp1).addImm(getUpper16(val)).addReg(Alpha::R31);
1526 BuildMI(BB, Alpha::LDA, 2, Result).addImm(getLower16(val)).addReg(Tmp1);
1527 }
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001528 else {
1529 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1530 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1531 unsigned CPI = CP->getConstantPoolIndex(C);
1532 AlphaLowering.restoreGP(BB);
1533 BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(CPI);
1534 }
1535 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001536 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001537 }
1538
1539 return 0;
1540}
1541
1542void ISel::Select(SDOperand N) {
1543 unsigned Tmp1, Tmp2, Opc;
Andrew Lenharth760270d2005-02-07 23:02:23 +00001544 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001545
Nate Begeman85fdeb22005-03-24 04:39:54 +00001546 if (!ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001547 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001548
1549 SDNode *Node = N.Val;
Andrew Lenharth760270d2005-02-07 23:02:23 +00001550
Andrew Lenharth760270d2005-02-07 23:02:23 +00001551 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001552
1553 default:
1554 Node->dump(); std::cerr << "\n";
1555 assert(0 && "Node not handled yet!");
1556
1557 case ISD::BRCOND: {
Andrew Lenharth445171a2005-02-08 00:40:03 +00001558 SelectBranchCC(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001559 return;
1560 }
1561
1562 case ISD::BR: {
1563 MachineBasicBlock *Dest =
1564 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1565
1566 Select(N.getOperand(0));
1567 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1568 return;
1569 }
1570
1571 case ISD::ImplicitDef:
1572 Select(N.getOperand(0));
1573 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1574 return;
1575
1576 case ISD::EntryToken: return; // Noop
1577
1578 case ISD::TokenFactor:
1579 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1580 Select(Node->getOperand(i));
1581
1582 //N.Val->dump(); std::cerr << "\n";
1583 //assert(0 && "Node not handled yet!");
1584
1585 return;
1586
1587 case ISD::CopyToReg:
1588 Select(N.getOperand(0));
1589 Tmp1 = SelectExpr(N.getOperand(1));
1590 Tmp2 = cast<RegSDNode>(N)->getReg();
1591
1592 if (Tmp1 != Tmp2) {
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001593 if (N.getOperand(1).getValueType() == MVT::f64 ||
1594 N.getOperand(1).getValueType() == MVT::f32)
Andrew Lenharth29219162005-02-07 06:31:44 +00001595 BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1596 else
1597 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001598 }
1599 return;
1600
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001601 case ISD::RET:
1602 switch (N.getNumOperands()) {
1603 default:
1604 std::cerr << N.getNumOperands() << "\n";
1605 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1606 std::cerr << N.getOperand(i).getValueType() << "\n";
1607 Node->dump();
1608 assert(0 && "Unknown return instruction!");
1609 case 2:
1610 Select(N.getOperand(0));
1611 Tmp1 = SelectExpr(N.getOperand(1));
1612 switch (N.getOperand(1).getValueType()) {
1613 default: Node->dump();
1614 assert(0 && "All other types should have been promoted!!");
1615 case MVT::f64:
1616 case MVT::f32:
1617 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1618 break;
1619 case MVT::i32:
1620 case MVT::i64:
1621 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1622 break;
1623 }
1624 break;
1625 case 1:
1626 Select(N.getOperand(0));
1627 break;
1628 }
1629 //Tmp2 = AlphaLowering.getRetAddr();
1630 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1631 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1632 return;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001633
Andrew Lenharthf311e8b2005-02-07 05:18:02 +00001634 case ISD::TRUNCSTORE:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001635 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001636 {
Andrew Lenharth9e8d1092005-02-06 15:40:40 +00001637 SDOperand Chain = N.getOperand(0);
1638 SDOperand Value = N.getOperand(1);
1639 SDOperand Address = N.getOperand(2);
1640 Select(Chain);
1641
1642 Tmp1 = SelectExpr(Value); //value
Andrew Lenharth760270d2005-02-07 23:02:23 +00001643
1644 if (opcode == ISD::STORE) {
1645 switch(Value.getValueType()) {
1646 default: assert(0 && "unknown Type in store");
1647 case MVT::i64: Opc = Alpha::STQ; break;
1648 case MVT::f64: Opc = Alpha::STT; break;
1649 case MVT::f32: Opc = Alpha::STS; break;
1650 }
1651 } else { //ISD::TRUNCSTORE
1652 switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
1653 default: assert(0 && "unknown Type in store");
1654 case MVT::i1: //FIXME: DAG does not promote this load
1655 case MVT::i8: Opc = Alpha::STB; break;
1656 case MVT::i16: Opc = Alpha::STW; break;
1657 case MVT::i32: Opc = Alpha::STL; break;
1658 }
Andrew Lenharth65838902005-02-06 16:22:15 +00001659 }
Andrew Lenharth760270d2005-02-07 23:02:23 +00001660
Andrew Lenharth9e8d1092005-02-06 15:40:40 +00001661 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001662 {
1663 AlphaLowering.restoreGP(BB);
1664 Opc = GetSymVersion(Opc);
1665 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1666 }
Andrew Lenharth05380342005-02-07 05:07:00 +00001667 else if(Address.getOpcode() == ISD::FrameIndex)
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001668 {
Andrew Lenharth032f2352005-02-22 21:59:48 +00001669 BuildMI(BB, Opc, 3).addReg(Tmp1)
1670 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
1671 .addReg(Alpha::F31);
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001672 }
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001673 else
Andrew Lenharth63f2ab22005-02-10 06:25:22 +00001674 {
1675 long offset;
1676 SelectAddr(Address, Tmp2, offset);
1677 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
1678 }
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001679 return;
1680 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001681
1682 case ISD::EXTLOAD:
1683 case ISD::SEXTLOAD:
1684 case ISD::ZEXTLOAD:
1685 case ISD::LOAD:
1686 case ISD::CopyFromReg:
1687 case ISD::CALL:
Andrew Lenharth032f2352005-02-22 21:59:48 +00001688 case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001689 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001690 SelectExpr(N);
1691 return;
1692
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001693 case ISD::ADJCALLSTACKDOWN:
1694 case ISD::ADJCALLSTACKUP:
1695 Select(N.getOperand(0));
1696 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1697
1698 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1699 Alpha::ADJUSTSTACKUP;
1700 BuildMI(BB, Opc, 1).addImm(Tmp1);
1701 return;
1702 }
1703 assert(0 && "Should not be reached!");
1704}
1705
1706
1707/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1708/// into a machine code representation using pattern matching and a machine
1709/// description file.
1710///
1711FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1712 return new ISel(TM);
1713}