blob: 2652eaaf7dd77a3a314044d16e22098681c1e856 [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);
386 if (DestType == MVT::f64) {
387 BuildMI(BB, Alpha::LDT_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
388 } else {
389 BuildMI(BB, Alpha::LDS_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
390 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000391 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000392 else
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000393 {
394 Select(Chain);
395 Tmp2 = SelectExpr(Address);
396 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
397 BuildMI(BB, Opc, 2, Result).addImm(0).addReg(Tmp2);
398 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000399 return Result;
400 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000401 case ISD::ConstantFP:
402 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
403 if (CN->isExactlyValue(+0.0)) {
404 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000405 } else if ( CN->isExactlyValue(-0.0)) {
406 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000407 } else {
408 abort();
409 }
410 }
411 return Result;
412
413 case ISD::MUL:
414 case ISD::ADD:
415 case ISD::SUB:
416 case ISD::SDIV:
417 switch( opcode ) {
418 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
419 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
420 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
421 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
422 };
423 Tmp1 = SelectExpr(N.getOperand(0));
424 Tmp2 = SelectExpr(N.getOperand(1));
425 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
426 return Result;
427
Andrew Lenharth2c594352005-01-29 15:42:07 +0000428 case ISD::EXTLOAD:
429 //include a conversion sequence for float loads to double
430 if (Result != notIn)
431 ExprMap[N.getValue(1)] = notIn; // Generate the token
432 else
433 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
434
435 Tmp2 = MakeReg(MVT::f32);
436
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000437 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
438 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
439
440 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))) {
441 AlphaLowering.restoreGP(BB);
442 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp2).addConstantPoolIndex(CP->getIndex());
443 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
444 return Result;
445 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000446 Select(Node->getOperand(0)); // chain
447 Tmp1 = SelectExpr(Node->getOperand(1));
448 BuildMI(BB, Alpha::LDS, 1, Tmp2).addReg(Tmp1);
449 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
450 return Result;
451
452
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000453 case ISD::UINT_TO_FP:
454 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000455 {
456 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
457 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000458 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000459
460 //The hard way:
461 // Spill the integer to memory and reload it from there.
462 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
463 MachineFunction *F = BB->getParent();
464 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
465
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000466 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
467 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
468 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
469 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000470
471 //The easy way: doesn't work
472// //so these instructions are not supported on ev56
473// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
474// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
475// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
476// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
477
Andrew Lenharth40831c52005-01-28 06:57:18 +0000478 return Result;
479 }
480 }
481 assert(0 && "should not get here");
482 return 0;
483}
484
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000485unsigned ISel::SelectExpr(SDOperand N) {
486 unsigned Result;
487 unsigned Tmp1, Tmp2, Tmp3;
488 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000489 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000490
491 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000492 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000493
494 unsigned &Reg = ExprMap[N];
495 if (Reg) return Reg;
496
497 if (N.getOpcode() != ISD::CALL)
498 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000499 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000500 else {
501 // If this is a call instruction, make sure to prepare ALL of the result
502 // values as well as the chain.
503 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000504 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000505 else {
506 Result = MakeReg(Node->getValueType(0));
507 ExprMap[N.getValue(0)] = Result;
508 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
509 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000510 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000511 }
512 }
513
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000514 if (DestType == MVT::f64 || DestType == MVT::f32 ||
515 (opcode == ISD::LOAD &&
516 (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)))
Andrew Lenharth40831c52005-01-28 06:57:18 +0000517 return SelectExprFP(N, Result);
518
519 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000520 default:
521 Node->dump();
522 assert(0 && "Node not handled!\n");
523
Andrew Lenharth2c594352005-01-29 15:42:07 +0000524 case ISD::ConstantPool:
525 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
526 AlphaLowering.restoreGP(BB);
527 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(Tmp1);
528 return Result;
529
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000530 case ISD::FrameIndex:
531 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Andrew Lenharth684f2292005-01-30 00:35:27 +0000532 BuildMI(BB, Alpha::LDA, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000533 return Result;
534
535 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000536 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000537 if (Result != notIn)
538 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000539 else
540 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
541
542 Select(Node->getOperand(0)); // chain
543 Tmp1 = SelectExpr(Node->getOperand(1));
544
545 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000546 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000547 case MVT::i64:
548 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
549 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000550 Node->dump();
551 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000552 case MVT::i64:
553 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
554 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000555 case MVT::i32:
556 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
557 break;
558 case MVT::i16:
559 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
560 break;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000561 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000562 case MVT::i8:
563 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
564 break;
565 }
566 break;
567 }
568 return Result;
569
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000570 case ISD::SEXTLOAD:
571 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000572 if (Result != notIn)
573 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000574 else
575 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
576
577 Select(Node->getOperand(0)); // chain
578 Tmp1 = SelectExpr(Node->getOperand(1));
579 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000580 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000581 case MVT::i64:
582 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
583 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000584 Node->dump();
585 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000586 case MVT::i32:
587 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
588 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000589 }
590 break;
591 }
592 return Result;
593
594 case ISD::ZEXTLOAD:
595 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000596 if (Result != notIn)
597 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000598 else
599 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
600
601 Select(Node->getOperand(0)); // chain
602 Tmp1 = SelectExpr(Node->getOperand(1));
603 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000604 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000605 case MVT::i64:
606 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
607 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000608 Node->dump();
609 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000610 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000611 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000612 break;
613 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000614 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000615 break;
616 }
617 break;
618 }
619 return Result;
620
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000621
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000622 case ISD::GlobalAddress:
623 AlphaLowering.restoreGP(BB);
624 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
625 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
626 return Result;
627
628 case ISD::CALL:
629 {
630 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000631
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000632 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000633 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000634
635 //grab the arguments
636 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000637 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000638 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000639 argvregs.push_back(SelectExpr(N.getOperand(i)));
640
Andrew Lenharth684f2292005-01-30 00:35:27 +0000641 //in reg args
642 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
643 {
644 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
645 Alpha::R19, Alpha::R20, Alpha::R21};
646 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
647 Alpha::F19, Alpha::F20, Alpha::F21};
648 switch(N.getOperand(i+2).getValueType()) {
649 default:
650 Node->dump();
651 N.getOperand(i).Val->dump();
652 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
653 assert(0 && "Unknown value type for call");
654 case MVT::i1:
655 case MVT::i8:
656 case MVT::i16:
657 case MVT::i32:
658 case MVT::i64:
659 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
660 break;
661 case MVT::f32:
662 case MVT::f64:
663 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
664 break;
665 }
666 }
667 //in mem args
668 for (int i = 6, e = argvregs.size(); i < e; ++i)
669 {
670 switch(N.getOperand(i+2).getValueType()) {
671 default:
672 Node->dump();
673 N.getOperand(i).Val->dump();
674 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
675 assert(0 && "Unknown value type for call");
676 case MVT::i1:
677 case MVT::i8:
678 case MVT::i16:
679 case MVT::i32:
680 case MVT::i64:
681 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
682 break;
683 case MVT::f32:
684 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
685 break;
686 case MVT::f64:
687 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
688 break;
689 }
690 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000691 //build the right kind of call
692 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000693 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
694 {
695 AlphaLowering.restoreGP(BB);
696 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
697 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000698 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000699 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
700 {
701 AlphaLowering.restoreGP(BB);
702 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
703 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000704 else
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000705 {
706 //no need to restore GP as we are doing an indirect call
707 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000708 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
709 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000710 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000711
712 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000713
714 switch (Node->getValueType(0)) {
715 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000716 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000717 case MVT::i1:
718 case MVT::i8:
719 case MVT::i16:
720 case MVT::i32:
721 case MVT::i64:
722 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
723 break;
724 case MVT::f32:
725 case MVT::f64:
726 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
727 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000728 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000729 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000730 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000731
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000732 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000733 abort();
734
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000735 case ISD::SIGN_EXTEND_INREG:
736 {
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000737 //Alpha has instructions for a bunch of signed 32 bit stuff
738 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
739 {
740 switch (N.getOperand(0).getOpcode()) {
741 case ISD::ADD:
742 case ISD::SUB:
743 case ISD::MUL:
744 {
745 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
746 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
747 //FIXME: first check for Scaled Adds and Subs!
748 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
749 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
750 { //Normal imm add/sub
751 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
752 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
753 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
754 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
755 }
756 else
757 { //Normal add/sub
758 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
759 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
760 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
761 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
762 }
763 return Result;
764 }
765 default: break; //Fall Though;
766 }
767 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000768 Tmp1 = SelectExpr(N.getOperand(0));
769 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000770 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000771 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000772 {
773 default:
774 Node->dump();
775 assert(0 && "Sign Extend InReg not there yet");
776 break;
777 case MVT::i32:
778 {
779 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
780 break;
781 }
782 case MVT::i16:
783 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
784 break;
785 case MVT::i8:
786 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
787 break;
788 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000789 return Result;
790 }
791 case ISD::ZERO_EXTEND_INREG:
792 {
793 Tmp1 = SelectExpr(N.getOperand(0));
794 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000795 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000796 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000797 {
798 default:
799 Node->dump();
800 assert(0 && "Zero Extend InReg not there yet");
801 break;
802 case MVT::i32: Tmp2 = 0xf0; break;
803 case MVT::i16: Tmp2 = 0xfc; break;
804 case MVT::i8: Tmp2 = 0xfe; break;
805 case MVT::i1: //handle this one special
806 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
807 return Result;
808 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000809 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000810 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000811 }
812
813 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000814 {
815 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
816 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
817 bool isConst1 = false;
818 bool isConst2 = false;
819 int dir;
Andrew Lenharth9818c052005-02-05 13:19:12 +0000820
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000821 //Tmp1 = SelectExpr(N.getOperand(0));
822 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000823 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
824 isConst1 = true;
825 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000826 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
827 isConst2 = true;
828
829 switch (SetCC->getCondition()) {
830 default: Node->dump(); assert(0 && "Unknown integer comparison!");
831 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
832 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
833 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
834 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
835 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
836 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
837 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
838 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
839 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000840 case ISD::SETNE: {//Handle this one special
841 //std::cerr << "Alpha does not have a setne.\n";
842 //abort();
843 Tmp1 = SelectExpr(N.getOperand(0));
844 Tmp2 = SelectExpr(N.getOperand(1));
845 Tmp3 = MakeReg(MVT::i64);
846 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
847 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000848 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
849 //BuildMI(BB,Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000850 return Result;
851 }
852 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000853 if (dir == 1) {
854 Tmp1 = SelectExpr(N.getOperand(0));
855 if (isConst2) {
856 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
857 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
858 } else {
859 Tmp2 = SelectExpr(N.getOperand(1));
860 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
861 }
862 } else if (dir == 2) {
863 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +0000864 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000865 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
866 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
867 } else {
868 Tmp2 = SelectExpr(N.getOperand(0));
869 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
870 }
871 } else { //dir == 0
872 if (isConst1) {
873 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
874 Tmp2 = SelectExpr(N.getOperand(1));
875 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
876 } else if (isConst2) {
877 Tmp1 = SelectExpr(N.getOperand(0));
878 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
879 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
880 } else {
881 Tmp1 = SelectExpr(N.getOperand(0));
882 Tmp2 = SelectExpr(N.getOperand(1));
883 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
884 }
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000885 }
886 } else {
887 //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
888 bool rev = false;
889 bool inv = false;
890
891 switch (SetCC->getCondition()) {
892 default: Node->dump(); assert(0 && "Unknown FP comparison!");
893 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
894 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
895 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
896 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
897 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
898 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
899 }
900
901 Tmp1 = SelectExpr(N.getOperand(0));
902 Tmp2 = SelectExpr(N.getOperand(1));
903 //Can only compare doubles, and dag won't promote for me
904 if (SetCC->getOperand(0).getValueType() == MVT::f32)
905 {
906 Tmp3 = MakeReg(MVT::f64);
907 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
908 Tmp1 = Tmp3;
909 }
910 if (SetCC->getOperand(1).getValueType() == MVT::f32)
911 {
912 Tmp3 = MakeReg(MVT::f64);
913 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
914 Tmp1 = Tmp2;
915 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000916
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000917 if (rev) std::swap(Tmp1, Tmp2);
918 Tmp3 = MakeReg(MVT::f64);
919 //do the comparison
920 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
921
922 //now arrange for Result (int) to have a 1 or 0
923
924 // Spill the FP to memory and reload it from there.
925 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
926 MachineFunction *F = BB->getParent();
927 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
928 unsigned Tmp4 = MakeReg(MVT::f64);
929 BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
930 BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
931 unsigned Tmp5 = MakeReg(MVT::i64);
932 BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
Andrew Lenharth9818c052005-02-05 13:19:12 +0000933
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000934 //now, set result based on Tmp5
935 //Set Tmp6 if fp cmp was false
936 unsigned Tmp6 = MakeReg(MVT::i64);
937 BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
938 //and invert
939 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
940
941 }
942 // else
943 // {
944 // Node->dump();
945 // assert(0 && "Not a setcc in setcc");
946 // }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000947 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000948 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000949 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000950
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000951 case ISD::CopyFromReg:
952 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000953 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000954 if (Result != notIn)
955 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +0000956 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000957 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +0000958
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000959 SDOperand Chain = N.getOperand(0);
960
961 Select(Chain);
962 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
963 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
964 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
965 return Result;
966 }
967
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000968 //Most of the plain arithmetic and logic share the same form, and the same
969 //constant immediate test
970 case ISD::AND:
971 case ISD::OR:
972 case ISD::XOR:
973 case ISD::SHL:
974 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +0000975 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000976 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000977 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
978 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000979 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
980 {
981 switch(opcode) {
982 case ISD::AND: Opc = Alpha::ANDi; break;
983 case ISD::OR: Opc = Alpha::BISi; break;
984 case ISD::XOR: Opc = Alpha::XORi; break;
985 case ISD::SHL: Opc = Alpha::SLi; break;
986 case ISD::SRL: Opc = Alpha::SRLi; break;
987 case ISD::SRA: Opc = Alpha::SRAi; break;
988 case ISD::MUL: Opc = Alpha::MULQi; break;
989 };
990 Tmp1 = SelectExpr(N.getOperand(0));
991 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
992 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
993 }
994 else
995 {
996 switch(opcode) {
997 case ISD::AND: Opc = Alpha::AND; break;
998 case ISD::OR: Opc = Alpha::BIS; break;
999 case ISD::XOR: Opc = Alpha::XOR; break;
1000 case ISD::SHL: Opc = Alpha::SL; break;
1001 case ISD::SRL: Opc = Alpha::SRL; break;
1002 case ISD::SRA: Opc = Alpha::SRA; break;
1003 case ISD::MUL: Opc = Alpha::MULQ; break;
1004 };
1005 Tmp1 = SelectExpr(N.getOperand(0));
1006 Tmp2 = SelectExpr(N.getOperand(1));
1007 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1008 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001009 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +00001010
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001011 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001012 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001013 {
Andrew Lenharth40831c52005-01-28 06:57:18 +00001014 bool isAdd = opcode == ISD::ADD;
1015
1016 //FIXME: first check for Scaled Adds and Subs!
1017 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001018 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1019 { //Normal imm add/sub
1020 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
1021 Tmp1 = SelectExpr(N.getOperand(0));
1022 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1023 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1024 }
1025 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001026 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
1027 { //LDA //FIXME: expand the above condition a bit
1028 Tmp1 = SelectExpr(N.getOperand(0));
1029 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1030 if (!isAdd)
1031 Tmp2 = -Tmp2;
1032 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1033 }
1034 else
1035 { //Normal add/sub
1036 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1037 Tmp1 = SelectExpr(N.getOperand(0));
1038 Tmp2 = SelectExpr(N.getOperand(1));
1039 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1040 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001041 return Result;
1042 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001043
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001044 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001045 case ISD::SREM:
1046 case ISD::SDIV:
1047 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001048 //FIXME: alpha really doesn't support any of these operations,
1049 // the ops are expanded into special library calls with
1050 // special calling conventions
1051 switch(opcode) {
1052 case ISD::UREM: Opc = Alpha::REMQU; break;
1053 case ISD::SREM: Opc = Alpha::REMQ; break;
1054 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1055 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001056 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001057 Tmp1 = SelectExpr(N.getOperand(0));
1058 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +00001059 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001060 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001061
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001062 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001063 case ISD::FP_TO_SINT:
1064 {
1065 assert (DestType == MVT::i64 && "only quads can be loaded to");
1066 MVT::ValueType SrcType = N.getOperand(0).getValueType();
1067 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1068
1069 //The hard way:
1070 // Spill the integer to memory and reload it from there.
1071 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1072 MachineFunction *F = BB->getParent();
1073 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1074
1075 //CVTTQ STT LDQ
1076 //CVTST CVTTQ STT LDQ
1077 if (SrcType == MVT::f32)
1078 {
1079 Tmp2 = MakeReg(MVT::f64);
1080 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1081 Tmp1 = Tmp2;
1082 }
1083 Tmp2 = MakeReg(MVT::f64);
1084 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1085 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1086 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1087
1088 return Result;
1089 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001090
1091// // case ISD::FP_TO_UINT:
1092
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001093 case ISD::SELECT:
1094 {
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001095 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001096 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1097 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001098 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001099 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001100 return Result;
1101 }
1102
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001103 case ISD::Constant:
1104 {
Andrew Lenharth22d5a412005-02-02 00:51:15 +00001105 unsigned long val = cast<ConstantSDNode>(N)->getValue();
1106 if (val < 32000 && (long)val > -32000)
1107 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
1108 else
1109 {
1110 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1111 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1112 unsigned CPI = CP->getConstantPoolIndex(C);
1113 AlphaLowering.restoreGP(BB);
1114 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CPI);
1115 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001116 return Result;
1117 }
1118
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001119 case ISD::LOAD:
1120 {
1121 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001122 if (Result != notIn)
1123 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001124 else
1125 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1126
1127 SDOperand Chain = N.getOperand(0);
1128 SDOperand Address = N.getOperand(1);
1129
Andrew Lenharthc23d6962005-02-02 04:35:44 +00001130 assert(N.getValue(0).getValueType() == MVT::i64 && "unknown Load dest type");
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001131
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001132 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001133 {
1134 Select(Chain);
1135 AlphaLowering.restoreGP(BB);
1136 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1137 }
1138 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1139 AlphaLowering.restoreGP(BB);
1140 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CP->getIndex());
1141 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001142 else
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001143 {
1144 Select(Chain);
1145 Tmp2 = SelectExpr(Address);
1146 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
1147 }
1148 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001149 }
1150 }
1151
1152 return 0;
1153}
1154
1155void ISel::Select(SDOperand N) {
1156 unsigned Tmp1, Tmp2, Opc;
1157
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001158 // FIXME: Disable for our current expansion model!
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001159 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001160 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001161
1162 SDNode *Node = N.Val;
1163
1164 switch (N.getOpcode()) {
1165
1166 default:
1167 Node->dump(); std::cerr << "\n";
1168 assert(0 && "Node not handled yet!");
1169
1170 case ISD::BRCOND: {
1171 MachineBasicBlock *Dest =
1172 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
1173
Andrew Lenharth9818c052005-02-05 13:19:12 +00001174 Select(N.getOperand(0)); //chain
1175
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001176 Tmp1 = SelectExpr(N.getOperand(1));
1177 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
1178 return;
1179 }
1180
1181 case ISD::BR: {
1182 MachineBasicBlock *Dest =
1183 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1184
1185 Select(N.getOperand(0));
1186 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1187 return;
1188 }
1189
1190 case ISD::ImplicitDef:
1191 Select(N.getOperand(0));
1192 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1193 return;
1194
1195 case ISD::EntryToken: return; // Noop
1196
1197 case ISD::TokenFactor:
1198 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1199 Select(Node->getOperand(i));
1200
1201 //N.Val->dump(); std::cerr << "\n";
1202 //assert(0 && "Node not handled yet!");
1203
1204 return;
1205
1206 case ISD::CopyToReg:
1207 Select(N.getOperand(0));
1208 Tmp1 = SelectExpr(N.getOperand(1));
1209 Tmp2 = cast<RegSDNode>(N)->getReg();
1210
1211 if (Tmp1 != Tmp2) {
1212 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1213 }
1214 return;
1215
1216 case ISD::RET:
1217 switch (N.getNumOperands()) {
1218 default:
1219 std::cerr << N.getNumOperands() << "\n";
1220 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1221 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001222 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001223 assert(0 && "Unknown return instruction!");
1224 case 2:
1225 Select(N.getOperand(0));
1226 Tmp1 = SelectExpr(N.getOperand(1));
1227 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001228 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
1229 case MVT::f64:
1230 case MVT::f32:
1231 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1232 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001233 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001234 case MVT::i64:
1235 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1236 break;
1237 }
1238 break;
1239 case 1:
1240 Select(N.getOperand(0));
1241 break;
1242 }
1243 //Tmp2 = AlphaLowering.getRetAddr();
1244 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1245 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1246 return;
1247
1248 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001249 {
1250 Select(N.getOperand(0));
1251 Tmp1 = SelectExpr(N.getOperand(1)); //value
1252 MVT::ValueType DestType = N.getOperand(1).getValueType();
1253 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
1254 {
1255 AlphaLowering.restoreGP(BB);
1256 if (DestType == MVT::i64) Opc = Alpha::STORE;
1257 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1258 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1259 else assert(0 && "unknown Type in store");
1260 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
1261 }
1262 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(2)))
1263 {
1264 AlphaLowering.restoreGP(BB);
1265 if (DestType == MVT::i64) Opc = Alpha::STORE;
1266 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1267 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1268 else assert(0 && "unknown Type in store");
1269 BuildMI(BB, Opc, 2).addReg(Tmp1).addConstantPoolIndex(CP->getIndex());
1270 }
1271 else
1272 {
1273 Tmp2 = SelectExpr(N.getOperand(2)); //address
1274 if (DestType == MVT::i64) Opc = Alpha::STQ;
1275 else if (DestType == MVT::f64) Opc = Alpha::STT;
1276 else if (DestType == MVT::f32) Opc = Alpha::STS;
1277 else assert(0 && "unknown Type in store");
1278 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
1279 }
1280 return;
1281 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001282
1283 case ISD::EXTLOAD:
1284 case ISD::SEXTLOAD:
1285 case ISD::ZEXTLOAD:
1286 case ISD::LOAD:
1287 case ISD::CopyFromReg:
1288 case ISD::CALL:
1289// case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001290 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001291 SelectExpr(N);
1292 return;
1293
1294
1295 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1296 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001297 if (StoredTy == MVT::i64) {
1298 Node->dump();
1299 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1300 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001301
1302 Select(N.getOperand(0));
1303 Tmp1 = SelectExpr(N.getOperand(1));
1304 Tmp2 = SelectExpr(N.getOperand(2));
1305
1306 switch (StoredTy) {
Chris Lattnerd7b59d02005-01-30 16:32:48 +00001307 default: Node->dump(); assert(0 && "Unhandled Type");
Andrew Lenharthd279b412005-01-25 19:58:40 +00001308 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001309 case MVT::i8: Opc = Alpha::STB; break;
1310 case MVT::i16: Opc = Alpha::STW; break;
1311 case MVT::i32: Opc = Alpha::STL; break;
1312 }
1313
1314 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1315 return;
1316 }
1317
1318 case ISD::ADJCALLSTACKDOWN:
1319 case ISD::ADJCALLSTACKUP:
1320 Select(N.getOperand(0));
1321 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1322
1323 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1324 Alpha::ADJUSTSTACKUP;
1325 BuildMI(BB, Opc, 1).addImm(Tmp1);
1326 return;
1327 }
1328 assert(0 && "Should not be reached!");
1329}
1330
1331
1332/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1333/// into a machine code representation using pattern matching and a machine
1334/// description file.
1335///
1336FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1337 return new ISel(TM);
1338}