blob: 3e385f6d6d350c2068dba8bd1757c670480d1ebf [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 Lenharth3d65d312005-01-27 03:49:45 +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);
65 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 Lenharthc1faced2005-02-01 01:37:24 +0000315 case ISD::FP_ROUND:
316 assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here");
317 Tmp1 = SelectExpr(N.getOperand(0));
318 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
319 return Result;
320
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000321 case ISD::FP_EXTEND:
322 assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here");
323 Tmp1 = SelectExpr(N.getOperand(0));
324 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
325 return Result;
326
Andrew Lenharth2c594352005-01-29 15:42:07 +0000327 case ISD::CopyFromReg:
328 {
329 // Make sure we generate both values.
330 if (Result != notIn)
331 ExprMap[N.getValue(1)] = notIn; // Generate the token
332 else
333 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
334
335 SDOperand Chain = N.getOperand(0);
336
337 Select(Chain);
338 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
339 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
340 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
341 return Result;
342 }
343
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000344 case ISD::LOAD:
345 {
346 // Make sure we generate both values.
347 if (Result != notIn)
348 ExprMap[N.getValue(1)] = notIn; // Generate the token
349 else
350 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000351
352 //DestType = N.getValue(0).getValueType();
353
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000354 SDOperand Chain = N.getOperand(0);
355 SDOperand Address = N.getOperand(1);
356
357 if (Address.getOpcode() == ISD::GlobalAddress)
358 {
359 Select(Chain);
360 AlphaLowering.restoreGP(BB);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000361 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000362 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
363 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000364 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
365 AlphaLowering.restoreGP(BB);
366 if (DestType == MVT::f64) {
367 BuildMI(BB, Alpha::LDT_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
368 } else {
369 BuildMI(BB, Alpha::LDS_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
370 }
371 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000372 else
373 {
374 Select(Chain);
375 Tmp2 = SelectExpr(Address);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000376 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000377 BuildMI(BB, Opc, 2, Result).addImm(0).addReg(Tmp2);
378 }
379 return Result;
380 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000381 case ISD::ConstantFP:
382 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
383 if (CN->isExactlyValue(+0.0)) {
384 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000385 } else if ( CN->isExactlyValue(-0.0)) {
386 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000387 } else {
388 abort();
389 }
390 }
391 return Result;
392
393 case ISD::MUL:
394 case ISD::ADD:
395 case ISD::SUB:
396 case ISD::SDIV:
397 switch( opcode ) {
398 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
399 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
400 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
401 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
402 };
403 Tmp1 = SelectExpr(N.getOperand(0));
404 Tmp2 = SelectExpr(N.getOperand(1));
405 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
406 return Result;
407
Andrew Lenharth2c594352005-01-29 15:42:07 +0000408 case ISD::EXTLOAD:
409 //include a conversion sequence for float loads to double
410 if (Result != notIn)
411 ExprMap[N.getValue(1)] = notIn; // Generate the token
412 else
413 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
414
415 Tmp2 = MakeReg(MVT::f32);
416
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000417 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
418 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
419
420 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))) {
421 AlphaLowering.restoreGP(BB);
422 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp2).addConstantPoolIndex(CP->getIndex());
423 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
424 return Result;
425 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000426 Select(Node->getOperand(0)); // chain
427 Tmp1 = SelectExpr(Node->getOperand(1));
428 BuildMI(BB, Alpha::LDS, 1, Tmp2).addReg(Tmp1);
429 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
430 return Result;
431
432
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000433 case ISD::UINT_TO_FP:
434 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000435 {
436 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
437 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000438 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000439
440 //The hard way:
441 // Spill the integer to memory and reload it from there.
442 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
443 MachineFunction *F = BB->getParent();
444 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
445
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000446 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
447 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
448 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
449 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000450
451 //The easy way: doesn't work
452// //so these instructions are not supported on ev56
453// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
454// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
455// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
456// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
457
Andrew Lenharth40831c52005-01-28 06:57:18 +0000458 return Result;
459 }
460 }
461 assert(0 && "should not get here");
462 return 0;
463}
464
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000465unsigned ISel::SelectExpr(SDOperand N) {
466 unsigned Result;
467 unsigned Tmp1, Tmp2, Tmp3;
468 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000469 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000470
471 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000472 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000473
474 unsigned &Reg = ExprMap[N];
475 if (Reg) return Reg;
476
477 if (N.getOpcode() != ISD::CALL)
478 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000479 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000480 else {
481 // If this is a call instruction, make sure to prepare ALL of the result
482 // values as well as the chain.
483 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000484 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000485 else {
486 Result = MakeReg(Node->getValueType(0));
487 ExprMap[N.getValue(0)] = Result;
488 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
489 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000490 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000491 }
492 }
493
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000494 if (DestType == MVT::f64 || DestType == MVT::f32 ||
495 (opcode == ISD::LOAD &&
496 (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)))
Andrew Lenharth40831c52005-01-28 06:57:18 +0000497 return SelectExprFP(N, Result);
498
499 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000500 default:
501 Node->dump();
502 assert(0 && "Node not handled!\n");
503
Andrew Lenharth2c594352005-01-29 15:42:07 +0000504 case ISD::ConstantPool:
505 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
506 AlphaLowering.restoreGP(BB);
507 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(Tmp1);
508 return Result;
509
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000510 case ISD::FrameIndex:
511 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Andrew Lenharth684f2292005-01-30 00:35:27 +0000512 BuildMI(BB, Alpha::LDA, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000513 return Result;
514
515 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000516 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000517 if (Result != notIn)
518 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000519 else
520 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
521
522 Select(Node->getOperand(0)); // chain
523 Tmp1 = SelectExpr(Node->getOperand(1));
524
525 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000526 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000527 case MVT::i64:
528 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
529 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000530 Node->dump();
531 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000532 case MVT::i64:
533 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
534 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000535 case MVT::i32:
536 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
537 break;
538 case MVT::i16:
539 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
540 break;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000541 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000542 case MVT::i8:
543 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
544 break;
545 }
546 break;
547 }
548 return Result;
549
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000550 case ISD::SEXTLOAD:
551 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000552 if (Result != notIn)
553 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000554 else
555 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
556
557 Select(Node->getOperand(0)); // chain
558 Tmp1 = SelectExpr(Node->getOperand(1));
559 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000560 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000561 case MVT::i64:
562 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
563 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000564 Node->dump();
565 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000566 case MVT::i32:
567 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
568 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000569 }
570 break;
571 }
572 return Result;
573
574 case ISD::ZEXTLOAD:
575 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000576 if (Result != notIn)
577 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000578 else
579 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
580
581 Select(Node->getOperand(0)); // chain
582 Tmp1 = SelectExpr(Node->getOperand(1));
583 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000584 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000585 case MVT::i64:
586 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
587 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000588 Node->dump();
589 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000590 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000591 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000592 break;
593 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000594 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000595 break;
596 }
597 break;
598 }
599 return Result;
600
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000601
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000602 case ISD::GlobalAddress:
603 AlphaLowering.restoreGP(BB);
604 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
605 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
606 return Result;
607
608 case ISD::CALL:
609 {
610 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000611
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000612 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000613 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000614
615 //grab the arguments
616 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000617 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000618 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000619 argvregs.push_back(SelectExpr(N.getOperand(i)));
620
Andrew Lenharth684f2292005-01-30 00:35:27 +0000621 //in reg args
622 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
623 {
624 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
625 Alpha::R19, Alpha::R20, Alpha::R21};
626 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
627 Alpha::F19, Alpha::F20, Alpha::F21};
628 switch(N.getOperand(i+2).getValueType()) {
629 default:
630 Node->dump();
631 N.getOperand(i).Val->dump();
632 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
633 assert(0 && "Unknown value type for call");
634 case MVT::i1:
635 case MVT::i8:
636 case MVT::i16:
637 case MVT::i32:
638 case MVT::i64:
639 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
640 break;
641 case MVT::f32:
642 case MVT::f64:
643 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
644 break;
645 }
646 }
647 //in mem args
648 for (int i = 6, e = argvregs.size(); i < e; ++i)
649 {
650 switch(N.getOperand(i+2).getValueType()) {
651 default:
652 Node->dump();
653 N.getOperand(i).Val->dump();
654 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
655 assert(0 && "Unknown value type for call");
656 case MVT::i1:
657 case MVT::i8:
658 case MVT::i16:
659 case MVT::i32:
660 case MVT::i64:
661 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
662 break;
663 case MVT::f32:
664 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
665 break;
666 case MVT::f64:
667 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
668 break;
669 }
670 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000671 //build the right kind of call
672 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000673 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
674 {
675 AlphaLowering.restoreGP(BB);
676 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
677 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000678 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000679 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
680 {
681 AlphaLowering.restoreGP(BB);
682 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
683 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000684 else
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000685 {
686 //no need to restore GP as we are doing an indirect call
687 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000688 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
689 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000690 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000691
692 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000693
694 switch (Node->getValueType(0)) {
695 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000696 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000697 case MVT::i1:
698 case MVT::i8:
699 case MVT::i16:
700 case MVT::i32:
701 case MVT::i64:
702 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
703 break;
704 case MVT::f32:
705 case MVT::f64:
706 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
707 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000708 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000709 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000710 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000711
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000712 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000713 abort();
714
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000715 case ISD::SIGN_EXTEND_INREG:
716 {
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000717 //Alpha has instructions for a bunch of signed 32 bit stuff
718 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
719 {
720 switch (N.getOperand(0).getOpcode()) {
721 case ISD::ADD:
722 case ISD::SUB:
723 case ISD::MUL:
724 {
725 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
726 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
727 //FIXME: first check for Scaled Adds and Subs!
728 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
729 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
730 { //Normal imm add/sub
731 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
732 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
733 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
734 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
735 }
736 else
737 { //Normal add/sub
738 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
739 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
740 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
741 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
742 }
743 return Result;
744 }
745 default: break; //Fall Though;
746 }
747 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000748 Tmp1 = SelectExpr(N.getOperand(0));
749 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000750 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000751 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000752 {
753 default:
754 Node->dump();
755 assert(0 && "Sign Extend InReg not there yet");
756 break;
757 case MVT::i32:
758 {
759 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
760 break;
761 }
762 case MVT::i16:
763 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
764 break;
765 case MVT::i8:
766 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
767 break;
768 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000769 return Result;
770 }
771 case ISD::ZERO_EXTEND_INREG:
772 {
773 Tmp1 = SelectExpr(N.getOperand(0));
774 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000775 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000776 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000777 {
778 default:
779 Node->dump();
780 assert(0 && "Zero Extend InReg not there yet");
781 break;
782 case MVT::i32: Tmp2 = 0xf0; break;
783 case MVT::i16: Tmp2 = 0xfc; break;
784 case MVT::i8: Tmp2 = 0xfe; break;
785 case MVT::i1: //handle this one special
786 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
787 return Result;
788 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000789 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000790 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000791 }
792
793 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000794 {
795 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
796 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
797 bool isConst1 = false;
798 bool isConst2 = false;
799 int dir;
800
801 //Tmp1 = SelectExpr(N.getOperand(0));
802 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000803 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
804 isConst1 = true;
805 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000806 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
807 isConst2 = true;
808
809 switch (SetCC->getCondition()) {
810 default: Node->dump(); assert(0 && "Unknown integer comparison!");
811 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
812 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
813 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
814 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
815 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
816 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
817 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
818 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
819 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000820 case ISD::SETNE: {//Handle this one special
821 //std::cerr << "Alpha does not have a setne.\n";
822 //abort();
823 Tmp1 = SelectExpr(N.getOperand(0));
824 Tmp2 = SelectExpr(N.getOperand(1));
825 Tmp3 = MakeReg(MVT::i64);
826 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
827 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000828 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
829 //BuildMI(BB,Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000830 return Result;
831 }
832 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000833 if (dir == 1) {
834 Tmp1 = SelectExpr(N.getOperand(0));
835 if (isConst2) {
836 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
837 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
838 } else {
839 Tmp2 = SelectExpr(N.getOperand(1));
840 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
841 }
842 } else if (dir == 2) {
843 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +0000844 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000845 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
846 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
847 } else {
848 Tmp2 = SelectExpr(N.getOperand(0));
849 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
850 }
851 } else { //dir == 0
852 if (isConst1) {
853 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
854 Tmp2 = SelectExpr(N.getOperand(1));
855 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
856 } else if (isConst2) {
857 Tmp1 = SelectExpr(N.getOperand(0));
858 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
859 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
860 } else {
861 Tmp1 = SelectExpr(N.getOperand(0));
862 Tmp2 = SelectExpr(N.getOperand(1));
863 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
864 }
865 }
866 }
867 else
868 {
869 Node->dump();
870 assert(0 && "only integer");
871 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000872 }
873 else
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000874 {
875 Node->dump();
876 assert(0 && "Not a setcc in setcc");
877 }
878 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000879 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000880
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000881 case ISD::CopyFromReg:
882 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000883 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000884 if (Result != notIn)
885 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +0000886 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000887 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +0000888
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000889 SDOperand Chain = N.getOperand(0);
890
891 Select(Chain);
892 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
893 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
894 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
895 return Result;
896 }
897
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000898 //Most of the plain arithmetic and logic share the same form, and the same
899 //constant immediate test
900 case ISD::AND:
901 case ISD::OR:
902 case ISD::XOR:
903 case ISD::SHL:
904 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +0000905 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000906 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000907 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
908 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000909 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
910 {
911 switch(opcode) {
912 case ISD::AND: Opc = Alpha::ANDi; break;
913 case ISD::OR: Opc = Alpha::BISi; break;
914 case ISD::XOR: Opc = Alpha::XORi; break;
915 case ISD::SHL: Opc = Alpha::SLi; break;
916 case ISD::SRL: Opc = Alpha::SRLi; break;
917 case ISD::SRA: Opc = Alpha::SRAi; break;
918 case ISD::MUL: Opc = Alpha::MULQi; break;
919 };
920 Tmp1 = SelectExpr(N.getOperand(0));
921 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
922 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
923 }
924 else
925 {
926 switch(opcode) {
927 case ISD::AND: Opc = Alpha::AND; break;
928 case ISD::OR: Opc = Alpha::BIS; break;
929 case ISD::XOR: Opc = Alpha::XOR; break;
930 case ISD::SHL: Opc = Alpha::SL; break;
931 case ISD::SRL: Opc = Alpha::SRL; break;
932 case ISD::SRA: Opc = Alpha::SRA; break;
933 case ISD::MUL: Opc = Alpha::MULQ; break;
934 };
935 Tmp1 = SelectExpr(N.getOperand(0));
936 Tmp2 = SelectExpr(N.getOperand(1));
937 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
938 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000939 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000940
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000941 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000942 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000943 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000944 bool isAdd = opcode == ISD::ADD;
945
946 //FIXME: first check for Scaled Adds and Subs!
947 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000948 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
949 { //Normal imm add/sub
950 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
951 Tmp1 = SelectExpr(N.getOperand(0));
952 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
953 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
954 }
955 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000956 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
957 { //LDA //FIXME: expand the above condition a bit
958 Tmp1 = SelectExpr(N.getOperand(0));
959 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
960 if (!isAdd)
961 Tmp2 = -Tmp2;
962 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
963 }
964 else
965 { //Normal add/sub
966 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
967 Tmp1 = SelectExpr(N.getOperand(0));
968 Tmp2 = SelectExpr(N.getOperand(1));
969 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
970 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000971 return Result;
972 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000973
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000974 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +0000975 case ISD::SREM:
976 case ISD::SDIV:
977 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000978 //FIXME: alpha really doesn't support any of these operations,
979 // the ops are expanded into special library calls with
980 // special calling conventions
981 switch(opcode) {
982 case ISD::UREM: Opc = Alpha::REMQU; break;
983 case ISD::SREM: Opc = Alpha::REMQ; break;
984 case ISD::UDIV: Opc = Alpha::DIVQU; break;
985 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000986 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000987 Tmp1 = SelectExpr(N.getOperand(0));
988 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +0000989 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000990 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000991
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000992 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000993 case ISD::FP_TO_SINT:
994 {
995 assert (DestType == MVT::i64 && "only quads can be loaded to");
996 MVT::ValueType SrcType = N.getOperand(0).getValueType();
997 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
998
999 //The hard way:
1000 // Spill the integer to memory and reload it from there.
1001 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1002 MachineFunction *F = BB->getParent();
1003 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1004
1005 //CVTTQ STT LDQ
1006 //CVTST CVTTQ STT LDQ
1007 if (SrcType == MVT::f32)
1008 {
1009 Tmp2 = MakeReg(MVT::f64);
1010 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1011 Tmp1 = Tmp2;
1012 }
1013 Tmp2 = MakeReg(MVT::f64);
1014 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1015 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1016 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1017
1018 return Result;
1019 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001020
1021// // case ISD::FP_TO_UINT:
1022
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001023 case ISD::SELECT:
1024 {
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001025 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001026 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1027 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001028 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001029 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001030 return Result;
1031 }
1032
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001033 case ISD::Constant:
1034 {
Andrew Lenharth22d5a412005-02-02 00:51:15 +00001035 unsigned long val = cast<ConstantSDNode>(N)->getValue();
1036 if (val < 32000 && (long)val > -32000)
1037 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
1038 else
1039 {
1040 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1041 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1042 unsigned CPI = CP->getConstantPoolIndex(C);
1043 AlphaLowering.restoreGP(BB);
1044 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CPI);
1045 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001046 return Result;
1047 }
1048
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001049 case ISD::LOAD:
1050 {
1051 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001052 if (Result != notIn)
1053 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001054 else
1055 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1056
1057 SDOperand Chain = N.getOperand(0);
1058 SDOperand Address = N.getOperand(1);
1059
Andrew Lenharthc23d6962005-02-02 04:35:44 +00001060 assert(N.getValue(0).getValueType() == MVT::i64 && "unknown Load dest type");
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001061
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001062 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001063 {
1064 Select(Chain);
1065 AlphaLowering.restoreGP(BB);
1066 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1067 }
1068 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1069 AlphaLowering.restoreGP(BB);
1070 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CP->getIndex());
1071 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001072 else
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001073 {
1074 Select(Chain);
1075 Tmp2 = SelectExpr(Address);
1076 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
1077 }
1078 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001079 }
1080 }
1081
1082 return 0;
1083}
1084
1085void ISel::Select(SDOperand N) {
1086 unsigned Tmp1, Tmp2, Opc;
1087
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001088 // FIXME: Disable for our current expansion model!
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001089 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001090 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001091
1092 SDNode *Node = N.Val;
1093
1094 switch (N.getOpcode()) {
1095
1096 default:
1097 Node->dump(); std::cerr << "\n";
1098 assert(0 && "Node not handled yet!");
1099
1100 case ISD::BRCOND: {
1101 MachineBasicBlock *Dest =
1102 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
1103
1104 Select(N.getOperand(0));
1105 Tmp1 = SelectExpr(N.getOperand(1));
1106 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
1107 return;
1108 }
1109
1110 case ISD::BR: {
1111 MachineBasicBlock *Dest =
1112 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1113
1114 Select(N.getOperand(0));
1115 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1116 return;
1117 }
1118
1119 case ISD::ImplicitDef:
1120 Select(N.getOperand(0));
1121 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1122 return;
1123
1124 case ISD::EntryToken: return; // Noop
1125
1126 case ISD::TokenFactor:
1127 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1128 Select(Node->getOperand(i));
1129
1130 //N.Val->dump(); std::cerr << "\n";
1131 //assert(0 && "Node not handled yet!");
1132
1133 return;
1134
1135 case ISD::CopyToReg:
1136 Select(N.getOperand(0));
1137 Tmp1 = SelectExpr(N.getOperand(1));
1138 Tmp2 = cast<RegSDNode>(N)->getReg();
1139
1140 if (Tmp1 != Tmp2) {
1141 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1142 }
1143 return;
1144
1145 case ISD::RET:
1146 switch (N.getNumOperands()) {
1147 default:
1148 std::cerr << N.getNumOperands() << "\n";
1149 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1150 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001151 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001152 assert(0 && "Unknown return instruction!");
1153 case 2:
1154 Select(N.getOperand(0));
1155 Tmp1 = SelectExpr(N.getOperand(1));
1156 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001157 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
1158 case MVT::f64:
1159 case MVT::f32:
1160 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1161 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001162 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001163 case MVT::i64:
1164 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1165 break;
1166 }
1167 break;
1168 case 1:
1169 Select(N.getOperand(0));
1170 break;
1171 }
1172 //Tmp2 = AlphaLowering.getRetAddr();
1173 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1174 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1175 return;
1176
1177 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001178 {
1179 Select(N.getOperand(0));
1180 Tmp1 = SelectExpr(N.getOperand(1)); //value
1181 MVT::ValueType DestType = N.getOperand(1).getValueType();
1182 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
1183 {
1184 AlphaLowering.restoreGP(BB);
1185 if (DestType == MVT::i64) Opc = Alpha::STORE;
1186 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1187 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1188 else assert(0 && "unknown Type in store");
1189 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
1190 }
1191 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(2)))
1192 {
1193 AlphaLowering.restoreGP(BB);
1194 if (DestType == MVT::i64) Opc = Alpha::STORE;
1195 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1196 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1197 else assert(0 && "unknown Type in store");
1198 BuildMI(BB, Opc, 2).addReg(Tmp1).addConstantPoolIndex(CP->getIndex());
1199 }
1200 else
1201 {
1202 Tmp2 = SelectExpr(N.getOperand(2)); //address
1203 if (DestType == MVT::i64) Opc = Alpha::STQ;
1204 else if (DestType == MVT::f64) Opc = Alpha::STT;
1205 else if (DestType == MVT::f32) Opc = Alpha::STS;
1206 else assert(0 && "unknown Type in store");
1207 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
1208 }
1209 return;
1210 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001211
1212 case ISD::EXTLOAD:
1213 case ISD::SEXTLOAD:
1214 case ISD::ZEXTLOAD:
1215 case ISD::LOAD:
1216 case ISD::CopyFromReg:
1217 case ISD::CALL:
1218// case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001219 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001220 SelectExpr(N);
1221 return;
1222
1223
1224 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1225 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001226 if (StoredTy == MVT::i64) {
1227 Node->dump();
1228 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1229 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001230
1231 Select(N.getOperand(0));
1232 Tmp1 = SelectExpr(N.getOperand(1));
1233 Tmp2 = SelectExpr(N.getOperand(2));
1234
1235 switch (StoredTy) {
Chris Lattnerd7b59d02005-01-30 16:32:48 +00001236 default: Node->dump(); assert(0 && "Unhandled Type");
Andrew Lenharthd279b412005-01-25 19:58:40 +00001237 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001238 case MVT::i8: Opc = Alpha::STB; break;
1239 case MVT::i16: Opc = Alpha::STW; break;
1240 case MVT::i32: Opc = Alpha::STL; break;
1241 }
1242
1243 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1244 return;
1245 }
1246
1247 case ISD::ADJCALLSTACKDOWN:
1248 case ISD::ADJCALLSTACKUP:
1249 Select(N.getOperand(0));
1250 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1251
1252 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1253 Alpha::ADJUSTSTACKUP;
1254 BuildMI(BB, Opc, 1).addImm(Tmp1);
1255 return;
1256 }
1257 assert(0 && "Should not be reached!");
1258}
1259
1260
1261/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1262/// into a machine code representation using pattern matching and a machine
1263/// description file.
1264///
1265FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1266 return new ISel(TM);
1267}