blob: bcfaae74fd6897bef64d6534e0584bcf7335b10a [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"
29#include <set>
Andrew Lenharth684f2292005-01-30 00:35:27 +000030#include <algorithm>
Andrew Lenharth304d0f32005-01-22 23:41:55 +000031using namespace llvm;
32
33//===----------------------------------------------------------------------===//
34// AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
35namespace {
36 class AlphaTargetLowering : public TargetLowering {
37 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
38 unsigned GP; //GOT vreg
39 public:
40 AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
41 // Set up the TargetLowering object.
Andrew Lenharth3d65d312005-01-27 03:49:45 +000042 //I am having problems with shr n ubyte 1
Andrew Lenharth879ef222005-02-02 17:00:21 +000043 setShiftAmountType(MVT::i64);
44 setSetCCResultType(MVT::i64);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000045
Andrew Lenharth304d0f32005-01-22 23:41:55 +000046 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
47 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000048 addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000049
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000050 setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000051
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000052 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000053 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000054
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000055 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000056 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
57 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
58
Andrew Lenharth3d65d312005-01-27 03:49:45 +000059 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); //what is the sign expansion of 1? 1 or -1?
Andrew Lenharth02981182005-01-26 01:24:38 +000060
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 Lenharth3d65d312005-01-27 03:49:45 +000068 computeRegisterProperties();
Andrew Lenharth304d0f32005-01-22 23:41:55 +000069
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000070 addLegalFPImmediate(+0.0); //F31
Andrew Lenharth12dd2622005-02-03 21:01:15 +000071 addLegalFPImmediate(-0.0); //-F31
Andrew Lenharth304d0f32005-01-22 23:41:55 +000072 }
73
74 /// LowerArguments - This hook must be implemented to indicate how we should
75 /// lower the arguments for the specified function, into the specified DAG.
76 virtual std::vector<SDOperand>
77 LowerArguments(Function &F, SelectionDAG &DAG);
78
79 /// LowerCallTo - This hook lowers an abstract call to a function into an
80 /// actual call.
81 virtual std::pair<SDOperand, SDOperand>
82 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
83 ArgListTy &Args, SelectionDAG &DAG);
84
85 virtual std::pair<SDOperand, SDOperand>
86 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
87
88 virtual std::pair<SDOperand,SDOperand>
89 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
90 const Type *ArgTy, SelectionDAG &DAG);
91
92 virtual std::pair<SDOperand, SDOperand>
93 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
94 SelectionDAG &DAG);
95
96 void restoreGP(MachineBasicBlock* BB)
97 {
98 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
99 }
100 };
101}
102
103//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
104
105//For now, just use variable size stack frame format
106
107//In a standard call, the first six items are passed in registers $16
108//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
109//of argument-to-register correspondence.) The remaining items are
110//collected in a memory argument list that is a naturally aligned
111//array of quadwords. In a standard call, this list, if present, must
112//be passed at 0(SP).
113//7 ... n 0(SP) ... (n-7)*8(SP)
114
115std::vector<SDOperand>
116AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
117{
118 std::vector<SDOperand> ArgValues;
119
120 // //#define FP $15
121 // //#define RA $26
122 // //#define PV $27
123 // //#define GP $29
124 // //#define SP $30
125
126 // assert(0 && "TODO");
127 MachineFunction &MF = DAG.getMachineFunction();
128 MachineFrameInfo *MFI = MF.getFrameInfo();
129
130 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
131 MachineBasicBlock& BB = MF.front();
132
133 //Handle the return address
134 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
135
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000136 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
137 Alpha::R19, Alpha::R20, Alpha::R21};
138 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
139 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000140 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000141 std::vector<unsigned> argPreg;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000142 std::vector<unsigned> argOpc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000143 int count = 0;
144 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
145 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000146 SDOperand newroot, argt;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000147 if (count < 6) {
148 switch (getValueType(I->getType())) {
149 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
150 case MVT::f64:
151 case MVT::f32:
152 BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
153 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
154 argPreg.push_back(args_float[count]);
155 argOpc.push_back(Alpha::CPYS);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000156 argt = newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth684f2292005-01-30 00:35:27 +0000157 break;
158 case MVT::i1:
159 case MVT::i8:
160 case MVT::i16:
161 case MVT::i32:
162 case MVT::i64:
163 BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
164 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
165 argPreg.push_back(args_int[count]);
166 argOpc.push_back(Alpha::BIS);
167 argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
168 if (getValueType(I->getType()) != MVT::i64)
169 argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
170 break;
171 }
172 } else { //more args
173 // Create the frame index object for this incoming parameter...
174 int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
175
176 // Create the SelectionDAG nodes corresponding to a load from this parameter
177 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
178 argt = newroot = DAG.getLoad(getValueType(I->getType()), DAG.getEntryNode(), FIN);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000179 }
180 DAG.setRoot(newroot.getValue(1));
181 ArgValues.push_back(argt);
Andrew Lenharth684f2292005-01-30 00:35:27 +0000182 ++count;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000183 }
184
185 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
186 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000187 for (int i = 0; i < std::min(count,6); ++i)
Andrew Lenharth40831c52005-01-28 06:57:18 +0000188 BuildMI(&BB, argOpc[i], 2, argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
189
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000190 return ArgValues;
191}
192
193std::pair<SDOperand, SDOperand>
194AlphaTargetLowering::LowerCallTo(SDOperand Chain,
195 const Type *RetTy, SDOperand Callee,
196 ArgListTy &Args, SelectionDAG &DAG) {
197 int NumBytes = 0;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000198 if (Args.size() > 6)
199 NumBytes = (Args.size() - 6) * 8;
200
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000201 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
202 DAG.getConstant(NumBytes, getPointerTy()));
203 std::vector<SDOperand> args_to_use;
204 for (unsigned i = 0, e = Args.size(); i != e; ++i)
205 {
206 switch (getValueType(Args[i].second)) {
207 default: assert(0 && "Unexpected ValueType for argument!");
208 case MVT::i1:
209 case MVT::i8:
210 case MVT::i16:
211 case MVT::i32:
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000212 // Promote the integer to 64 bits. If the input type is signed use a
213 // sign extend, otherwise use a zero extend.
214 if (Args[i].second->isSigned())
Andrew Lenharth40831c52005-01-28 06:57:18 +0000215 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000216 else
Andrew Lenharth40831c52005-01-28 06:57:18 +0000217 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000218 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000219 case MVT::i64:
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000220 case MVT::f64:
221 case MVT::f32:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000222 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000223 }
224 args_to_use.push_back(Args[i].first);
225 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000226
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000227 std::vector<MVT::ValueType> RetVals;
228 MVT::ValueType RetTyVT = getValueType(RetTy);
229 if (RetTyVT != MVT::isVoid)
230 RetVals.push_back(RetTyVT);
231 RetVals.push_back(MVT::Other);
232
233 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
234 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
235 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
236 DAG.getConstant(NumBytes, getPointerTy()));
237 return std::make_pair(TheCall, Chain);
238}
239
240std::pair<SDOperand, SDOperand>
241AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
242 //vastart just returns the address of the VarArgsFrameIndex slot.
243 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
244}
245
246std::pair<SDOperand,SDOperand> AlphaTargetLowering::
247LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
248 const Type *ArgTy, SelectionDAG &DAG) {
249 abort();
250}
251
252
253std::pair<SDOperand, SDOperand> AlphaTargetLowering::
254LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
255 SelectionDAG &DAG) {
256 abort();
257}
258
259
260
261
262
263namespace {
264
265 //===--------------------------------------------------------------------===//
266 /// ISel - Alpha specific code to select Alpha machine instructions for
267 /// SelectionDAG operations.
268 ///
269 class ISel : public SelectionDAGISel {
270
271 /// AlphaLowering - This object fully describes how to lower LLVM code to an
272 /// Alpha-specific SelectionDAG.
273 AlphaTargetLowering AlphaLowering;
274
275
276 /// ExprMap - As shared expressions are codegen'd, we keep track of which
277 /// vreg the value is produced in, so we only emit one copy of each compiled
278 /// tree.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000279 static const unsigned notIn = (unsigned)(-1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000280 std::map<SDOperand, unsigned> ExprMap;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000281
282 public:
283 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
284 }
285
286 /// InstructionSelectBasicBlock - This callback is invoked by
287 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
288 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
289 // Codegen the basic block.
290 Select(DAG.getRoot());
291
292 // Clear state used for selection.
293 ExprMap.clear();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000294 }
295
296 unsigned SelectExpr(SDOperand N);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000297 unsigned SelectExprFP(SDOperand N, unsigned Result);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000298 void Select(SDOperand N);
299 };
300}
301
Andrew Lenharth40831c52005-01-28 06:57:18 +0000302unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
303{
304 unsigned Tmp1, Tmp2, Tmp3;
305 unsigned Opc = 0;
306 SDNode *Node = N.Val;
307 MVT::ValueType DestType = N.getValueType();
308 unsigned opcode = N.getOpcode();
309
310 switch (opcode) {
311 default:
312 Node->dump();
313 assert(0 && "Node not handled!\n");
Andrew Lenharth2c594352005-01-29 15:42:07 +0000314
Andrew Lenharth9818c052005-02-05 13:19:12 +0000315 case ISD::SELECT:
316 {
317 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
318 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
319 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000320
321
322 // Spill the cond to memory and reload it from there.
323 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
324 MachineFunction *F = BB->getParent();
325 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
326 unsigned Tmp4 = MakeReg(MVT::f64);
327 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
328 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
329 //now ideally, we don't have to do anything to the flag...
Andrew Lenharth9818c052005-02-05 13:19:12 +0000330 // Get the condition into the zero flag.
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000331 BuildMI(BB, Alpha::FCMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp4);
Andrew Lenharth9818c052005-02-05 13:19:12 +0000332 return Result;
333 }
334
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000335 case ISD::FP_ROUND:
336 assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here");
337 Tmp1 = SelectExpr(N.getOperand(0));
338 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
339 return Result;
340
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000341 case ISD::FP_EXTEND:
342 assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here");
343 Tmp1 = SelectExpr(N.getOperand(0));
344 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
345 return Result;
346
Andrew Lenharth2c594352005-01-29 15:42:07 +0000347 case ISD::CopyFromReg:
348 {
349 // Make sure we generate both values.
350 if (Result != notIn)
351 ExprMap[N.getValue(1)] = notIn; // Generate the token
352 else
353 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
354
355 SDOperand Chain = N.getOperand(0);
356
357 Select(Chain);
358 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
359 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
360 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
361 return Result;
362 }
363
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000364 case ISD::LOAD:
365 {
366 // Make sure we generate both values.
367 if (Result != notIn)
368 ExprMap[N.getValue(1)] = notIn; // Generate the token
369 else
370 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000371
372 //DestType = N.getValue(0).getValueType();
373
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000374 SDOperand Chain = N.getOperand(0);
375 SDOperand Address = N.getOperand(1);
376
377 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000378 {
379 Select(Chain);
380 AlphaLowering.restoreGP(BB);
381 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
382 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
383 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000384 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000385 AlphaLowering.restoreGP(BB);
Andrew Lenharth97127a12005-02-05 17:41:39 +0000386 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
387 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000388 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000389 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000390 else
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000391 {
392 Select(Chain);
393 Tmp2 = SelectExpr(Address);
394 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
395 BuildMI(BB, Opc, 2, Result).addImm(0).addReg(Tmp2);
396 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000397 return Result;
398 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000399 case ISD::ConstantFP:
400 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
401 if (CN->isExactlyValue(+0.0)) {
402 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000403 } else if ( CN->isExactlyValue(-0.0)) {
404 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000405 } else {
406 abort();
407 }
408 }
409 return Result;
410
411 case ISD::MUL:
412 case ISD::ADD:
413 case ISD::SUB:
414 case ISD::SDIV:
415 switch( opcode ) {
416 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
417 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
418 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
419 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
420 };
421 Tmp1 = SelectExpr(N.getOperand(0));
422 Tmp2 = SelectExpr(N.getOperand(1));
423 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
424 return Result;
425
Andrew Lenharth2c594352005-01-29 15:42:07 +0000426 case ISD::EXTLOAD:
427 //include a conversion sequence for float loads to double
428 if (Result != notIn)
429 ExprMap[N.getValue(1)] = notIn; // Generate the token
430 else
431 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
432
433 Tmp2 = MakeReg(MVT::f32);
434
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000435 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
436 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
437
438 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))) {
439 AlphaLowering.restoreGP(BB);
440 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp2).addConstantPoolIndex(CP->getIndex());
441 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
442 return Result;
443 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000444 Select(Node->getOperand(0)); // chain
445 Tmp1 = SelectExpr(Node->getOperand(1));
446 BuildMI(BB, Alpha::LDS, 1, Tmp2).addReg(Tmp1);
447 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
448 return Result;
449
450
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000451 case ISD::UINT_TO_FP:
452 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000453 {
454 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
455 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000456 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000457
458 //The hard way:
459 // Spill the integer to memory and reload it from there.
460 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
461 MachineFunction *F = BB->getParent();
462 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
463
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000464 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
465 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
466 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
467 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000468
469 //The easy way: doesn't work
470// //so these instructions are not supported on ev56
471// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
472// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
473// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
474// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
475
Andrew Lenharth40831c52005-01-28 06:57:18 +0000476 return Result;
477 }
478 }
479 assert(0 && "should not get here");
480 return 0;
481}
482
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000483unsigned ISel::SelectExpr(SDOperand N) {
484 unsigned Result;
485 unsigned Tmp1, Tmp2, Tmp3;
486 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000487 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000488
489 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000490 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000491
492 unsigned &Reg = ExprMap[N];
493 if (Reg) return Reg;
494
495 if (N.getOpcode() != ISD::CALL)
496 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000497 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000498 else {
499 // If this is a call instruction, make sure to prepare ALL of the result
500 // values as well as the chain.
501 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000502 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000503 else {
504 Result = MakeReg(Node->getValueType(0));
505 ExprMap[N.getValue(0)] = Result;
506 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
507 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000508 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000509 }
510 }
511
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000512 if (DestType == MVT::f64 || DestType == MVT::f32 ||
513 (opcode == ISD::LOAD &&
514 (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)))
Andrew Lenharth40831c52005-01-28 06:57:18 +0000515 return SelectExprFP(N, Result);
516
517 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000518 default:
519 Node->dump();
520 assert(0 && "Node not handled!\n");
521
Andrew Lenharth2c594352005-01-29 15:42:07 +0000522 case ISD::ConstantPool:
523 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
524 AlphaLowering.restoreGP(BB);
525 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(Tmp1);
526 return Result;
527
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000528 case ISD::FrameIndex:
529 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Andrew Lenharth684f2292005-01-30 00:35:27 +0000530 BuildMI(BB, Alpha::LDA, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000531 return Result;
532
533 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000534 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000535 if (Result != notIn)
536 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000537 else
538 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
539
540 Select(Node->getOperand(0)); // chain
541 Tmp1 = SelectExpr(Node->getOperand(1));
542
543 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000544 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000545 case MVT::i64:
546 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
547 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000548 Node->dump();
549 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000550 case MVT::i64:
551 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
552 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000553 case MVT::i32:
554 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
555 break;
556 case MVT::i16:
557 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
558 break;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000559 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000560 case MVT::i8:
561 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
562 break;
563 }
564 break;
565 }
566 return Result;
567
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000568 case ISD::SEXTLOAD:
569 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000570 if (Result != notIn)
571 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000572 else
573 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
574
575 Select(Node->getOperand(0)); // chain
576 Tmp1 = SelectExpr(Node->getOperand(1));
577 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000578 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000579 case MVT::i64:
580 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
581 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000582 Node->dump();
583 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000584 case MVT::i32:
585 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
586 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000587 }
588 break;
589 }
590 return Result;
591
592 case ISD::ZEXTLOAD:
593 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000594 if (Result != notIn)
595 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000596 else
597 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
598
599 Select(Node->getOperand(0)); // chain
600 Tmp1 = SelectExpr(Node->getOperand(1));
601 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000602 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000603 case MVT::i64:
604 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
605 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000606 Node->dump();
607 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000608 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000609 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000610 break;
611 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000612 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000613 break;
614 }
615 break;
616 }
617 return Result;
618
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000619
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000620 case ISD::GlobalAddress:
621 AlphaLowering.restoreGP(BB);
622 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
623 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
624 return Result;
625
626 case ISD::CALL:
627 {
628 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000629
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000630 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000631 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000632
633 //grab the arguments
634 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000635 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000636 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000637 argvregs.push_back(SelectExpr(N.getOperand(i)));
638
Andrew Lenharth684f2292005-01-30 00:35:27 +0000639 //in reg args
640 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
641 {
642 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
643 Alpha::R19, Alpha::R20, Alpha::R21};
644 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
645 Alpha::F19, Alpha::F20, Alpha::F21};
646 switch(N.getOperand(i+2).getValueType()) {
647 default:
648 Node->dump();
649 N.getOperand(i).Val->dump();
650 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
651 assert(0 && "Unknown value type for call");
652 case MVT::i1:
653 case MVT::i8:
654 case MVT::i16:
655 case MVT::i32:
656 case MVT::i64:
657 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
658 break;
659 case MVT::f32:
660 case MVT::f64:
661 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
662 break;
663 }
664 }
665 //in mem args
666 for (int i = 6, e = argvregs.size(); i < e; ++i)
667 {
668 switch(N.getOperand(i+2).getValueType()) {
669 default:
670 Node->dump();
671 N.getOperand(i).Val->dump();
672 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
673 assert(0 && "Unknown value type for call");
674 case MVT::i1:
675 case MVT::i8:
676 case MVT::i16:
677 case MVT::i32:
678 case MVT::i64:
679 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
680 break;
681 case MVT::f32:
682 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
683 break;
684 case MVT::f64:
685 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
686 break;
687 }
688 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000689 //build the right kind of call
690 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000691 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
692 {
693 AlphaLowering.restoreGP(BB);
694 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
695 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000696 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000697 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
698 {
699 AlphaLowering.restoreGP(BB);
700 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
701 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000702 else
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000703 {
704 //no need to restore GP as we are doing an indirect call
705 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000706 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
707 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000708 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000709
710 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000711
712 switch (Node->getValueType(0)) {
713 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000714 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000715 case MVT::i1:
716 case MVT::i8:
717 case MVT::i16:
718 case MVT::i32:
719 case MVT::i64:
720 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
721 break;
722 case MVT::f32:
723 case MVT::f64:
724 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
725 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000726 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000727 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000728 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000729
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000730 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000731 abort();
732
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000733 case ISD::SIGN_EXTEND_INREG:
734 {
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000735 //Alpha has instructions for a bunch of signed 32 bit stuff
736 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
737 {
738 switch (N.getOperand(0).getOpcode()) {
739 case ISD::ADD:
740 case ISD::SUB:
741 case ISD::MUL:
742 {
743 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
744 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
745 //FIXME: first check for Scaled Adds and Subs!
746 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
747 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
748 { //Normal imm add/sub
749 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
750 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
751 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
752 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
753 }
754 else
755 { //Normal add/sub
756 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
757 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
758 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
759 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
760 }
761 return Result;
762 }
763 default: break; //Fall Though;
764 }
765 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000766 Tmp1 = SelectExpr(N.getOperand(0));
767 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000768 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000769 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000770 {
771 default:
772 Node->dump();
773 assert(0 && "Sign Extend InReg not there yet");
774 break;
775 case MVT::i32:
776 {
777 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
778 break;
779 }
780 case MVT::i16:
781 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
782 break;
783 case MVT::i8:
784 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
785 break;
786 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000787 return Result;
788 }
789 case ISD::ZERO_EXTEND_INREG:
790 {
791 Tmp1 = SelectExpr(N.getOperand(0));
792 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000793 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000794 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000795 {
796 default:
797 Node->dump();
798 assert(0 && "Zero Extend InReg not there yet");
799 break;
800 case MVT::i32: Tmp2 = 0xf0; break;
801 case MVT::i16: Tmp2 = 0xfc; break;
802 case MVT::i8: Tmp2 = 0xfe; break;
803 case MVT::i1: //handle this one special
804 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
805 return Result;
806 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000807 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000808 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000809 }
810
811 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000812 {
813 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
814 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
815 bool isConst1 = false;
816 bool isConst2 = false;
817 int dir;
Andrew Lenharth9818c052005-02-05 13:19:12 +0000818
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000819 //Tmp1 = SelectExpr(N.getOperand(0));
820 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000821 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
822 isConst1 = true;
823 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000824 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
825 isConst2 = true;
826
827 switch (SetCC->getCondition()) {
828 default: Node->dump(); assert(0 && "Unknown integer comparison!");
829 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
830 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
831 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
832 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
833 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
834 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
835 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
836 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
837 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000838 case ISD::SETNE: {//Handle this one special
839 //std::cerr << "Alpha does not have a setne.\n";
840 //abort();
841 Tmp1 = SelectExpr(N.getOperand(0));
842 Tmp2 = SelectExpr(N.getOperand(1));
843 Tmp3 = MakeReg(MVT::i64);
844 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
845 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000846 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000847 return Result;
848 }
849 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000850 if (dir == 1) {
851 Tmp1 = SelectExpr(N.getOperand(0));
852 if (isConst2) {
853 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
854 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
855 } else {
856 Tmp2 = SelectExpr(N.getOperand(1));
857 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
858 }
859 } else if (dir == 2) {
860 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +0000861 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000862 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
863 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
864 } else {
865 Tmp2 = SelectExpr(N.getOperand(0));
866 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
867 }
868 } else { //dir == 0
869 if (isConst1) {
870 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
871 Tmp2 = SelectExpr(N.getOperand(1));
872 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
873 } else if (isConst2) {
874 Tmp1 = SelectExpr(N.getOperand(0));
875 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
876 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
877 } else {
878 Tmp1 = SelectExpr(N.getOperand(0));
879 Tmp2 = SelectExpr(N.getOperand(1));
880 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
881 }
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000882 }
883 } else {
884 //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
885 bool rev = false;
886 bool inv = false;
887
888 switch (SetCC->getCondition()) {
889 default: Node->dump(); assert(0 && "Unknown FP comparison!");
890 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
891 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
892 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
893 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
894 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
895 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
896 }
897
898 Tmp1 = SelectExpr(N.getOperand(0));
899 Tmp2 = SelectExpr(N.getOperand(1));
900 //Can only compare doubles, and dag won't promote for me
901 if (SetCC->getOperand(0).getValueType() == MVT::f32)
902 {
903 Tmp3 = MakeReg(MVT::f64);
904 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
905 Tmp1 = Tmp3;
906 }
907 if (SetCC->getOperand(1).getValueType() == MVT::f32)
908 {
909 Tmp3 = MakeReg(MVT::f64);
910 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
911 Tmp1 = Tmp2;
912 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000913
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000914 if (rev) std::swap(Tmp1, Tmp2);
915 Tmp3 = MakeReg(MVT::f64);
916 //do the comparison
917 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
918
919 //now arrange for Result (int) to have a 1 or 0
920
921 // Spill the FP to memory and reload it from there.
922 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
923 MachineFunction *F = BB->getParent();
924 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
925 unsigned Tmp4 = MakeReg(MVT::f64);
926 BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
927 BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
928 unsigned Tmp5 = MakeReg(MVT::i64);
929 BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
Andrew Lenharth9818c052005-02-05 13:19:12 +0000930
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000931 //now, set result based on Tmp5
932 //Set Tmp6 if fp cmp was false
933 unsigned Tmp6 = MakeReg(MVT::i64);
934 BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
935 //and invert
936 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
937
938 }
939 // else
940 // {
941 // Node->dump();
942 // assert(0 && "Not a setcc in setcc");
943 // }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000944 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000945 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000946 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000947
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000948 case ISD::CopyFromReg:
949 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000950 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000951 if (Result != notIn)
952 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +0000953 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000954 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +0000955
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000956 SDOperand Chain = N.getOperand(0);
957
958 Select(Chain);
959 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
960 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
961 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
962 return Result;
963 }
964
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000965 //Most of the plain arithmetic and logic share the same form, and the same
966 //constant immediate test
967 case ISD::AND:
968 case ISD::OR:
969 case ISD::XOR:
970 case ISD::SHL:
971 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +0000972 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000973 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000974 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
975 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000976 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
977 {
978 switch(opcode) {
979 case ISD::AND: Opc = Alpha::ANDi; break;
980 case ISD::OR: Opc = Alpha::BISi; break;
981 case ISD::XOR: Opc = Alpha::XORi; break;
982 case ISD::SHL: Opc = Alpha::SLi; break;
983 case ISD::SRL: Opc = Alpha::SRLi; break;
984 case ISD::SRA: Opc = Alpha::SRAi; break;
985 case ISD::MUL: Opc = Alpha::MULQi; break;
986 };
987 Tmp1 = SelectExpr(N.getOperand(0));
988 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
989 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
990 }
991 else
992 {
993 switch(opcode) {
994 case ISD::AND: Opc = Alpha::AND; break;
995 case ISD::OR: Opc = Alpha::BIS; break;
996 case ISD::XOR: Opc = Alpha::XOR; break;
997 case ISD::SHL: Opc = Alpha::SL; break;
998 case ISD::SRL: Opc = Alpha::SRL; break;
999 case ISD::SRA: Opc = Alpha::SRA; break;
1000 case ISD::MUL: Opc = Alpha::MULQ; break;
1001 };
1002 Tmp1 = SelectExpr(N.getOperand(0));
1003 Tmp2 = SelectExpr(N.getOperand(1));
1004 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1005 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001006 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +00001007
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001008 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001009 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001010 {
Andrew Lenharth40831c52005-01-28 06:57:18 +00001011 bool isAdd = opcode == ISD::ADD;
1012
1013 //FIXME: first check for Scaled Adds and Subs!
1014 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001015 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1016 { //Normal imm add/sub
1017 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
1018 Tmp1 = SelectExpr(N.getOperand(0));
1019 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1020 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1021 }
1022 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001023 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
1024 { //LDA //FIXME: expand the above condition a bit
1025 Tmp1 = SelectExpr(N.getOperand(0));
1026 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1027 if (!isAdd)
1028 Tmp2 = -Tmp2;
1029 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1030 }
1031 else
1032 { //Normal add/sub
1033 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1034 Tmp1 = SelectExpr(N.getOperand(0));
1035 Tmp2 = SelectExpr(N.getOperand(1));
1036 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1037 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001038 return Result;
1039 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001040
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001041 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001042 case ISD::SREM:
1043 case ISD::SDIV:
1044 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001045 //FIXME: alpha really doesn't support any of these operations,
1046 // the ops are expanded into special library calls with
1047 // special calling conventions
1048 switch(opcode) {
1049 case ISD::UREM: Opc = Alpha::REMQU; break;
1050 case ISD::SREM: Opc = Alpha::REMQ; break;
1051 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1052 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001053 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001054 Tmp1 = SelectExpr(N.getOperand(0));
1055 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +00001056 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001057 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001058
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001059 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001060 case ISD::FP_TO_SINT:
1061 {
1062 assert (DestType == MVT::i64 && "only quads can be loaded to");
1063 MVT::ValueType SrcType = N.getOperand(0).getValueType();
1064 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1065
1066 //The hard way:
1067 // Spill the integer to memory and reload it from there.
1068 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1069 MachineFunction *F = BB->getParent();
1070 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1071
1072 //CVTTQ STT LDQ
1073 //CVTST CVTTQ STT LDQ
1074 if (SrcType == MVT::f32)
1075 {
1076 Tmp2 = MakeReg(MVT::f64);
1077 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1078 Tmp1 = Tmp2;
1079 }
1080 Tmp2 = MakeReg(MVT::f64);
1081 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1082 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1083 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1084
1085 return Result;
1086 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001087
1088// // case ISD::FP_TO_UINT:
1089
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001090 case ISD::SELECT:
1091 {
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001092 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001093 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1094 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001095 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001096 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001097 return Result;
1098 }
1099
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001100 case ISD::Constant:
1101 {
Andrew Lenharth22d5a412005-02-02 00:51:15 +00001102 unsigned long val = cast<ConstantSDNode>(N)->getValue();
1103 if (val < 32000 && (long)val > -32000)
1104 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
1105 else
1106 {
1107 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1108 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1109 unsigned CPI = CP->getConstantPoolIndex(C);
1110 AlphaLowering.restoreGP(BB);
1111 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CPI);
1112 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001113 return Result;
1114 }
1115
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001116 case ISD::LOAD:
1117 {
1118 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001119 if (Result != notIn)
1120 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001121 else
1122 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1123
1124 SDOperand Chain = N.getOperand(0);
1125 SDOperand Address = N.getOperand(1);
1126
Andrew Lenharthc23d6962005-02-02 04:35:44 +00001127 assert(N.getValue(0).getValueType() == MVT::i64 && "unknown Load dest type");
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001128
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001129 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001130 {
1131 Select(Chain);
1132 AlphaLowering.restoreGP(BB);
1133 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1134 }
1135 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1136 AlphaLowering.restoreGP(BB);
1137 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CP->getIndex());
1138 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001139 else
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001140 {
1141 Select(Chain);
1142 Tmp2 = SelectExpr(Address);
1143 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
1144 }
1145 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001146 }
1147 }
1148
1149 return 0;
1150}
1151
1152void ISel::Select(SDOperand N) {
1153 unsigned Tmp1, Tmp2, Opc;
1154
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001155 // FIXME: Disable for our current expansion model!
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001156 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001157 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001158
1159 SDNode *Node = N.Val;
1160
1161 switch (N.getOpcode()) {
1162
1163 default:
1164 Node->dump(); std::cerr << "\n";
1165 assert(0 && "Node not handled yet!");
1166
1167 case ISD::BRCOND: {
1168 MachineBasicBlock *Dest =
1169 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
1170
Andrew Lenharth9818c052005-02-05 13:19:12 +00001171 Select(N.getOperand(0)); //chain
1172
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001173 Tmp1 = SelectExpr(N.getOperand(1));
1174 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
1175 return;
1176 }
1177
1178 case ISD::BR: {
1179 MachineBasicBlock *Dest =
1180 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1181
1182 Select(N.getOperand(0));
1183 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1184 return;
1185 }
1186
1187 case ISD::ImplicitDef:
1188 Select(N.getOperand(0));
1189 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1190 return;
1191
1192 case ISD::EntryToken: return; // Noop
1193
1194 case ISD::TokenFactor:
1195 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1196 Select(Node->getOperand(i));
1197
1198 //N.Val->dump(); std::cerr << "\n";
1199 //assert(0 && "Node not handled yet!");
1200
1201 return;
1202
1203 case ISD::CopyToReg:
1204 Select(N.getOperand(0));
1205 Tmp1 = SelectExpr(N.getOperand(1));
1206 Tmp2 = cast<RegSDNode>(N)->getReg();
1207
1208 if (Tmp1 != Tmp2) {
1209 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1210 }
1211 return;
1212
1213 case ISD::RET:
1214 switch (N.getNumOperands()) {
1215 default:
1216 std::cerr << N.getNumOperands() << "\n";
1217 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1218 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001219 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001220 assert(0 && "Unknown return instruction!");
1221 case 2:
1222 Select(N.getOperand(0));
1223 Tmp1 = SelectExpr(N.getOperand(1));
1224 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001225 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
1226 case MVT::f64:
1227 case MVT::f32:
1228 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1229 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001230 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001231 case MVT::i64:
1232 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1233 break;
1234 }
1235 break;
1236 case 1:
1237 Select(N.getOperand(0));
1238 break;
1239 }
1240 //Tmp2 = AlphaLowering.getRetAddr();
1241 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1242 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1243 return;
1244
1245 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001246 {
1247 Select(N.getOperand(0));
1248 Tmp1 = SelectExpr(N.getOperand(1)); //value
1249 MVT::ValueType DestType = N.getOperand(1).getValueType();
1250 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
1251 {
1252 AlphaLowering.restoreGP(BB);
1253 if (DestType == MVT::i64) Opc = Alpha::STORE;
1254 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1255 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1256 else assert(0 && "unknown Type in store");
1257 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
1258 }
1259 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(2)))
1260 {
1261 AlphaLowering.restoreGP(BB);
1262 if (DestType == MVT::i64) Opc = Alpha::STORE;
1263 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1264 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1265 else assert(0 && "unknown Type in store");
1266 BuildMI(BB, Opc, 2).addReg(Tmp1).addConstantPoolIndex(CP->getIndex());
1267 }
1268 else
1269 {
1270 Tmp2 = SelectExpr(N.getOperand(2)); //address
1271 if (DestType == MVT::i64) Opc = Alpha::STQ;
1272 else if (DestType == MVT::f64) Opc = Alpha::STT;
1273 else if (DestType == MVT::f32) Opc = Alpha::STS;
1274 else assert(0 && "unknown Type in store");
1275 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
1276 }
1277 return;
1278 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001279
1280 case ISD::EXTLOAD:
1281 case ISD::SEXTLOAD:
1282 case ISD::ZEXTLOAD:
1283 case ISD::LOAD:
1284 case ISD::CopyFromReg:
1285 case ISD::CALL:
1286// case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001287 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001288 SelectExpr(N);
1289 return;
1290
1291
1292 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1293 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001294 if (StoredTy == MVT::i64) {
1295 Node->dump();
1296 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1297 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001298
1299 Select(N.getOperand(0));
1300 Tmp1 = SelectExpr(N.getOperand(1));
1301 Tmp2 = SelectExpr(N.getOperand(2));
1302
1303 switch (StoredTy) {
Chris Lattnerd7b59d02005-01-30 16:32:48 +00001304 default: Node->dump(); assert(0 && "Unhandled Type");
Andrew Lenharthd279b412005-01-25 19:58:40 +00001305 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001306 case MVT::i8: Opc = Alpha::STB; break;
1307 case MVT::i16: Opc = Alpha::STW; break;
1308 case MVT::i32: Opc = Alpha::STL; break;
1309 }
1310
1311 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1312 return;
1313 }
1314
1315 case ISD::ADJCALLSTACKDOWN:
1316 case ISD::ADJCALLSTACKUP:
1317 Select(N.getOperand(0));
1318 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1319
1320 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1321 Alpha::ADJUSTSTACKUP;
1322 BuildMI(BB, Opc, 1).addImm(Tmp1);
1323 return;
1324 }
1325 assert(0 && "Should not be reached!");
1326}
1327
1328
1329/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1330/// into a machine code representation using pattern matching and a machine
1331/// description file.
1332///
1333FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1334 return new ISel(TM);
1335}