blob: b05dc65825546d7d156b78de01582dc509f55f2b [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.
Andrew Lenharth3d65d312005-01-27 03:49:45 +000041 //I am having problems with shr n ubyte 1
42 setShiftAmountType(MVT::i64); //are these needed?
43 setSetCCResultType(MVT::i64); //are these needed?
44
Andrew Lenharth304d0f32005-01-22 23:41:55 +000045 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
46 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000047 addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000048
Andrew Lenharth3d65d312005-01-27 03:49:45 +000049 setOperationAction(ISD::EXTLOAD , MVT::i1 , Expand); //Should this be Promote? Chris?
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000050
Andrew Lenharth3d65d312005-01-27 03:49:45 +000051 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); //Should this be Promote? Chris?
Andrew Lenharth304d0f32005-01-22 23:41:55 +000052 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000053
Andrew Lenharth3d65d312005-01-27 03:49:45 +000054 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); //Should this be Promote? Chris?
Andrew Lenharth304d0f32005-01-22 23:41:55 +000055 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
56 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
57
Andrew Lenharth3d65d312005-01-27 03:49:45 +000058 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 +000059
Andrew Lenharth3d65d312005-01-27 03:49:45 +000060 setOperationAction(ISD::SREM, MVT::f32, Expand);
61 setOperationAction(ISD::SREM, MVT::f64, Expand);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +000062
Andrew Lenharth3d65d312005-01-27 03:49:45 +000063 computeRegisterProperties();
Andrew Lenharth304d0f32005-01-22 23:41:55 +000064
Andrew Lenharth304d0f32005-01-22 23:41:55 +000065 // addLegalFPImmediate(+0.0); // FLD0
66 // addLegalFPImmediate(+1.0); // FLD1
67 // addLegalFPImmediate(-0.0); // FLD0/FCHS
68 // addLegalFPImmediate(-1.0); // FLD1/FCHS
69 }
70
71 /// LowerArguments - This hook must be implemented to indicate how we should
72 /// lower the arguments for the specified function, into the specified DAG.
73 virtual std::vector<SDOperand>
74 LowerArguments(Function &F, SelectionDAG &DAG);
75
76 /// LowerCallTo - This hook lowers an abstract call to a function into an
77 /// actual call.
78 virtual std::pair<SDOperand, SDOperand>
79 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
80 ArgListTy &Args, SelectionDAG &DAG);
81
82 virtual std::pair<SDOperand, SDOperand>
83 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
84
85 virtual std::pair<SDOperand,SDOperand>
86 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
87 const Type *ArgTy, SelectionDAG &DAG);
88
89 virtual std::pair<SDOperand, SDOperand>
90 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
91 SelectionDAG &DAG);
92
93 void restoreGP(MachineBasicBlock* BB)
94 {
95 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
96 }
97 };
98}
99
100//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
101
102//For now, just use variable size stack frame format
103
104//In a standard call, the first six items are passed in registers $16
105//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
106//of argument-to-register correspondence.) The remaining items are
107//collected in a memory argument list that is a naturally aligned
108//array of quadwords. In a standard call, this list, if present, must
109//be passed at 0(SP).
110//7 ... n 0(SP) ... (n-7)*8(SP)
111
112std::vector<SDOperand>
113AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
114{
115 std::vector<SDOperand> ArgValues;
116
117 // //#define FP $15
118 // //#define RA $26
119 // //#define PV $27
120 // //#define GP $29
121 // //#define SP $30
122
123 // assert(0 && "TODO");
124 MachineFunction &MF = DAG.getMachineFunction();
125 MachineFrameInfo *MFI = MF.getFrameInfo();
126
127 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
128 MachineBasicBlock& BB = MF.front();
129
130 //Handle the return address
131 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
132
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000133 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
134 Alpha::R19, Alpha::R20, Alpha::R21};
135 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
136 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000137 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000138 std::vector<unsigned> argPreg;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000139 int count = 0;
140 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
141 {
142 ++count;
143 assert(count <= 6 && "More than 6 args not supported");
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000144 switch (getValueType(I->getType())) {
145 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
146 case MVT::f64:
147 case MVT::f32:
148 BuildMI(&BB, Alpha::IDEF, 0, args_float[count - 1]);
149 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
150 argPreg.push_back(args_float[count - 1]);
151 break;
152 case MVT::i1:
153 case MVT::i8:
154 case MVT::i16:
155 case MVT::i32:
156 case MVT::i64:
157 BuildMI(&BB, Alpha::IDEF, 0, args_int[count - 1]);
Andrew Lenharthc0d502e2005-01-27 00:52:26 +0000158 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000159 argPreg.push_back(args_int[count - 1]);
160 break;
161 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000162 }
163
164 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
165 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
166 count = 0;
167 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
168 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000169 SDOperand newroot;
170 unsigned Opc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000171 switch (getValueType(I->getType()))
172 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000173 default: assert(0 && "Unhandled type");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000174 case MVT::i64:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000175 case MVT::i32:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000176 case MVT::i16:
177 case MVT::i8:
178 case MVT::i1:
179 Opc = Alpha::BIS;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000180 break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000181 case MVT::f32:
182 case MVT::f64:
183 Opc = Alpha::CPYS;
184 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000185 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000186 BuildMI(&BB, Opc, 2, argVreg[count]).addReg(argPreg[count]).addReg(argPreg[count]);
187 newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000188 DAG.setRoot(newroot.getValue(1));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000189 ArgValues.push_back(newroot);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000190 ++count;
191 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000192
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000193 return ArgValues;
194}
195
196std::pair<SDOperand, SDOperand>
197AlphaTargetLowering::LowerCallTo(SDOperand Chain,
198 const Type *RetTy, SDOperand Callee,
199 ArgListTy &Args, SelectionDAG &DAG) {
200 int NumBytes = 0;
201 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:
212 // 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 Lenharth3e98fde2005-01-26 21:54:09 +0000215 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND_INREG, MVT::i64, Args[i].first);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000216 else
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000217 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND_INREG, MVT::i64, Args[i].first);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000218 break;
219 case MVT::i64:
220 break;
Andrew Lenharth7e57bd52005-01-27 01:22:48 +0000221 case MVT::f64:
222 case MVT::f32:
223 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000224 }
225 args_to_use.push_back(Args[i].first);
226 }
227
228 std::vector<MVT::ValueType> RetVals;
229 MVT::ValueType RetTyVT = getValueType(RetTy);
230 if (RetTyVT != MVT::isVoid)
231 RetVals.push_back(RetTyVT);
232 RetVals.push_back(MVT::Other);
233
234 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
235 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
236 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
237 DAG.getConstant(NumBytes, getPointerTy()));
238 return std::make_pair(TheCall, Chain);
239}
240
241std::pair<SDOperand, SDOperand>
242AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
243 //vastart just returns the address of the VarArgsFrameIndex slot.
244 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
245}
246
247std::pair<SDOperand,SDOperand> AlphaTargetLowering::
248LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
249 const Type *ArgTy, SelectionDAG &DAG) {
250 abort();
251}
252
253
254std::pair<SDOperand, SDOperand> AlphaTargetLowering::
255LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
256 SelectionDAG &DAG) {
257 abort();
258}
259
260
261
262
263
264namespace {
265
266 //===--------------------------------------------------------------------===//
267 /// ISel - Alpha specific code to select Alpha machine instructions for
268 /// SelectionDAG operations.
269 ///
270 class ISel : public SelectionDAGISel {
271
272 /// AlphaLowering - This object fully describes how to lower LLVM code to an
273 /// Alpha-specific SelectionDAG.
274 AlphaTargetLowering AlphaLowering;
275
276
277 /// ExprMap - As shared expressions are codegen'd, we keep track of which
278 /// vreg the value is produced in, so we only emit one copy of each compiled
279 /// tree.
280 std::map<SDOperand, unsigned> ExprMap;
281 std::set<SDOperand> LoweredTokens;
282
283 public:
284 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
285 }
286
287 /// InstructionSelectBasicBlock - This callback is invoked by
288 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
289 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
290 // Codegen the basic block.
291 Select(DAG.getRoot());
292
293 // Clear state used for selection.
294 ExprMap.clear();
295 LoweredTokens.clear();
296 }
297
298 unsigned SelectExpr(SDOperand N);
299 void Select(SDOperand N);
300 };
301}
302
303unsigned ISel::SelectExpr(SDOperand N) {
304 unsigned Result;
305 unsigned Tmp1, Tmp2, Tmp3;
306 unsigned Opc = 0;
307
308 SDNode *Node = N.Val;
309
310 unsigned &Reg = ExprMap[N];
311 if (Reg) return Reg;
312
313 if (N.getOpcode() != ISD::CALL)
314 Reg = Result = (N.getValueType() != MVT::Other) ?
315 MakeReg(N.getValueType()) : 1;
316 else {
317 // If this is a call instruction, make sure to prepare ALL of the result
318 // values as well as the chain.
319 if (Node->getNumValues() == 1)
320 Reg = Result = 1; // Void call, just a chain.
321 else {
322 Result = MakeReg(Node->getValueType(0));
323 ExprMap[N.getValue(0)] = Result;
324 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
325 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
326 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
327 }
328 }
329
330 switch (N.getOpcode()) {
331 default:
332 Node->dump();
333 assert(0 && "Node not handled!\n");
334
335 case ISD::FrameIndex:
336 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
337 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
338 return Result;
339
340 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000341 // Make sure we generate both values.
342 if (Result != 1)
343 ExprMap[N.getValue(1)] = 1; // Generate the token
344 else
345 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
346
347 Select(Node->getOperand(0)); // chain
348 Tmp1 = SelectExpr(Node->getOperand(1));
349
350 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000351 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000352 case MVT::i64:
353 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
354 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000355 Node->dump();
356 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000357 case MVT::i64:
358 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
359 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000360 case MVT::i32:
361 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
362 break;
363 case MVT::i16:
364 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
365 break;
366 case MVT::i8:
367 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 }
394 break;
395 }
396 return Result;
397
398 case ISD::ZEXTLOAD:
399 // Make sure we generate both values.
400 if (Result != 1)
401 ExprMap[N.getValue(1)] = 1; // Generate the token
402 else
403 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
404
405 Select(Node->getOperand(0)); // chain
406 Tmp1 = SelectExpr(Node->getOperand(1));
407 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000408 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000409 case MVT::i64:
410 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
411 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000412 Node->dump();
413 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000414 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000415 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000416 break;
417 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000418 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000419 break;
420 }
421 break;
422 }
423 return Result;
424
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000425
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000426 case ISD::GlobalAddress:
427 AlphaLowering.restoreGP(BB);
428 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
429 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
430 return Result;
431
432 case ISD::CALL:
433 {
434 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000435
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000436 // The chain for this call is now lowered.
437 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1));
438
439 //grab the arguments
440 std::vector<unsigned> argvregs;
441 assert(Node->getNumOperands() < 8 && "Only 6 args supported");
442 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000443 argvregs.push_back(SelectExpr(N.getOperand(i)));
444
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000445 for(int i = 0, e = argvregs.size(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000446 {
447 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
448 Alpha::R19, Alpha::R20, Alpha::R21};
449 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
450 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth7e57bd52005-01-27 01:22:48 +0000451 switch(N.getOperand(i+2).getValueType()) {
452 default:
453 Node->dump();
454 N.getOperand(i).Val->dump();
455 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
456 assert(0 && "Unknown value type for call");
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000457 case MVT::i1:
458 case MVT::i8:
459 case MVT::i16:
460 case MVT::i32:
461 case MVT::i64:
462 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
463 break;
464 case MVT::f32:
465 case MVT::f64:
466 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
467 break;
468 }
469
470 }
471 //build the right kind of call
472 if (GlobalAddressSDNode *GASD =
473 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
474 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000475 AlphaLowering.restoreGP(BB);
476 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
477 }
478 else if (ExternalSymbolSDNode *ESSDN =
479 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
480 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000481 AlphaLowering.restoreGP(BB);
482 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
483 }
484 else
485 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000486 Tmp1 = SelectExpr(N.getOperand(1));
487 BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1);
488 AlphaLowering.restoreGP(BB);
489 }
490
491 //push the result into a virtual register
492 // if (Result != 1)
493 // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
494
495 switch (Node->getValueType(0)) {
496 default: Node->dump(); assert(0 && "Unknown value type for call result!");
497 case MVT::Other: return 1;
498 case MVT::i1:
499 case MVT::i8:
500 case MVT::i16:
501 case MVT::i32:
502 case MVT::i64:
503 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
504 break;
505 case MVT::f32:
506 case MVT::f64:
507 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
508 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000509 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000510 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000511 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000512
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000513 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000514 abort();
515
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000516 case ISD::SIGN_EXTEND_INREG:
517 {
518 Tmp1 = SelectExpr(N.getOperand(0));
519 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000520 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000521 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000522 {
523 default:
524 Node->dump();
525 assert(0 && "Sign Extend InReg not there yet");
526 break;
527 case MVT::i32:
528 {
529 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
530 break;
531 }
532 case MVT::i16:
533 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
534 break;
535 case MVT::i8:
536 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
537 break;
538 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000539 return Result;
540 }
541 case ISD::ZERO_EXTEND_INREG:
542 {
543 Tmp1 = SelectExpr(N.getOperand(0));
544 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000545 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000546 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000547 {
548 default:
549 Node->dump();
550 assert(0 && "Zero Extend InReg not there yet");
551 break;
552 case MVT::i32: Tmp2 = 0xf0; break;
553 case MVT::i16: Tmp2 = 0xfc; break;
554 case MVT::i8: Tmp2 = 0xfe; break;
555 case MVT::i1: //handle this one special
556 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
557 return Result;
558 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000559 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000560 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000561 }
562
563 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000564 {
565 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
566 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
567 bool isConst1 = false;
568 bool isConst2 = false;
569 int dir;
570
571 //Tmp1 = SelectExpr(N.getOperand(0));
572 if(N.getOperand(0).getOpcode() == ISD::Constant &&
573 cast<ConstantSDNode>(N.getOperand(0))->getValue() >= 0 &&
574 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
575 isConst1 = true;
576 if(N.getOperand(1).getOpcode() == ISD::Constant &&
577 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
578 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
579 isConst2 = true;
580
581 switch (SetCC->getCondition()) {
582 default: Node->dump(); assert(0 && "Unknown integer comparison!");
583 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
584 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
585 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
586 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
587 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
588 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
589 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
590 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
591 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
592 case ISD::SETNE:
593 std::cerr << "Alpha does not have a setne.\n";
594 abort();
595 }
596 if (dir == 1) {
597 Tmp1 = SelectExpr(N.getOperand(0));
598 if (isConst2) {
599 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
600 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
601 } else {
602 Tmp2 = SelectExpr(N.getOperand(1));
603 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
604 }
605 } else if (dir == 2) {
606 Tmp1 = SelectExpr(N.getOperand(1));
607 if (isConst2) {
608 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
609 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
610 } else {
611 Tmp2 = SelectExpr(N.getOperand(0));
612 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
613 }
614 } else { //dir == 0
615 if (isConst1) {
616 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
617 Tmp2 = SelectExpr(N.getOperand(1));
618 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
619 } else if (isConst2) {
620 Tmp1 = SelectExpr(N.getOperand(0));
621 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
622 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
623 } else {
624 Tmp1 = SelectExpr(N.getOperand(0));
625 Tmp2 = SelectExpr(N.getOperand(1));
626 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
627 }
628 }
629 }
630 else
631 {
632 Node->dump();
633 assert(0 && "only integer");
634 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000635 }
636 else
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000637 {
638 Node->dump();
639 assert(0 && "Not a setcc in setcc");
640 }
641 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000642 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000643
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000644 case ISD::CopyFromReg:
645 {
646 if (Result == 1)
647 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
648
649 SDOperand Chain = N.getOperand(0);
650
651 Select(Chain);
652 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
653 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
654 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
655 return Result;
656 }
657
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000658 //Most of the plain arithmetic and logic share the same form, and the same
659 //constant immediate test
660 case ISD::AND:
661 case ISD::OR:
662 case ISD::XOR:
663 case ISD::SHL:
664 case ISD::SRL:
665 case ISD::MUL:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000666 switch (N.getValueType()) {
667 default: Node->dump(); assert (0 && "unhandled type");
668 case MVT::f64:
669 assert(N.getOpcode() == ISD::MUL && "only mul here please");
670 Tmp1 = SelectExpr(N.getOperand(0));
671 Tmp2 = SelectExpr(N.getOperand(1));
672 BuildMI(BB, Alpha::MULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
673 break;
674 case MVT::f32:
675 assert(N.getOpcode() == ISD::MUL && "only mul here please");
676 Tmp1 = SelectExpr(N.getOperand(0));
677 Tmp2 = SelectExpr(N.getOperand(1));
678 BuildMI(BB, Alpha::MULS, 2, Result).addReg(Tmp1).addReg(Tmp2);
679 break;
680 case MVT::i64:
681 if(N.getOperand(1).getOpcode() == ISD::Constant &&
682 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
683 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
684 {
685 switch(N.getOpcode()) {
686 case ISD::AND: Opc = Alpha::ANDi; break;
687 case ISD::OR: Opc = Alpha::BISi; break;
688 case ISD::XOR: Opc = Alpha::XORi; break;
689 case ISD::SHL: Opc = Alpha::SLi; break;
690 case ISD::SRL: Opc = Alpha::SRLi; break;
691 case ISD::SRA: Opc = Alpha::SRAi; break;
692 case ISD::MUL: Opc = Alpha::MULQi; break;
693 };
694 Tmp1 = SelectExpr(N.getOperand(0));
695 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
696 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
697 }
698 else
699 {
700 switch(N.getOpcode()) {
701 case ISD::AND: Opc = Alpha::AND; break;
702 case ISD::OR: Opc = Alpha::BIS; break;
703 case ISD::XOR: Opc = Alpha::XOR; break;
704 case ISD::SHL: Opc = Alpha::SL; break;
705 case ISD::SRL: Opc = Alpha::SRL; break;
706 case ISD::SRA: Opc = Alpha::SRA; break;
707 case ISD::MUL: Opc = Alpha::MULQ; break;
708 };
709 Tmp1 = SelectExpr(N.getOperand(0));
710 Tmp2 = SelectExpr(N.getOperand(1));
711 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
712 }
713 break;
714 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000715 return Result;
716
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000717 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000718 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000719 {
720 bool isAdd = N.getOpcode() == ISD::ADD;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000721
722 switch (N.getValueType()) {
723 default: Node->dump(); assert(0 && "Unhandled type");
724 case MVT::i64: {
725 //FIXME: first check for Scaled Adds and Subs!
726 if(N.getOperand(1).getOpcode() == ISD::Constant &&
727 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
728 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
729 { //Normal imm add/sub
730 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
731 Tmp1 = SelectExpr(N.getOperand(0));
732 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
733 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
734 }
735 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
736 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
737 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
738 { //LDA //FIXME: expand the above condition a bit
739 Tmp1 = SelectExpr(N.getOperand(0));
740 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
741 if (!isAdd)
742 Tmp2 = -Tmp2;
743 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
744 }
745 else
746 { //Normal add/sub
747 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
748 Tmp1 = SelectExpr(N.getOperand(0));
749 Tmp2 = SelectExpr(N.getOperand(1));
750 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
751 }
752 } break;
753 case MVT::f64:
754 case MVT::f32:
755 if (N.getValueType() == MVT::f64)
756 Opc = isAdd ? Alpha::ADDT : Alpha::SUBT;
757 else
758 Opc = isAdd ? Alpha::ADDS : Alpha::SUBS;
759 //
760 Tmp1 = SelectExpr(N.getOperand(0));
761 Tmp2 = SelectExpr(N.getOperand(1));
762 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
763 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000764 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000765 return Result;
766 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000767
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000768 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +0000769 case ISD::SREM:
770 case ISD::SDIV:
771 case ISD::UDIV:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000772 switch (N.getValueType()) {
773 default: Node->dump(); assert (0 && "unhandled type");
774 case MVT::f64:
775 assert(N.getOpcode() == ISD::SDIV && "only div here please");
776 Opc = Alpha::DIVT;
777 break;
778 case MVT::f32:
779 assert(N.getOpcode() == ISD::SDIV && "only div here please");
780 Opc = Alpha::DIVS;
781 break;
782 case MVT::i64:
783 //FIXME: alpha really doesn't support any of these operations,
784 // the ops are expanded into special library calls with
785 // special calling conventions
786 switch(N.getOpcode()) {
787 case ISD::UREM: Opc = Alpha::REMQU; break;
788 case ISD::SREM: Opc = Alpha::REMQ; break;
789 case ISD::UDIV: Opc = Alpha::DIVQU; break;
790 case ISD::SDIV: Opc = Alpha::DIVQ; break;
791 }
792 break;
793 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000794 Tmp1 = SelectExpr(N.getOperand(0));
795 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +0000796 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000797 return Result;
798
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000799// case ISD::SINT_TO_FP:
800// MVT::ValueType DestTy = N.getValueType();
801// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
802// Tmp2 = MakeReg(DestTy);
803// Opc = DestTy == MVT::f64 ? ITOFT : ITOFS;
804// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
805// Opc = DestTy == MVT::f64 ? CVTQT : CVTQS;
806// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
807// // case ISD::UINT_TO_FP:
808
809// case ISD::FP_TO_SINT:
810// assert (N.getValueType() == MVT::f64 && "Only can convert for doubles");
811// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
812// Tmp2 = MakeReg(SrcTy);
813// BuildMI(BB, CVTTQ, 1, Tmp2).addReg(Tmp1);
814// BuildMI(BB, FTOIT, 1, Result).addReg(Tmp2);
815// return result;
816
817// // case ISD::FP_TO_UINT:
818
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000819 case ISD::SELECT:
820 {
821 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
822 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
823 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
824 // Get the condition into the zero flag.
825 unsigned dummy = MakeReg(MVT::i64);
826 BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
827 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
828 return Result;
829 }
830
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000831 case ISD::Constant:
832 {
833 long val = cast<ConstantSDNode>(N)->getValue();
834 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
835 return Result;
836 }
837
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000838 case ISD::LOAD:
839 {
840 // Make sure we generate both values.
841 if (Result != 1)
842 ExprMap[N.getValue(1)] = 1; // Generate the token
843 else
844 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
845
846 SDOperand Chain = N.getOperand(0);
847 SDOperand Address = N.getOperand(1);
848
849 if (Address.getOpcode() == ISD::GlobalAddress)
850 {
851 Select(Chain);
852 AlphaLowering.restoreGP(BB);
853 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
854 }
855 else
856 {
857 Select(Chain);
858 Tmp2 = SelectExpr(Address);
859 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
860 }
861 return Result;
862 }
863 }
864
865 return 0;
866}
867
868void ISel::Select(SDOperand N) {
869 unsigned Tmp1, Tmp2, Opc;
870
871 // FIXME: Disable for our current expansion model!
872 if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
873 return; // Already selected.
874
875 SDNode *Node = N.Val;
876
877 switch (N.getOpcode()) {
878
879 default:
880 Node->dump(); std::cerr << "\n";
881 assert(0 && "Node not handled yet!");
882
883 case ISD::BRCOND: {
884 MachineBasicBlock *Dest =
885 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
886
887 Select(N.getOperand(0));
888 Tmp1 = SelectExpr(N.getOperand(1));
889 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
890 return;
891 }
892
893 case ISD::BR: {
894 MachineBasicBlock *Dest =
895 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
896
897 Select(N.getOperand(0));
898 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
899 return;
900 }
901
902 case ISD::ImplicitDef:
903 Select(N.getOperand(0));
904 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
905 return;
906
907 case ISD::EntryToken: return; // Noop
908
909 case ISD::TokenFactor:
910 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
911 Select(Node->getOperand(i));
912
913 //N.Val->dump(); std::cerr << "\n";
914 //assert(0 && "Node not handled yet!");
915
916 return;
917
918 case ISD::CopyToReg:
919 Select(N.getOperand(0));
920 Tmp1 = SelectExpr(N.getOperand(1));
921 Tmp2 = cast<RegSDNode>(N)->getReg();
922
923 if (Tmp1 != Tmp2) {
924 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
925 }
926 return;
927
928 case ISD::RET:
929 switch (N.getNumOperands()) {
930 default:
931 std::cerr << N.getNumOperands() << "\n";
932 for (unsigned i = 0; i < N.getNumOperands(); ++i)
933 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000934 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000935 assert(0 && "Unknown return instruction!");
936 case 2:
937 Select(N.getOperand(0));
938 Tmp1 = SelectExpr(N.getOperand(1));
939 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000940 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
941 case MVT::f64:
942 case MVT::f32:
943 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
944 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000945 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000946 case MVT::i64:
947 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
948 break;
949 }
950 break;
951 case 1:
952 Select(N.getOperand(0));
953 break;
954 }
955 //Tmp2 = AlphaLowering.getRetAddr();
956 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
957 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
958 return;
959
960 case ISD::STORE:
961 Select(N.getOperand(0));
962 Tmp1 = SelectExpr(N.getOperand(1)); //value
963 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
964 {
965 AlphaLowering.restoreGP(BB);
966 BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
967 }
968 else
969 {
970 Tmp2 = SelectExpr(N.getOperand(2)); //address
971 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
972 }
973 return;
974
975 case ISD::EXTLOAD:
976 case ISD::SEXTLOAD:
977 case ISD::ZEXTLOAD:
978 case ISD::LOAD:
979 case ISD::CopyFromReg:
980 case ISD::CALL:
981// case ISD::DYNAMIC_STACKALLOC:
982 SelectExpr(N);
983 return;
984
985
986 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
987 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000988 if (StoredTy == MVT::i64) {
989 Node->dump();
990 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
991 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000992
993 Select(N.getOperand(0));
994 Tmp1 = SelectExpr(N.getOperand(1));
995 Tmp2 = SelectExpr(N.getOperand(2));
996
997 switch (StoredTy) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000998 default: Node->dump(); assert(0 && "Unhandled Type"); break;
Andrew Lenharthd279b412005-01-25 19:58:40 +0000999 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001000 case MVT::i8: Opc = Alpha::STB; break;
1001 case MVT::i16: Opc = Alpha::STW; break;
1002 case MVT::i32: Opc = Alpha::STL; break;
1003 }
1004
1005 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1006 return;
1007 }
1008
1009 case ISD::ADJCALLSTACKDOWN:
1010 case ISD::ADJCALLSTACKUP:
1011 Select(N.getOperand(0));
1012 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1013
1014 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1015 Alpha::ADJUSTSTACKUP;
1016 BuildMI(BB, Opc, 1).addImm(Tmp1);
1017 return;
1018 }
1019 assert(0 && "Should not be reached!");
1020}
1021
1022
1023/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1024/// into a machine code representation using pattern matching and a machine
1025/// description file.
1026///
1027FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1028 return new ISel(TM);
1029}