blob: df6d00da992073143d706f500ca43b26fc9c407f [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;
Andrew Lenharth7e57bd52005-01-27 01:22:48 +0000223 case MVT::f64:
224 case MVT::f32:
225 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000226 }
227 args_to_use.push_back(Args[i].first);
228 }
229
230 std::vector<MVT::ValueType> RetVals;
231 MVT::ValueType RetTyVT = getValueType(RetTy);
232 if (RetTyVT != MVT::isVoid)
233 RetVals.push_back(RetTyVT);
234 RetVals.push_back(MVT::Other);
235
236 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
237 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
238 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
239 DAG.getConstant(NumBytes, getPointerTy()));
240 return std::make_pair(TheCall, Chain);
241}
242
243std::pair<SDOperand, SDOperand>
244AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
245 //vastart just returns the address of the VarArgsFrameIndex slot.
246 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
247}
248
249std::pair<SDOperand,SDOperand> AlphaTargetLowering::
250LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
251 const Type *ArgTy, SelectionDAG &DAG) {
252 abort();
253}
254
255
256std::pair<SDOperand, SDOperand> AlphaTargetLowering::
257LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
258 SelectionDAG &DAG) {
259 abort();
260}
261
262
263
264
265
266namespace {
267
268 //===--------------------------------------------------------------------===//
269 /// ISel - Alpha specific code to select Alpha machine instructions for
270 /// SelectionDAG operations.
271 ///
272 class ISel : public SelectionDAGISel {
273
274 /// AlphaLowering - This object fully describes how to lower LLVM code to an
275 /// Alpha-specific SelectionDAG.
276 AlphaTargetLowering AlphaLowering;
277
278
279 /// ExprMap - As shared expressions are codegen'd, we keep track of which
280 /// vreg the value is produced in, so we only emit one copy of each compiled
281 /// tree.
282 std::map<SDOperand, unsigned> ExprMap;
283 std::set<SDOperand> LoweredTokens;
284
285 public:
286 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
287 }
288
289 /// InstructionSelectBasicBlock - This callback is invoked by
290 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
291 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
292 // Codegen the basic block.
293 Select(DAG.getRoot());
294
295 // Clear state used for selection.
296 ExprMap.clear();
297 LoweredTokens.clear();
298 }
299
300 unsigned SelectExpr(SDOperand N);
301 void Select(SDOperand N);
302 };
303}
304
305unsigned ISel::SelectExpr(SDOperand N) {
306 unsigned Result;
307 unsigned Tmp1, Tmp2, Tmp3;
308 unsigned Opc = 0;
309
310 SDNode *Node = N.Val;
311
312 unsigned &Reg = ExprMap[N];
313 if (Reg) return Reg;
314
315 if (N.getOpcode() != ISD::CALL)
316 Reg = Result = (N.getValueType() != MVT::Other) ?
317 MakeReg(N.getValueType()) : 1;
318 else {
319 // If this is a call instruction, make sure to prepare ALL of the result
320 // values as well as the chain.
321 if (Node->getNumValues() == 1)
322 Reg = Result = 1; // Void call, just a chain.
323 else {
324 Result = MakeReg(Node->getValueType(0));
325 ExprMap[N.getValue(0)] = Result;
326 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
327 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
328 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
329 }
330 }
331
332 switch (N.getOpcode()) {
333 default:
334 Node->dump();
335 assert(0 && "Node not handled!\n");
336
337 case ISD::FrameIndex:
338 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
339 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
340 return Result;
341
342 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000343 // Make sure we generate both values.
344 if (Result != 1)
345 ExprMap[N.getValue(1)] = 1; // Generate the token
346 else
347 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
348
349 Select(Node->getOperand(0)); // chain
350 Tmp1 = SelectExpr(Node->getOperand(1));
351
352 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000353 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000354 case MVT::i64:
355 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
356 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000357 Node->dump();
358 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000359 case MVT::i64:
360 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
361 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000362 case MVT::i32:
363 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
364 break;
365 case MVT::i16:
366 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
367 break;
368 case MVT::i8:
Andrew Lenharthd279b412005-01-25 19:58:40 +0000369 case MVT::i1: //FIXME: DAG does not expand i8??
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000370 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
371 break;
372 }
373 break;
374 }
375 return Result;
376
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000377 case ISD::SEXTLOAD:
378 // Make sure we generate both values.
379 if (Result != 1)
380 ExprMap[N.getValue(1)] = 1; // Generate the token
381 else
382 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
383
384 Select(Node->getOperand(0)); // chain
385 Tmp1 = SelectExpr(Node->getOperand(1));
386 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000387 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000388 case MVT::i64:
389 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
390 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000391 Node->dump();
392 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000393 case MVT::i32:
394 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
395 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000396// case MVT::i16:
397// BuildMI(BB, Alpha::LDW, 2, Result).addImm(0).addReg(Tmp1);
398// break;
399// case MVT::i8:
400// BuildMI(BB, Alpha::LDB, 2, Result).addImm(0).addReg(Tmp1);
401// break;
402 }
403 break;
404 }
405 return Result;
406
407 case ISD::ZEXTLOAD:
408 // Make sure we generate both values.
409 if (Result != 1)
410 ExprMap[N.getValue(1)] = 1; // Generate the token
411 else
412 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
413
414 Select(Node->getOperand(0)); // chain
415 Tmp1 = SelectExpr(Node->getOperand(1));
416 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000417 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000418 case MVT::i64:
419 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
420 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000421 Node->dump();
422 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000423 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000424 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000425 break;
426 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000427 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000428 break;
429 }
430 break;
431 }
432 return Result;
433
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000434
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000435 case ISD::GlobalAddress:
436 AlphaLowering.restoreGP(BB);
437 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
438 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
439 return Result;
440
441 case ISD::CALL:
442 {
443 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000444
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000445 // The chain for this call is now lowered.
446 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1));
447
448 //grab the arguments
449 std::vector<unsigned> argvregs;
450 assert(Node->getNumOperands() < 8 && "Only 6 args supported");
451 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000452 argvregs.push_back(SelectExpr(N.getOperand(i)));
453
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000454 for(int i = 0, e = argvregs.size(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000455 {
456 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
457 Alpha::R19, Alpha::R20, Alpha::R21};
458 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
459 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth7e57bd52005-01-27 01:22:48 +0000460 switch(N.getOperand(i+2).getValueType()) {
461 default:
462 Node->dump();
463 N.getOperand(i).Val->dump();
464 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
465 assert(0 && "Unknown value type for call");
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000466 case MVT::i1:
467 case MVT::i8:
468 case MVT::i16:
469 case MVT::i32:
470 case MVT::i64:
471 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
472 break;
473 case MVT::f32:
474 case MVT::f64:
475 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
476 break;
477 }
478
479 }
480 //build the right kind of call
481 if (GlobalAddressSDNode *GASD =
482 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
483 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000484 AlphaLowering.restoreGP(BB);
485 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
486 }
487 else if (ExternalSymbolSDNode *ESSDN =
488 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
489 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000490 AlphaLowering.restoreGP(BB);
491 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
492 }
493 else
494 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000495 Tmp1 = SelectExpr(N.getOperand(1));
496 BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1);
497 AlphaLowering.restoreGP(BB);
498 }
499
500 //push the result into a virtual register
501 // if (Result != 1)
502 // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
503
504 switch (Node->getValueType(0)) {
505 default: Node->dump(); assert(0 && "Unknown value type for call result!");
506 case MVT::Other: return 1;
507 case MVT::i1:
508 case MVT::i8:
509 case MVT::i16:
510 case MVT::i32:
511 case MVT::i64:
512 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
513 break;
514 case MVT::f32:
515 case MVT::f64:
516 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
517 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000518 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000519 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000520 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000521
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000522 case ISD::SIGN_EXTEND:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000523 case ISD::SIGN_EXTEND_INREG:
524 {
525 Tmp1 = SelectExpr(N.getOperand(0));
526 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000527 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000528 switch(MVN->getExtraValueType())
529 {
530 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000531 Node->dump();
532 assert(0 && "Sign Extend InReg not there yet");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000533 break;
534 case MVT::i32:
535 {
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000536 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000537 break;
538 }
539 case MVT::i16:
540 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
541 break;
542 case MVT::i8:
543 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
544 break;
545 }
546 return Result;
547 }
548 case ISD::ZERO_EXTEND_INREG:
549 {
550 Tmp1 = SelectExpr(N.getOperand(0));
551 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000552 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000553 switch(MVN->getExtraValueType())
554 {
555 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000556 Node->dump();
557 assert(0 && "Zero Extend InReg not there yet");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000558 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000559 case MVT::i32: Tmp2 = 0xf0; break;
560 case MVT::i16: Tmp2 = 0xfc; break;
561 case MVT::i8: Tmp2 = 0xfe; break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000562 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000563 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
564 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000565 }
566
567 case ISD::SETCC:
568 Tmp1 = SelectExpr(N.getOperand(0));
569 Tmp2 = SelectExpr(N.getOperand(1));
570 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
571 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
572 switch (SetCC->getCondition()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000573 default: Node->dump(); assert(0 && "Unknown integer comparison!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000574 case ISD::SETEQ:
575 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
576 break;
577 case ISD::SETGT:
578 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp2).addReg(Tmp1);
579 break;
580 case ISD::SETGE:
581 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp2).addReg(Tmp1);
582 break;
583 case ISD::SETLT:
584 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp1).addReg(Tmp2);
585 break;
586 case ISD::SETLE:
587 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp1).addReg(Tmp2);
588 break;
589 case ISD::SETNE:
590 {
591 unsigned Tmp3 = MakeReg(MVT::i64);
592 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
593 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp3).addReg(Alpha::R31);
594 break;
595 }
596 case ISD::SETULT:
597 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
598 break;
599 case ISD::SETUGT:
600 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp2).addReg(Tmp1);
601 break;
602 case ISD::SETULE:
603 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp1).addReg(Tmp2);
604 break;
605 case ISD::SETUGE:
606 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp2).addReg(Tmp1);
607 break;
608 }
609 }
610 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000611 {
612 Node->dump();
613 assert(0 && "only integer");
614 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000615 }
616 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000617 {
618 Node->dump();
619 assert(0 && "Not a setcc in setcc");
620 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000621 return Result;
622
623 case ISD::CopyFromReg:
624 {
625 if (Result == 1)
626 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
627
628 SDOperand Chain = N.getOperand(0);
629
630 Select(Chain);
631 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
632 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
633 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
634 return Result;
635 }
636
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000637 //Most of the plain arithmetic and logic share the same form, and the same
638 //constant immediate test
639 case ISD::AND:
640 case ISD::OR:
641 case ISD::XOR:
642 case ISD::SHL:
643 case ISD::SRL:
644 case ISD::MUL:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000645 switch (N.getValueType()) {
646 default: Node->dump(); assert (0 && "unhandled type");
647 case MVT::f64:
648 assert(N.getOpcode() == ISD::MUL && "only mul here please");
649 Tmp1 = SelectExpr(N.getOperand(0));
650 Tmp2 = SelectExpr(N.getOperand(1));
651 BuildMI(BB, Alpha::MULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
652 break;
653 case MVT::f32:
654 assert(N.getOpcode() == ISD::MUL && "only mul here please");
655 Tmp1 = SelectExpr(N.getOperand(0));
656 Tmp2 = SelectExpr(N.getOperand(1));
657 BuildMI(BB, Alpha::MULS, 2, Result).addReg(Tmp1).addReg(Tmp2);
658 break;
659 case MVT::i64:
660 if(N.getOperand(1).getOpcode() == ISD::Constant &&
661 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
662 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
663 {
664 switch(N.getOpcode()) {
665 case ISD::AND: Opc = Alpha::ANDi; break;
666 case ISD::OR: Opc = Alpha::BISi; break;
667 case ISD::XOR: Opc = Alpha::XORi; break;
668 case ISD::SHL: Opc = Alpha::SLi; break;
669 case ISD::SRL: Opc = Alpha::SRLi; break;
670 case ISD::SRA: Opc = Alpha::SRAi; break;
671 case ISD::MUL: Opc = Alpha::MULQi; break;
672 };
673 Tmp1 = SelectExpr(N.getOperand(0));
674 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
675 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
676 }
677 else
678 {
679 switch(N.getOpcode()) {
680 case ISD::AND: Opc = Alpha::AND; break;
681 case ISD::OR: Opc = Alpha::BIS; break;
682 case ISD::XOR: Opc = Alpha::XOR; break;
683 case ISD::SHL: Opc = Alpha::SL; break;
684 case ISD::SRL: Opc = Alpha::SRL; break;
685 case ISD::SRA: Opc = Alpha::SRA; break;
686 case ISD::MUL: Opc = Alpha::MULQ; break;
687 };
688 Tmp1 = SelectExpr(N.getOperand(0));
689 Tmp2 = SelectExpr(N.getOperand(1));
690 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
691 }
692 break;
693 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000694 return Result;
695
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000696 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000697 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000698 {
699 bool isAdd = N.getOpcode() == ISD::ADD;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000700
701 switch (N.getValueType()) {
702 default: Node->dump(); assert(0 && "Unhandled type");
703 case MVT::i64: {
704 //FIXME: first check for Scaled Adds and Subs!
705 if(N.getOperand(1).getOpcode() == ISD::Constant &&
706 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
707 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
708 { //Normal imm add/sub
709 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
710 Tmp1 = SelectExpr(N.getOperand(0));
711 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
712 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
713 }
714 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
715 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
716 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
717 { //LDA //FIXME: expand the above condition a bit
718 Tmp1 = SelectExpr(N.getOperand(0));
719 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
720 if (!isAdd)
721 Tmp2 = -Tmp2;
722 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
723 }
724 else
725 { //Normal add/sub
726 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
727 Tmp1 = SelectExpr(N.getOperand(0));
728 Tmp2 = SelectExpr(N.getOperand(1));
729 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
730 }
731 } break;
732 case MVT::f64:
733 case MVT::f32:
734 if (N.getValueType() == MVT::f64)
735 Opc = isAdd ? Alpha::ADDT : Alpha::SUBT;
736 else
737 Opc = isAdd ? Alpha::ADDS : Alpha::SUBS;
738 //
739 Tmp1 = SelectExpr(N.getOperand(0));
740 Tmp2 = SelectExpr(N.getOperand(1));
741 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
742 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000743 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000744 return Result;
745 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000746
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000747 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +0000748 case ISD::SREM:
749 case ISD::SDIV:
750 case ISD::UDIV:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000751 switch (N.getValueType()) {
752 default: Node->dump(); assert (0 && "unhandled type");
753 case MVT::f64:
754 assert(N.getOpcode() == ISD::SDIV && "only div here please");
755 Opc = Alpha::DIVT;
756 break;
757 case MVT::f32:
758 assert(N.getOpcode() == ISD::SDIV && "only div here please");
759 Opc = Alpha::DIVS;
760 break;
761 case MVT::i64:
762 //FIXME: alpha really doesn't support any of these operations,
763 // the ops are expanded into special library calls with
764 // special calling conventions
765 switch(N.getOpcode()) {
766 case ISD::UREM: Opc = Alpha::REMQU; break;
767 case ISD::SREM: Opc = Alpha::REMQ; break;
768 case ISD::UDIV: Opc = Alpha::DIVQU; break;
769 case ISD::SDIV: Opc = Alpha::DIVQ; break;
770 }
771 break;
772 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000773 Tmp1 = SelectExpr(N.getOperand(0));
774 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +0000775 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000776 return Result;
777
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000778// case ISD::SINT_TO_FP:
779// MVT::ValueType DestTy = N.getValueType();
780// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
781// Tmp2 = MakeReg(DestTy);
782// Opc = DestTy == MVT::f64 ? ITOFT : ITOFS;
783// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
784// Opc = DestTy == MVT::f64 ? CVTQT : CVTQS;
785// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
786// // case ISD::UINT_TO_FP:
787
788// case ISD::FP_TO_SINT:
789// assert (N.getValueType() == MVT::f64 && "Only can convert for doubles");
790// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
791// Tmp2 = MakeReg(SrcTy);
792// BuildMI(BB, CVTTQ, 1, Tmp2).addReg(Tmp1);
793// BuildMI(BB, FTOIT, 1, Result).addReg(Tmp2);
794// return result;
795
796// // case ISD::FP_TO_UINT:
797
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000798 case ISD::SELECT:
799 {
800 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
801 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
802 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
803 // Get the condition into the zero flag.
804 unsigned dummy = MakeReg(MVT::i64);
805 BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
806 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
807 return Result;
808 }
809
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000810 case ISD::Constant:
811 {
812 long val = cast<ConstantSDNode>(N)->getValue();
813 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
814 return Result;
815 }
816
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000817 case ISD::LOAD:
818 {
819 // Make sure we generate both values.
820 if (Result != 1)
821 ExprMap[N.getValue(1)] = 1; // Generate the token
822 else
823 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
824
825 SDOperand Chain = N.getOperand(0);
826 SDOperand Address = N.getOperand(1);
827
828 if (Address.getOpcode() == ISD::GlobalAddress)
829 {
830 Select(Chain);
831 AlphaLowering.restoreGP(BB);
832 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
833 }
834 else
835 {
836 Select(Chain);
837 Tmp2 = SelectExpr(Address);
838 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
839 }
840 return Result;
841 }
842 }
843
844 return 0;
845}
846
847void ISel::Select(SDOperand N) {
848 unsigned Tmp1, Tmp2, Opc;
849
850 // FIXME: Disable for our current expansion model!
851 if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
852 return; // Already selected.
853
854 SDNode *Node = N.Val;
855
856 switch (N.getOpcode()) {
857
858 default:
859 Node->dump(); std::cerr << "\n";
860 assert(0 && "Node not handled yet!");
861
862 case ISD::BRCOND: {
863 MachineBasicBlock *Dest =
864 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
865
866 Select(N.getOperand(0));
867 Tmp1 = SelectExpr(N.getOperand(1));
868 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
869 return;
870 }
871
872 case ISD::BR: {
873 MachineBasicBlock *Dest =
874 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
875
876 Select(N.getOperand(0));
877 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
878 return;
879 }
880
881 case ISD::ImplicitDef:
882 Select(N.getOperand(0));
883 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
884 return;
885
886 case ISD::EntryToken: return; // Noop
887
888 case ISD::TokenFactor:
889 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
890 Select(Node->getOperand(i));
891
892 //N.Val->dump(); std::cerr << "\n";
893 //assert(0 && "Node not handled yet!");
894
895 return;
896
897 case ISD::CopyToReg:
898 Select(N.getOperand(0));
899 Tmp1 = SelectExpr(N.getOperand(1));
900 Tmp2 = cast<RegSDNode>(N)->getReg();
901
902 if (Tmp1 != Tmp2) {
903 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
904 }
905 return;
906
907 case ISD::RET:
908 switch (N.getNumOperands()) {
909 default:
910 std::cerr << N.getNumOperands() << "\n";
911 for (unsigned i = 0; i < N.getNumOperands(); ++i)
912 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000913 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000914 assert(0 && "Unknown return instruction!");
915 case 2:
916 Select(N.getOperand(0));
917 Tmp1 = SelectExpr(N.getOperand(1));
918 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000919 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
920 case MVT::f64:
921 case MVT::f32:
922 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
923 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000924 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000925 case MVT::i64:
926 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
927 break;
928 }
929 break;
930 case 1:
931 Select(N.getOperand(0));
932 break;
933 }
934 //Tmp2 = AlphaLowering.getRetAddr();
935 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
936 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
937 return;
938
939 case ISD::STORE:
940 Select(N.getOperand(0));
941 Tmp1 = SelectExpr(N.getOperand(1)); //value
942 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
943 {
944 AlphaLowering.restoreGP(BB);
945 BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
946 }
947 else
948 {
949 Tmp2 = SelectExpr(N.getOperand(2)); //address
950 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
951 }
952 return;
953
954 case ISD::EXTLOAD:
955 case ISD::SEXTLOAD:
956 case ISD::ZEXTLOAD:
957 case ISD::LOAD:
958 case ISD::CopyFromReg:
959 case ISD::CALL:
960// case ISD::DYNAMIC_STACKALLOC:
961 SelectExpr(N);
962 return;
963
964
965 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
966 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000967 if (StoredTy == MVT::i64) {
968 Node->dump();
969 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
970 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000971
972 Select(N.getOperand(0));
973 Tmp1 = SelectExpr(N.getOperand(1));
974 Tmp2 = SelectExpr(N.getOperand(2));
975
976 switch (StoredTy) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000977 default: Node->dump(); assert(0 && "Unhandled Type"); break;
Andrew Lenharthd279b412005-01-25 19:58:40 +0000978 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000979 case MVT::i8: Opc = Alpha::STB; break;
980 case MVT::i16: Opc = Alpha::STW; break;
981 case MVT::i32: Opc = Alpha::STL; break;
982 }
983
984 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
985 return;
986 }
987
988 case ISD::ADJCALLSTACKDOWN:
989 case ISD::ADJCALLSTACKUP:
990 Select(N.getOperand(0));
991 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
992
993 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
994 Alpha::ADJUSTSTACKUP;
995 BuildMI(BB, Opc, 1).addImm(Tmp1);
996 return;
997 }
998 assert(0 && "Should not be reached!");
999}
1000
1001
1002/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1003/// into a machine code representation using pattern matching and a machine
1004/// description file.
1005///
1006FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1007 return new ISel(TM);
1008}