blob: 0e1cf144251bb7ce6bcbd68553097561ef7ed9ad [file] [log] [blame]
Andrew Lenharth2d6f0222005-01-24 19:44:07 +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>
30using namespace llvm;
31
32//===----------------------------------------------------------------------===//
33// AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
34namespace {
35 class AlphaTargetLowering : public TargetLowering {
36 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
37 unsigned GP; //GOT vreg
38 public:
39 AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
40 // Set up the TargetLowering object.
41 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
42 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
43
44 setOperationAction(ISD::EXTLOAD , MVT::i1 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000045
Andrew Lenharth304d0f32005-01-22 23:41:55 +000046 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000047 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000048
Andrew Lenharth304d0f32005-01-22 23:41:55 +000049 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
50 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
51 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
52
Andrew Lenharth02981182005-01-26 01:24:38 +000053 setOperationAction(ISD::ZERO_EXTEND_INREG, MVT::i1, Expand);
54 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
55
Andrew Lenharth3e98fde2005-01-26 21:54:09 +000056 // setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand);
57 // setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand);
58 setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
59 setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
60 setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote);
61 setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Promote);
62
63 setOperationAction(ISD::FP_TO_SINT , MVT::f32 , Promote);
Andrew Lenharth02981182005-01-26 01:24:38 +000064
Andrew Lenharth304d0f32005-01-22 23:41:55 +000065 computeRegisterProperties();
66
Andrew Lenharth304d0f32005-01-22 23:41:55 +000067 // addLegalFPImmediate(+0.0); // FLD0
68 // addLegalFPImmediate(+1.0); // FLD1
69 // addLegalFPImmediate(-0.0); // FLD0/FCHS
70 // addLegalFPImmediate(-1.0); // FLD1/FCHS
71 }
72
73 /// LowerArguments - This hook must be implemented to indicate how we should
74 /// lower the arguments for the specified function, into the specified DAG.
75 virtual std::vector<SDOperand>
76 LowerArguments(Function &F, SelectionDAG &DAG);
77
78 /// LowerCallTo - This hook lowers an abstract call to a function into an
79 /// actual call.
80 virtual std::pair<SDOperand, SDOperand>
81 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
82 ArgListTy &Args, SelectionDAG &DAG);
83
84 virtual std::pair<SDOperand, SDOperand>
85 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
86
87 virtual std::pair<SDOperand,SDOperand>
88 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
89 const Type *ArgTy, SelectionDAG &DAG);
90
91 virtual std::pair<SDOperand, SDOperand>
92 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
93 SelectionDAG &DAG);
94
95 void restoreGP(MachineBasicBlock* BB)
96 {
97 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
98 }
99 };
100}
101
102//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
103
104//For now, just use variable size stack frame format
105
106//In a standard call, the first six items are passed in registers $16
107//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
108//of argument-to-register correspondence.) The remaining items are
109//collected in a memory argument list that is a naturally aligned
110//array of quadwords. In a standard call, this list, if present, must
111//be passed at 0(SP).
112//7 ... n 0(SP) ... (n-7)*8(SP)
113
114std::vector<SDOperand>
115AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
116{
117 std::vector<SDOperand> ArgValues;
118
119 // //#define FP $15
120 // //#define RA $26
121 // //#define PV $27
122 // //#define GP $29
123 // //#define SP $30
124
125 // assert(0 && "TODO");
126 MachineFunction &MF = DAG.getMachineFunction();
127 MachineFrameInfo *MFI = MF.getFrameInfo();
128
129 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
130 MachineBasicBlock& BB = MF.front();
131
132 //Handle the return address
133 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
134
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000135 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
136 Alpha::R19, Alpha::R20, Alpha::R21};
137 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
138 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000139 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000140 std::vector<unsigned> argPreg;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000141 int count = 0;
142 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
143 {
144 ++count;
145 assert(count <= 6 && "More than 6 args not supported");
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000146 switch (getValueType(I->getType())) {
147 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
148 case MVT::f64:
149 case MVT::f32:
150 BuildMI(&BB, Alpha::IDEF, 0, args_float[count - 1]);
151 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
152 argPreg.push_back(args_float[count - 1]);
153 break;
154 case MVT::i1:
155 case MVT::i8:
156 case MVT::i16:
157 case MVT::i32:
158 case MVT::i64:
159 BuildMI(&BB, Alpha::IDEF, 0, args_int[count - 1]);
Andrew Lenharthc0d502e2005-01-27 00:52:26 +0000160 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000161 argPreg.push_back(args_int[count - 1]);
162 break;
163 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000164 }
165
166 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
167 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
168 count = 0;
169 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
170 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000171 SDOperand newroot;
172 unsigned Opc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000173 switch (getValueType(I->getType()))
174 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000175 default: assert(0 && "Unhandled type");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000176 case MVT::i64:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000177 case MVT::i32:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000178 case MVT::i16:
179 case MVT::i8:
180 case MVT::i1:
181 Opc = Alpha::BIS;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000182 break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000183 case MVT::f32:
184 case MVT::f64:
185 Opc = Alpha::CPYS;
186 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000187 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000188 BuildMI(&BB, Opc, 2, argVreg[count]).addReg(argPreg[count]).addReg(argPreg[count]);
189 newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000190 DAG.setRoot(newroot.getValue(1));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000191 ArgValues.push_back(newroot);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000192 ++count;
193 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000194
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000195 return ArgValues;
196}
197
198std::pair<SDOperand, SDOperand>
199AlphaTargetLowering::LowerCallTo(SDOperand Chain,
200 const Type *RetTy, SDOperand Callee,
201 ArgListTy &Args, SelectionDAG &DAG) {
202 int NumBytes = 0;
203 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
204 DAG.getConstant(NumBytes, getPointerTy()));
205 std::vector<SDOperand> args_to_use;
206 for (unsigned i = 0, e = Args.size(); i != e; ++i)
207 {
208 switch (getValueType(Args[i].second)) {
209 default: assert(0 && "Unexpected ValueType for argument!");
210 case MVT::i1:
211 case MVT::i8:
212 case MVT::i16:
213 case MVT::i32:
214 // Promote the integer to 64 bits. If the input type is signed use a
215 // sign extend, otherwise use a zero extend.
216 if (Args[i].second->isSigned())
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000217 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND_INREG, MVT::i64, Args[i].first);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000218 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000219 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND_INREG, MVT::i64, Args[i].first);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000220 break;
221 case MVT::i64:
222 break;
223 }
224 args_to_use.push_back(Args[i].first);
225 }
226
227 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.
279 std::map<SDOperand, unsigned> ExprMap;
280 std::set<SDOperand> LoweredTokens;
281
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();
294 LoweredTokens.clear();
295 }
296
297 unsigned SelectExpr(SDOperand N);
298 void Select(SDOperand N);
299 };
300}
301
302unsigned ISel::SelectExpr(SDOperand N) {
303 unsigned Result;
304 unsigned Tmp1, Tmp2, Tmp3;
305 unsigned Opc = 0;
306
307 SDNode *Node = N.Val;
308
309 unsigned &Reg = ExprMap[N];
310 if (Reg) return Reg;
311
312 if (N.getOpcode() != ISD::CALL)
313 Reg = Result = (N.getValueType() != MVT::Other) ?
314 MakeReg(N.getValueType()) : 1;
315 else {
316 // If this is a call instruction, make sure to prepare ALL of the result
317 // values as well as the chain.
318 if (Node->getNumValues() == 1)
319 Reg = Result = 1; // Void call, just a chain.
320 else {
321 Result = MakeReg(Node->getValueType(0));
322 ExprMap[N.getValue(0)] = Result;
323 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
324 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
325 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
326 }
327 }
328
329 switch (N.getOpcode()) {
330 default:
331 Node->dump();
332 assert(0 && "Node not handled!\n");
333
334 case ISD::FrameIndex:
335 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
336 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
337 return Result;
338
339 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000340 // Make sure we generate both values.
341 if (Result != 1)
342 ExprMap[N.getValue(1)] = 1; // Generate the token
343 else
344 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
345
346 Select(Node->getOperand(0)); // chain
347 Tmp1 = SelectExpr(Node->getOperand(1));
348
349 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000350 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000351 case MVT::i64:
352 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
353 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000354 Node->dump();
355 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000356 case MVT::i64:
357 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
358 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000359 case MVT::i32:
360 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
361 break;
362 case MVT::i16:
363 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
364 break;
365 case MVT::i8:
Andrew Lenharthd279b412005-01-25 19:58:40 +0000366 case MVT::i1: //FIXME: DAG does not expand i8??
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000367 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
368 break;
369 }
370 break;
371 }
372 return Result;
373
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000374 case ISD::SEXTLOAD:
375 // Make sure we generate both values.
376 if (Result != 1)
377 ExprMap[N.getValue(1)] = 1; // Generate the token
378 else
379 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
380
381 Select(Node->getOperand(0)); // chain
382 Tmp1 = SelectExpr(Node->getOperand(1));
383 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000384 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000385 case MVT::i64:
386 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
387 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000388 Node->dump();
389 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000390 case MVT::i32:
391 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
392 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000393// case MVT::i16:
394// BuildMI(BB, Alpha::LDW, 2, Result).addImm(0).addReg(Tmp1);
395// break;
396// case MVT::i8:
397// BuildMI(BB, Alpha::LDB, 2, Result).addImm(0).addReg(Tmp1);
398// break;
399 }
400 break;
401 }
402 return Result;
403
404 case ISD::ZEXTLOAD:
405 // Make sure we generate both values.
406 if (Result != 1)
407 ExprMap[N.getValue(1)] = 1; // Generate the token
408 else
409 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
410
411 Select(Node->getOperand(0)); // chain
412 Tmp1 = SelectExpr(Node->getOperand(1));
413 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000414 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000415 case MVT::i64:
416 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
417 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000418 Node->dump();
419 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000420 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000421 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000422 break;
423 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000424 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000425 break;
426 }
427 break;
428 }
429 return Result;
430
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000431
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000432 case ISD::GlobalAddress:
433 AlphaLowering.restoreGP(BB);
434 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
435 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
436 return Result;
437
438 case ISD::CALL:
439 {
440 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000441
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000442 // The chain for this call is now lowered.
443 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1));
444
445 //grab the arguments
446 std::vector<unsigned> argvregs;
447 assert(Node->getNumOperands() < 8 && "Only 6 args supported");
448 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000449 argvregs.push_back(SelectExpr(N.getOperand(i)));
450
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000451 for(int i = 0, e = argvregs.size(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000452 {
453 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
454 Alpha::R19, Alpha::R20, Alpha::R21};
455 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
456 Alpha::F19, Alpha::F20, Alpha::F21};
457 switch(N.getOperand(i).getValueType()) {
458 default: Node->dump(); assert(0 && "Unknown value type for call");
459 case MVT::i1:
460 case MVT::i8:
461 case MVT::i16:
462 case MVT::i32:
463 case MVT::i64:
464 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
465 break;
466 case MVT::f32:
467 case MVT::f64:
468 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
469 break;
470 }
471
472 }
473 //build the right kind of call
474 if (GlobalAddressSDNode *GASD =
475 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
476 {
477 Select(N.getOperand(0));
478 AlphaLowering.restoreGP(BB);
479 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
480 }
481 else if (ExternalSymbolSDNode *ESSDN =
482 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
483 {
484 Select(N.getOperand(0));
485 AlphaLowering.restoreGP(BB);
486 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
487 }
488 else
489 {
490 Select(N.getOperand(0));
491 Tmp1 = SelectExpr(N.getOperand(1));
492 BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1);
493 AlphaLowering.restoreGP(BB);
494 }
495
496 //push the result into a virtual register
497 // if (Result != 1)
498 // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
499
500 switch (Node->getValueType(0)) {
501 default: Node->dump(); assert(0 && "Unknown value type for call result!");
502 case MVT::Other: return 1;
503 case MVT::i1:
504 case MVT::i8:
505 case MVT::i16:
506 case MVT::i32:
507 case MVT::i64:
508 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
509 break;
510 case MVT::f32:
511 case MVT::f64:
512 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
513 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000514 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000515 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000516 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000517
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000518 case ISD::SIGN_EXTEND:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000519 case ISD::SIGN_EXTEND_INREG:
520 {
521 Tmp1 = SelectExpr(N.getOperand(0));
522 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000523 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000524 switch(MVN->getExtraValueType())
525 {
526 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000527 Node->dump();
528 assert(0 && "Sign Extend InReg not there yet");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000529 break;
530 case MVT::i32:
531 {
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000532 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000533 break;
534 }
535 case MVT::i16:
536 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
537 break;
538 case MVT::i8:
539 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
540 break;
541 }
542 return Result;
543 }
544 case ISD::ZERO_EXTEND_INREG:
545 {
546 Tmp1 = SelectExpr(N.getOperand(0));
547 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000548 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000549 switch(MVN->getExtraValueType())
550 {
551 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000552 Node->dump();
553 assert(0 && "Zero Extend InReg not there yet");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000554 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000555 case MVT::i32: Tmp2 = 0xf0; break;
556 case MVT::i16: Tmp2 = 0xfc; break;
557 case MVT::i8: Tmp2 = 0xfe; break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000558 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000559 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
560 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000561 }
562
563 case ISD::SETCC:
564 Tmp1 = SelectExpr(N.getOperand(0));
565 Tmp2 = SelectExpr(N.getOperand(1));
566 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
567 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
568 switch (SetCC->getCondition()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000569 default: Node->dump(); assert(0 && "Unknown integer comparison!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000570 case ISD::SETEQ:
571 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
572 break;
573 case ISD::SETGT:
574 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp2).addReg(Tmp1);
575 break;
576 case ISD::SETGE:
577 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp2).addReg(Tmp1);
578 break;
579 case ISD::SETLT:
580 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp1).addReg(Tmp2);
581 break;
582 case ISD::SETLE:
583 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp1).addReg(Tmp2);
584 break;
585 case ISD::SETNE:
586 {
587 unsigned Tmp3 = MakeReg(MVT::i64);
588 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
589 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp3).addReg(Alpha::R31);
590 break;
591 }
592 case ISD::SETULT:
593 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
594 break;
595 case ISD::SETUGT:
596 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp2).addReg(Tmp1);
597 break;
598 case ISD::SETULE:
599 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp1).addReg(Tmp2);
600 break;
601 case ISD::SETUGE:
602 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp2).addReg(Tmp1);
603 break;
604 }
605 }
606 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000607 {
608 Node->dump();
609 assert(0 && "only integer");
610 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000611 }
612 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000613 {
614 Node->dump();
615 assert(0 && "Not a setcc in setcc");
616 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000617 return Result;
618
619 case ISD::CopyFromReg:
620 {
621 if (Result == 1)
622 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
623
624 SDOperand Chain = N.getOperand(0);
625
626 Select(Chain);
627 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
628 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
629 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
630 return Result;
631 }
632
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000633 //Most of the plain arithmetic and logic share the same form, and the same
634 //constant immediate test
635 case ISD::AND:
636 case ISD::OR:
637 case ISD::XOR:
638 case ISD::SHL:
639 case ISD::SRL:
640 case ISD::MUL:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000641 switch (N.getValueType()) {
642 default: Node->dump(); assert (0 && "unhandled type");
643 case MVT::f64:
644 assert(N.getOpcode() == ISD::MUL && "only mul here please");
645 Tmp1 = SelectExpr(N.getOperand(0));
646 Tmp2 = SelectExpr(N.getOperand(1));
647 BuildMI(BB, Alpha::MULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
648 break;
649 case MVT::f32:
650 assert(N.getOpcode() == ISD::MUL && "only mul here please");
651 Tmp1 = SelectExpr(N.getOperand(0));
652 Tmp2 = SelectExpr(N.getOperand(1));
653 BuildMI(BB, Alpha::MULS, 2, Result).addReg(Tmp1).addReg(Tmp2);
654 break;
655 case MVT::i64:
656 if(N.getOperand(1).getOpcode() == ISD::Constant &&
657 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
658 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
659 {
660 switch(N.getOpcode()) {
661 case ISD::AND: Opc = Alpha::ANDi; break;
662 case ISD::OR: Opc = Alpha::BISi; break;
663 case ISD::XOR: Opc = Alpha::XORi; break;
664 case ISD::SHL: Opc = Alpha::SLi; break;
665 case ISD::SRL: Opc = Alpha::SRLi; break;
666 case ISD::SRA: Opc = Alpha::SRAi; break;
667 case ISD::MUL: Opc = Alpha::MULQi; break;
668 };
669 Tmp1 = SelectExpr(N.getOperand(0));
670 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
671 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
672 }
673 else
674 {
675 switch(N.getOpcode()) {
676 case ISD::AND: Opc = Alpha::AND; break;
677 case ISD::OR: Opc = Alpha::BIS; break;
678 case ISD::XOR: Opc = Alpha::XOR; break;
679 case ISD::SHL: Opc = Alpha::SL; break;
680 case ISD::SRL: Opc = Alpha::SRL; break;
681 case ISD::SRA: Opc = Alpha::SRA; break;
682 case ISD::MUL: Opc = Alpha::MULQ; break;
683 };
684 Tmp1 = SelectExpr(N.getOperand(0));
685 Tmp2 = SelectExpr(N.getOperand(1));
686 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
687 }
688 break;
689 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000690 return Result;
691
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000692 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000693 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000694 {
695 bool isAdd = N.getOpcode() == ISD::ADD;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000696
697 switch (N.getValueType()) {
698 default: Node->dump(); assert(0 && "Unhandled type");
699 case MVT::i64: {
700 //FIXME: first check for Scaled Adds and Subs!
701 if(N.getOperand(1).getOpcode() == ISD::Constant &&
702 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
703 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
704 { //Normal imm add/sub
705 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
706 Tmp1 = SelectExpr(N.getOperand(0));
707 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
708 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
709 }
710 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
711 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
712 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
713 { //LDA //FIXME: expand the above condition a bit
714 Tmp1 = SelectExpr(N.getOperand(0));
715 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
716 if (!isAdd)
717 Tmp2 = -Tmp2;
718 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
719 }
720 else
721 { //Normal add/sub
722 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
723 Tmp1 = SelectExpr(N.getOperand(0));
724 Tmp2 = SelectExpr(N.getOperand(1));
725 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
726 }
727 } break;
728 case MVT::f64:
729 case MVT::f32:
730 if (N.getValueType() == MVT::f64)
731 Opc = isAdd ? Alpha::ADDT : Alpha::SUBT;
732 else
733 Opc = isAdd ? Alpha::ADDS : Alpha::SUBS;
734 //
735 Tmp1 = SelectExpr(N.getOperand(0));
736 Tmp2 = SelectExpr(N.getOperand(1));
737 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
738 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000739 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000740 return Result;
741 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000742
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000743 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +0000744 case ISD::SREM:
745 case ISD::SDIV:
746 case ISD::UDIV:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000747 switch (N.getValueType()) {
748 default: Node->dump(); assert (0 && "unhandled type");
749 case MVT::f64:
750 assert(N.getOpcode() == ISD::SDIV && "only div here please");
751 Opc = Alpha::DIVT;
752 break;
753 case MVT::f32:
754 assert(N.getOpcode() == ISD::SDIV && "only div here please");
755 Opc = Alpha::DIVS;
756 break;
757 case MVT::i64:
758 //FIXME: alpha really doesn't support any of these operations,
759 // the ops are expanded into special library calls with
760 // special calling conventions
761 switch(N.getOpcode()) {
762 case ISD::UREM: Opc = Alpha::REMQU; break;
763 case ISD::SREM: Opc = Alpha::REMQ; break;
764 case ISD::UDIV: Opc = Alpha::DIVQU; break;
765 case ISD::SDIV: Opc = Alpha::DIVQ; break;
766 }
767 break;
768 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000769 Tmp1 = SelectExpr(N.getOperand(0));
770 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +0000771 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000772 return Result;
773
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000774// case ISD::SINT_TO_FP:
775// MVT::ValueType DestTy = N.getValueType();
776// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
777// Tmp2 = MakeReg(DestTy);
778// Opc = DestTy == MVT::f64 ? ITOFT : ITOFS;
779// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
780// Opc = DestTy == MVT::f64 ? CVTQT : CVTQS;
781// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
782// // case ISD::UINT_TO_FP:
783
784// case ISD::FP_TO_SINT:
785// assert (N.getValueType() == MVT::f64 && "Only can convert for doubles");
786// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
787// Tmp2 = MakeReg(SrcTy);
788// BuildMI(BB, CVTTQ, 1, Tmp2).addReg(Tmp1);
789// BuildMI(BB, FTOIT, 1, Result).addReg(Tmp2);
790// return result;
791
792// // case ISD::FP_TO_UINT:
793
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000794 case ISD::SELECT:
795 {
796 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
797 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
798 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
799 // Get the condition into the zero flag.
800 unsigned dummy = MakeReg(MVT::i64);
801 BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
802 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
803 return Result;
804 }
805
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000806 case ISD::Constant:
807 {
808 long val = cast<ConstantSDNode>(N)->getValue();
809 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
810 return Result;
811 }
812
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000813 case ISD::LOAD:
814 {
815 // Make sure we generate both values.
816 if (Result != 1)
817 ExprMap[N.getValue(1)] = 1; // Generate the token
818 else
819 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
820
821 SDOperand Chain = N.getOperand(0);
822 SDOperand Address = N.getOperand(1);
823
824 if (Address.getOpcode() == ISD::GlobalAddress)
825 {
826 Select(Chain);
827 AlphaLowering.restoreGP(BB);
828 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
829 }
830 else
831 {
832 Select(Chain);
833 Tmp2 = SelectExpr(Address);
834 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
835 }
836 return Result;
837 }
838 }
839
840 return 0;
841}
842
843void ISel::Select(SDOperand N) {
844 unsigned Tmp1, Tmp2, Opc;
845
846 // FIXME: Disable for our current expansion model!
847 if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
848 return; // Already selected.
849
850 SDNode *Node = N.Val;
851
852 switch (N.getOpcode()) {
853
854 default:
855 Node->dump(); std::cerr << "\n";
856 assert(0 && "Node not handled yet!");
857
858 case ISD::BRCOND: {
859 MachineBasicBlock *Dest =
860 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
861
862 Select(N.getOperand(0));
863 Tmp1 = SelectExpr(N.getOperand(1));
864 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
865 return;
866 }
867
868 case ISD::BR: {
869 MachineBasicBlock *Dest =
870 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
871
872 Select(N.getOperand(0));
873 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
874 return;
875 }
876
877 case ISD::ImplicitDef:
878 Select(N.getOperand(0));
879 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
880 return;
881
882 case ISD::EntryToken: return; // Noop
883
884 case ISD::TokenFactor:
885 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
886 Select(Node->getOperand(i));
887
888 //N.Val->dump(); std::cerr << "\n";
889 //assert(0 && "Node not handled yet!");
890
891 return;
892
893 case ISD::CopyToReg:
894 Select(N.getOperand(0));
895 Tmp1 = SelectExpr(N.getOperand(1));
896 Tmp2 = cast<RegSDNode>(N)->getReg();
897
898 if (Tmp1 != Tmp2) {
899 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
900 }
901 return;
902
903 case ISD::RET:
904 switch (N.getNumOperands()) {
905 default:
906 std::cerr << N.getNumOperands() << "\n";
907 for (unsigned i = 0; i < N.getNumOperands(); ++i)
908 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000909 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000910 assert(0 && "Unknown return instruction!");
911 case 2:
912 Select(N.getOperand(0));
913 Tmp1 = SelectExpr(N.getOperand(1));
914 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000915 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
916 case MVT::f64:
917 case MVT::f32:
918 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
919 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000920 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000921 case MVT::i64:
922 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
923 break;
924 }
925 break;
926 case 1:
927 Select(N.getOperand(0));
928 break;
929 }
930 //Tmp2 = AlphaLowering.getRetAddr();
931 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
932 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
933 return;
934
935 case ISD::STORE:
936 Select(N.getOperand(0));
937 Tmp1 = SelectExpr(N.getOperand(1)); //value
938 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
939 {
940 AlphaLowering.restoreGP(BB);
941 BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
942 }
943 else
944 {
945 Tmp2 = SelectExpr(N.getOperand(2)); //address
946 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
947 }
948 return;
949
950 case ISD::EXTLOAD:
951 case ISD::SEXTLOAD:
952 case ISD::ZEXTLOAD:
953 case ISD::LOAD:
954 case ISD::CopyFromReg:
955 case ISD::CALL:
956// case ISD::DYNAMIC_STACKALLOC:
957 SelectExpr(N);
958 return;
959
960
961 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
962 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000963 if (StoredTy == MVT::i64) {
964 Node->dump();
965 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
966 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000967
968 Select(N.getOperand(0));
969 Tmp1 = SelectExpr(N.getOperand(1));
970 Tmp2 = SelectExpr(N.getOperand(2));
971
972 switch (StoredTy) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000973 default: Node->dump(); assert(0 && "Unhandled Type"); break;
Andrew Lenharthd279b412005-01-25 19:58:40 +0000974 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000975 case MVT::i8: Opc = Alpha::STB; break;
976 case MVT::i16: Opc = Alpha::STW; break;
977 case MVT::i32: Opc = Alpha::STL; break;
978 }
979
980 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
981 return;
982 }
983
984 case ISD::ADJCALLSTACKDOWN:
985 case ISD::ADJCALLSTACKUP:
986 Select(N.getOperand(0));
987 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
988
989 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
990 Alpha::ADJUSTSTACKUP;
991 BuildMI(BB, Opc, 1).addImm(Tmp1);
992 return;
993 }
994 assert(0 && "Should not be reached!");
995}
996
997
998/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
999/// into a machine code representation using pattern matching and a machine
1000/// description file.
1001///
1002FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1003 return new ISel(TM);
1004}