blob: b9abf4661b473434de1d3244a3af4e0112bd2649 [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 Lenharthd2bb9602005-01-27 07:50:35 +000049 setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote);
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 Lenharthd2bb9602005-01-27 07:50:35 +000065 addLegalFPImmediate(+0.0); //F31
Andrew Lenharth304d0f32005-01-22 23:41:55 +000066 }
67
68 /// LowerArguments - This hook must be implemented to indicate how we should
69 /// lower the arguments for the specified function, into the specified DAG.
70 virtual std::vector<SDOperand>
71 LowerArguments(Function &F, SelectionDAG &DAG);
72
73 /// LowerCallTo - This hook lowers an abstract call to a function into an
74 /// actual call.
75 virtual std::pair<SDOperand, SDOperand>
76 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
77 ArgListTy &Args, SelectionDAG &DAG);
78
79 virtual std::pair<SDOperand, SDOperand>
80 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
81
82 virtual std::pair<SDOperand,SDOperand>
83 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
84 const Type *ArgTy, SelectionDAG &DAG);
85
86 virtual std::pair<SDOperand, SDOperand>
87 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
88 SelectionDAG &DAG);
89
90 void restoreGP(MachineBasicBlock* BB)
91 {
92 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
93 }
94 };
95}
96
97//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
98
99//For now, just use variable size stack frame format
100
101//In a standard call, the first six items are passed in registers $16
102//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
103//of argument-to-register correspondence.) The remaining items are
104//collected in a memory argument list that is a naturally aligned
105//array of quadwords. In a standard call, this list, if present, must
106//be passed at 0(SP).
107//7 ... n 0(SP) ... (n-7)*8(SP)
108
109std::vector<SDOperand>
110AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
111{
112 std::vector<SDOperand> ArgValues;
113
114 // //#define FP $15
115 // //#define RA $26
116 // //#define PV $27
117 // //#define GP $29
118 // //#define SP $30
119
120 // assert(0 && "TODO");
121 MachineFunction &MF = DAG.getMachineFunction();
122 MachineFrameInfo *MFI = MF.getFrameInfo();
123
124 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
125 MachineBasicBlock& BB = MF.front();
126
127 //Handle the return address
128 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
129
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000130 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
131 Alpha::R19, Alpha::R20, Alpha::R21};
132 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
133 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000134 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000135 std::vector<unsigned> argPreg;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000136 int count = 0;
137 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
138 {
139 ++count;
140 assert(count <= 6 && "More than 6 args not supported");
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000141 switch (getValueType(I->getType())) {
142 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
143 case MVT::f64:
144 case MVT::f32:
145 BuildMI(&BB, Alpha::IDEF, 0, args_float[count - 1]);
146 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
147 argPreg.push_back(args_float[count - 1]);
148 break;
149 case MVT::i1:
150 case MVT::i8:
151 case MVT::i16:
152 case MVT::i32:
153 case MVT::i64:
154 BuildMI(&BB, Alpha::IDEF, 0, args_int[count - 1]);
Andrew Lenharthc0d502e2005-01-27 00:52:26 +0000155 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000156 argPreg.push_back(args_int[count - 1]);
157 break;
158 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000159 }
160
161 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
162 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
163 count = 0;
164 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
165 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000166 SDOperand newroot;
167 unsigned Opc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000168 switch (getValueType(I->getType()))
169 {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000170 default: assert(0 && "Unhandled type");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000171 case MVT::i64:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000172 case MVT::i32:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000173 case MVT::i16:
174 case MVT::i8:
175 case MVT::i1:
176 Opc = Alpha::BIS;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000177 break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000178 case MVT::f32:
179 case MVT::f64:
180 Opc = Alpha::CPYS;
181 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000182 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000183 BuildMI(&BB, Opc, 2, argVreg[count]).addReg(argPreg[count]).addReg(argPreg[count]);
184 newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000185 DAG.setRoot(newroot.getValue(1));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000186 ArgValues.push_back(newroot);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000187 ++count;
188 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000189
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000190 return ArgValues;
191}
192
193std::pair<SDOperand, SDOperand>
194AlphaTargetLowering::LowerCallTo(SDOperand Chain,
195 const Type *RetTy, SDOperand Callee,
196 ArgListTy &Args, SelectionDAG &DAG) {
197 int NumBytes = 0;
198 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
199 DAG.getConstant(NumBytes, getPointerTy()));
200 std::vector<SDOperand> args_to_use;
201 for (unsigned i = 0, e = Args.size(); i != e; ++i)
202 {
203 switch (getValueType(Args[i].second)) {
204 default: assert(0 && "Unexpected ValueType for argument!");
205 case MVT::i1:
206 case MVT::i8:
207 case MVT::i16:
208 case MVT::i32:
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000209 // Promote the integer to 64 bits. If the input type is signed use a
210 // sign extend, otherwise use a zero extend.
211 if (Args[i].second->isSigned())
212 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND_INREG, MVT::i64, Args[i].first);
213 else
214 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND_INREG, MVT::i64, Args[i].first);
215 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000216 case MVT::i64:
217 break;
Andrew Lenharth7e57bd52005-01-27 01:22:48 +0000218 case MVT::f64:
219 case MVT::f32:
220 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000221 }
222 args_to_use.push_back(Args[i].first);
223 }
224
225 std::vector<MVT::ValueType> RetVals;
226 MVT::ValueType RetTyVT = getValueType(RetTy);
227 if (RetTyVT != MVT::isVoid)
228 RetVals.push_back(RetTyVT);
229 RetVals.push_back(MVT::Other);
230
231 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
232 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
233 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
234 DAG.getConstant(NumBytes, getPointerTy()));
235 return std::make_pair(TheCall, Chain);
236}
237
238std::pair<SDOperand, SDOperand>
239AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
240 //vastart just returns the address of the VarArgsFrameIndex slot.
241 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
242}
243
244std::pair<SDOperand,SDOperand> AlphaTargetLowering::
245LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
246 const Type *ArgTy, SelectionDAG &DAG) {
247 abort();
248}
249
250
251std::pair<SDOperand, SDOperand> AlphaTargetLowering::
252LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
253 SelectionDAG &DAG) {
254 abort();
255}
256
257
258
259
260
261namespace {
262
263 //===--------------------------------------------------------------------===//
264 /// ISel - Alpha specific code to select Alpha machine instructions for
265 /// SelectionDAG operations.
266 ///
267 class ISel : public SelectionDAGISel {
268
269 /// AlphaLowering - This object fully describes how to lower LLVM code to an
270 /// Alpha-specific SelectionDAG.
271 AlphaTargetLowering AlphaLowering;
272
273
274 /// ExprMap - As shared expressions are codegen'd, we keep track of which
275 /// vreg the value is produced in, so we only emit one copy of each compiled
276 /// tree.
277 std::map<SDOperand, unsigned> ExprMap;
278 std::set<SDOperand> LoweredTokens;
279
280 public:
281 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
282 }
283
284 /// InstructionSelectBasicBlock - This callback is invoked by
285 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
286 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
287 // Codegen the basic block.
288 Select(DAG.getRoot());
289
290 // Clear state used for selection.
291 ExprMap.clear();
292 LoweredTokens.clear();
293 }
294
295 unsigned SelectExpr(SDOperand N);
296 void Select(SDOperand N);
297 };
298}
299
300unsigned ISel::SelectExpr(SDOperand N) {
301 unsigned Result;
302 unsigned Tmp1, Tmp2, Tmp3;
303 unsigned Opc = 0;
304
305 SDNode *Node = N.Val;
306
307 unsigned &Reg = ExprMap[N];
308 if (Reg) return Reg;
309
310 if (N.getOpcode() != ISD::CALL)
311 Reg = Result = (N.getValueType() != MVT::Other) ?
312 MakeReg(N.getValueType()) : 1;
313 else {
314 // If this is a call instruction, make sure to prepare ALL of the result
315 // values as well as the chain.
316 if (Node->getNumValues() == 1)
317 Reg = Result = 1; // Void call, just a chain.
318 else {
319 Result = MakeReg(Node->getValueType(0));
320 ExprMap[N.getValue(0)] = Result;
321 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
322 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
323 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
324 }
325 }
326
327 switch (N.getOpcode()) {
328 default:
329 Node->dump();
330 assert(0 && "Node not handled!\n");
331
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000332 case ISD::ConstantFP:
333 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
334 if (CN->isExactlyValue(+0.0) ||
335 CN->isExactlyValue(-0.0)) {
336 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(R31).addReg(R31);
337 } else {
338 abort();
339 }
340 }
341 return Result;
342
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000343 case ISD::FrameIndex:
344 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
345 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
346 return Result;
347
348 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000349 // Make sure we generate both values.
350 if (Result != 1)
351 ExprMap[N.getValue(1)] = 1; // Generate the token
352 else
353 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
354
355 Select(Node->getOperand(0)); // chain
356 Tmp1 = SelectExpr(Node->getOperand(1));
357
358 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000359 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000360 case MVT::i64:
361 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
362 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000363 Node->dump();
364 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000365 case MVT::i64:
366 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
367 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000368 case MVT::i32:
369 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
370 break;
371 case MVT::i16:
372 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
373 break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000374 case MVT::i1: //Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000375 case MVT::i8:
376 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
377 break;
378 }
379 break;
380 }
381 return Result;
382
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000383 case ISD::SEXTLOAD:
384 // Make sure we generate both values.
385 if (Result != 1)
386 ExprMap[N.getValue(1)] = 1; // Generate the token
387 else
388 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
389
390 Select(Node->getOperand(0)); // chain
391 Tmp1 = SelectExpr(Node->getOperand(1));
392 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000393 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000394 case MVT::i64:
395 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
396 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000397 Node->dump();
398 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000399 case MVT::i32:
400 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
401 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000402 }
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 Lenharth3d65d312005-01-27 03:49:45 +0000523 abort();
524
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000525 case ISD::SIGN_EXTEND_INREG:
526 {
527 Tmp1 = SelectExpr(N.getOperand(0));
528 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000529 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000530 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000531 {
532 default:
533 Node->dump();
534 assert(0 && "Sign Extend InReg not there yet");
535 break;
536 case MVT::i32:
537 {
538 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
539 break;
540 }
541 case MVT::i16:
542 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
543 break;
544 case MVT::i8:
545 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
546 break;
547 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000548 return Result;
549 }
550 case ISD::ZERO_EXTEND_INREG:
551 {
552 Tmp1 = SelectExpr(N.getOperand(0));
553 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000554 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000555 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000556 {
557 default:
558 Node->dump();
559 assert(0 && "Zero Extend InReg not there yet");
560 break;
561 case MVT::i32: Tmp2 = 0xf0; break;
562 case MVT::i16: Tmp2 = 0xfc; break;
563 case MVT::i8: Tmp2 = 0xfe; break;
564 case MVT::i1: //handle this one special
565 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
566 return Result;
567 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000568 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000569 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000570 }
571
572 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000573 {
574 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
575 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
576 bool isConst1 = false;
577 bool isConst2 = false;
578 int dir;
579
580 //Tmp1 = SelectExpr(N.getOperand(0));
581 if(N.getOperand(0).getOpcode() == ISD::Constant &&
582 cast<ConstantSDNode>(N.getOperand(0))->getValue() >= 0 &&
583 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
584 isConst1 = true;
585 if(N.getOperand(1).getOpcode() == ISD::Constant &&
586 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
587 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
588 isConst2 = true;
589
590 switch (SetCC->getCondition()) {
591 default: Node->dump(); assert(0 && "Unknown integer comparison!");
592 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
593 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
594 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
595 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
596 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
597 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
598 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
599 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
600 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000601 case ISD::SETNE: {//Handle this one special
602 //std::cerr << "Alpha does not have a setne.\n";
603 //abort();
604 Tmp1 = SelectExpr(N.getOperand(0));
605 Tmp2 = SelectExpr(N.getOperand(1));
606 Tmp3 = MakeReg(MVT::i64);
607 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
608 //and invert
609 BuildMI(BB,Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
610 return Result;
611 }
612 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000613 if (dir == 1) {
614 Tmp1 = SelectExpr(N.getOperand(0));
615 if (isConst2) {
616 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
617 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
618 } else {
619 Tmp2 = SelectExpr(N.getOperand(1));
620 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
621 }
622 } else if (dir == 2) {
623 Tmp1 = SelectExpr(N.getOperand(1));
624 if (isConst2) {
625 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
626 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
627 } else {
628 Tmp2 = SelectExpr(N.getOperand(0));
629 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
630 }
631 } else { //dir == 0
632 if (isConst1) {
633 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
634 Tmp2 = SelectExpr(N.getOperand(1));
635 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
636 } else if (isConst2) {
637 Tmp1 = SelectExpr(N.getOperand(0));
638 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
639 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
640 } else {
641 Tmp1 = SelectExpr(N.getOperand(0));
642 Tmp2 = SelectExpr(N.getOperand(1));
643 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
644 }
645 }
646 }
647 else
648 {
649 Node->dump();
650 assert(0 && "only integer");
651 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000652 }
653 else
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000654 {
655 Node->dump();
656 assert(0 && "Not a setcc in setcc");
657 }
658 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000659 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000660
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000661 case ISD::CopyFromReg:
662 {
663 if (Result == 1)
664 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
665
666 SDOperand Chain = N.getOperand(0);
667
668 Select(Chain);
669 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
670 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
671 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
672 return Result;
673 }
674
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000675 //Most of the plain arithmetic and logic share the same form, and the same
676 //constant immediate test
677 case ISD::AND:
678 case ISD::OR:
679 case ISD::XOR:
680 case ISD::SHL:
681 case ISD::SRL:
682 case ISD::MUL:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000683 switch (N.getValueType()) {
684 default: Node->dump(); assert (0 && "unhandled type");
685 case MVT::f64:
686 assert(N.getOpcode() == ISD::MUL && "only mul here please");
687 Tmp1 = SelectExpr(N.getOperand(0));
688 Tmp2 = SelectExpr(N.getOperand(1));
689 BuildMI(BB, Alpha::MULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
690 break;
691 case MVT::f32:
692 assert(N.getOpcode() == ISD::MUL && "only mul here please");
693 Tmp1 = SelectExpr(N.getOperand(0));
694 Tmp2 = SelectExpr(N.getOperand(1));
695 BuildMI(BB, Alpha::MULS, 2, Result).addReg(Tmp1).addReg(Tmp2);
696 break;
697 case MVT::i64:
698 if(N.getOperand(1).getOpcode() == ISD::Constant &&
699 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
700 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
701 {
702 switch(N.getOpcode()) {
703 case ISD::AND: Opc = Alpha::ANDi; break;
704 case ISD::OR: Opc = Alpha::BISi; break;
705 case ISD::XOR: Opc = Alpha::XORi; break;
706 case ISD::SHL: Opc = Alpha::SLi; break;
707 case ISD::SRL: Opc = Alpha::SRLi; break;
708 case ISD::SRA: Opc = Alpha::SRAi; break;
709 case ISD::MUL: Opc = Alpha::MULQi; break;
710 };
711 Tmp1 = SelectExpr(N.getOperand(0));
712 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
713 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
714 }
715 else
716 {
717 switch(N.getOpcode()) {
718 case ISD::AND: Opc = Alpha::AND; break;
719 case ISD::OR: Opc = Alpha::BIS; break;
720 case ISD::XOR: Opc = Alpha::XOR; break;
721 case ISD::SHL: Opc = Alpha::SL; break;
722 case ISD::SRL: Opc = Alpha::SRL; break;
723 case ISD::SRA: Opc = Alpha::SRA; break;
724 case ISD::MUL: Opc = Alpha::MULQ; break;
725 };
726 Tmp1 = SelectExpr(N.getOperand(0));
727 Tmp2 = SelectExpr(N.getOperand(1));
728 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
729 }
730 break;
731 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000732 return Result;
733
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000734 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000735 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000736 {
737 bool isAdd = N.getOpcode() == ISD::ADD;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000738
739 switch (N.getValueType()) {
740 default: Node->dump(); assert(0 && "Unhandled type");
741 case MVT::i64: {
742 //FIXME: first check for Scaled Adds and Subs!
743 if(N.getOperand(1).getOpcode() == ISD::Constant &&
744 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
745 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
746 { //Normal imm add/sub
747 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
748 Tmp1 = SelectExpr(N.getOperand(0));
749 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
750 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
751 }
752 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
753 cast<ConstantSDNode>(N.getOperand(1))->getValue() >= 0 &&
754 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
755 { //LDA //FIXME: expand the above condition a bit
756 Tmp1 = SelectExpr(N.getOperand(0));
757 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
758 if (!isAdd)
759 Tmp2 = -Tmp2;
760 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
761 }
762 else
763 { //Normal add/sub
764 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
765 Tmp1 = SelectExpr(N.getOperand(0));
766 Tmp2 = SelectExpr(N.getOperand(1));
767 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
768 }
769 } break;
770 case MVT::f64:
771 case MVT::f32:
772 if (N.getValueType() == MVT::f64)
773 Opc = isAdd ? Alpha::ADDT : Alpha::SUBT;
774 else
775 Opc = isAdd ? Alpha::ADDS : Alpha::SUBS;
776 //
777 Tmp1 = SelectExpr(N.getOperand(0));
778 Tmp2 = SelectExpr(N.getOperand(1));
779 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
780 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000781 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000782 return Result;
783 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000784
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000785 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +0000786 case ISD::SREM:
787 case ISD::SDIV:
788 case ISD::UDIV:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000789 switch (N.getValueType()) {
790 default: Node->dump(); assert (0 && "unhandled type");
791 case MVT::f64:
792 assert(N.getOpcode() == ISD::SDIV && "only div here please");
793 Opc = Alpha::DIVT;
794 break;
795 case MVT::f32:
796 assert(N.getOpcode() == ISD::SDIV && "only div here please");
797 Opc = Alpha::DIVS;
798 break;
799 case MVT::i64:
800 //FIXME: alpha really doesn't support any of these operations,
801 // the ops are expanded into special library calls with
802 // special calling conventions
803 switch(N.getOpcode()) {
804 case ISD::UREM: Opc = Alpha::REMQU; break;
805 case ISD::SREM: Opc = Alpha::REMQ; break;
806 case ISD::UDIV: Opc = Alpha::DIVQU; break;
807 case ISD::SDIV: Opc = Alpha::DIVQ; break;
808 }
809 break;
810 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000811 Tmp1 = SelectExpr(N.getOperand(0));
812 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +0000813 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000814 return Result;
815
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000816 case ISD::SINT_TO_FP:
817 {
818 MVT::ValueType DestTy = N.getValueType();
819 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
820 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
821 Tmp2 = MakeReg(DestTy);
822 Opc = DestTy == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
823 BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
824 Opc = DestTy == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
825 BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
826 return Result;
827 }
828
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000829// // case ISD::UINT_TO_FP:
830
831// case ISD::FP_TO_SINT:
832// assert (N.getValueType() == MVT::f64 && "Only can convert for doubles");
833// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
834// Tmp2 = MakeReg(SrcTy);
835// BuildMI(BB, CVTTQ, 1, Tmp2).addReg(Tmp1);
836// BuildMI(BB, FTOIT, 1, Result).addReg(Tmp2);
837// return result;
838
839// // case ISD::FP_TO_UINT:
840
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000841 case ISD::SELECT:
842 {
843 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
844 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
845 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
846 // Get the condition into the zero flag.
847 unsigned dummy = MakeReg(MVT::i64);
848 BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
849 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
850 return Result;
851 }
852
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000853 case ISD::Constant:
854 {
855 long val = cast<ConstantSDNode>(N)->getValue();
856 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
857 return Result;
858 }
859
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000860 case ISD::LOAD:
861 {
862 // Make sure we generate both values.
863 if (Result != 1)
864 ExprMap[N.getValue(1)] = 1; // Generate the token
865 else
866 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
867
868 SDOperand Chain = N.getOperand(0);
869 SDOperand Address = N.getOperand(1);
870
871 if (Address.getOpcode() == ISD::GlobalAddress)
872 {
873 Select(Chain);
874 AlphaLowering.restoreGP(BB);
875 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
876 }
877 else
878 {
879 Select(Chain);
880 Tmp2 = SelectExpr(Address);
881 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
882 }
883 return Result;
884 }
885 }
886
887 return 0;
888}
889
890void ISel::Select(SDOperand N) {
891 unsigned Tmp1, Tmp2, Opc;
892
893 // FIXME: Disable for our current expansion model!
894 if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
895 return; // Already selected.
896
897 SDNode *Node = N.Val;
898
899 switch (N.getOpcode()) {
900
901 default:
902 Node->dump(); std::cerr << "\n";
903 assert(0 && "Node not handled yet!");
904
905 case ISD::BRCOND: {
906 MachineBasicBlock *Dest =
907 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
908
909 Select(N.getOperand(0));
910 Tmp1 = SelectExpr(N.getOperand(1));
911 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
912 return;
913 }
914
915 case ISD::BR: {
916 MachineBasicBlock *Dest =
917 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
918
919 Select(N.getOperand(0));
920 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
921 return;
922 }
923
924 case ISD::ImplicitDef:
925 Select(N.getOperand(0));
926 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
927 return;
928
929 case ISD::EntryToken: return; // Noop
930
931 case ISD::TokenFactor:
932 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
933 Select(Node->getOperand(i));
934
935 //N.Val->dump(); std::cerr << "\n";
936 //assert(0 && "Node not handled yet!");
937
938 return;
939
940 case ISD::CopyToReg:
941 Select(N.getOperand(0));
942 Tmp1 = SelectExpr(N.getOperand(1));
943 Tmp2 = cast<RegSDNode>(N)->getReg();
944
945 if (Tmp1 != Tmp2) {
946 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
947 }
948 return;
949
950 case ISD::RET:
951 switch (N.getNumOperands()) {
952 default:
953 std::cerr << N.getNumOperands() << "\n";
954 for (unsigned i = 0; i < N.getNumOperands(); ++i)
955 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000956 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000957 assert(0 && "Unknown return instruction!");
958 case 2:
959 Select(N.getOperand(0));
960 Tmp1 = SelectExpr(N.getOperand(1));
961 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000962 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
963 case MVT::f64:
964 case MVT::f32:
965 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
966 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000967 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000968 case MVT::i64:
969 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
970 break;
971 }
972 break;
973 case 1:
974 Select(N.getOperand(0));
975 break;
976 }
977 //Tmp2 = AlphaLowering.getRetAddr();
978 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
979 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
980 return;
981
982 case ISD::STORE:
983 Select(N.getOperand(0));
984 Tmp1 = SelectExpr(N.getOperand(1)); //value
985 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
986 {
987 AlphaLowering.restoreGP(BB);
988 BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
989 }
990 else
991 {
992 Tmp2 = SelectExpr(N.getOperand(2)); //address
993 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
994 }
995 return;
996
997 case ISD::EXTLOAD:
998 case ISD::SEXTLOAD:
999 case ISD::ZEXTLOAD:
1000 case ISD::LOAD:
1001 case ISD::CopyFromReg:
1002 case ISD::CALL:
1003// case ISD::DYNAMIC_STACKALLOC:
1004 SelectExpr(N);
1005 return;
1006
1007
1008 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1009 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001010 if (StoredTy == MVT::i64) {
1011 Node->dump();
1012 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1013 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001014
1015 Select(N.getOperand(0));
1016 Tmp1 = SelectExpr(N.getOperand(1));
1017 Tmp2 = SelectExpr(N.getOperand(2));
1018
1019 switch (StoredTy) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001020 default: Node->dump(); assert(0 && "Unhandled Type"); break;
Andrew Lenharthd279b412005-01-25 19:58:40 +00001021 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001022 case MVT::i8: Opc = Alpha::STB; break;
1023 case MVT::i16: Opc = Alpha::STW; break;
1024 case MVT::i32: Opc = Alpha::STL; break;
1025 }
1026
1027 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1028 return;
1029 }
1030
1031 case ISD::ADJCALLSTACKDOWN:
1032 case ISD::ADJCALLSTACKUP:
1033 Select(N.getOperand(0));
1034 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1035
1036 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1037 Alpha::ADJUSTSTACKUP;
1038 BuildMI(BB, Opc, 1).addImm(Tmp1);
1039 return;
1040 }
1041 assert(0 && "Should not be reached!");
1042}
1043
1044
1045/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1046/// into a machine code representation using pattern matching and a machine
1047/// description file.
1048///
1049FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1050 return new ISel(TM);
1051}