blob: 29ee2553bbc59d7e8673424b9316ab9702fa9fcc [file] [log] [blame]
Misha Brukman2a8350a2005-02-05 02:24:26 +00001//===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
Andrew Lenharth304d0f32005-01-22 23:41:55 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a pattern matching instruction selector for Alpha.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Alpha.h"
Andrew Lenharth304d0f32005-01-22 23:41:55 +000015#include "AlphaRegisterInfo.h"
16#include "llvm/Constants.h" // FIXME: REMOVE
17#include "llvm/Function.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineFrameInfo.h"
22#include "llvm/CodeGen/SelectionDAG.h"
23#include "llvm/CodeGen/SelectionDAGISel.h"
24#include "llvm/CodeGen/SSARegMap.h"
25#include "llvm/Target/TargetData.h"
26#include "llvm/Target/TargetLowering.h"
27#include "llvm/Support/MathExtras.h"
28#include "llvm/ADT/Statistic.h"
29#include <set>
Andrew Lenharth684f2292005-01-30 00:35:27 +000030#include <algorithm>
Andrew Lenharth304d0f32005-01-22 23:41:55 +000031using namespace llvm;
32
33//===----------------------------------------------------------------------===//
34// AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
35namespace {
36 class AlphaTargetLowering : public TargetLowering {
37 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
38 unsigned GP; //GOT vreg
39 public:
40 AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
41 // Set up the TargetLowering object.
Andrew Lenharth3d65d312005-01-27 03:49:45 +000042 //I am having problems with shr n ubyte 1
Andrew Lenharth879ef222005-02-02 17:00:21 +000043 setShiftAmountType(MVT::i64);
44 setSetCCResultType(MVT::i64);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000045
Andrew Lenharth304d0f32005-01-22 23:41:55 +000046 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
47 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
Andrew Lenharth3d65d312005-01-27 03:49:45 +000048 addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000049
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000050 setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000051
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000052 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000053 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
Andrew Lenharth2f8fb772005-01-25 00:35:34 +000054
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +000055 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
Andrew Lenharth304d0f32005-01-22 23:41:55 +000056 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
57 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
58
Andrew Lenharth3d65d312005-01-27 03:49:45 +000059 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); //what is the sign expansion of 1? 1 or -1?
Andrew Lenharth02981182005-01-26 01:24:38 +000060
Andrew Lenharth9818c052005-02-05 13:19:12 +000061 setOperationAction(ISD::SREM , MVT::f32 , Expand);
62 setOperationAction(ISD::SREM , MVT::f64 , Expand);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +000063
Andrew Lenharth8d163d22005-02-02 05:49:42 +000064 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
Andrew Lenharth9818c052005-02-05 13:19:12 +000065 setOperationAction(ISD::MEMSET , MVT::Other, Expand);
66 setOperationAction(ISD::MEMCPY , MVT::Other, Expand);
67
68 setOperationAction(ISD::SETCC , MVT::f32 , Promote);
Andrew Lenharth8d163d22005-02-02 05:49:42 +000069
Andrew Lenharth3d65d312005-01-27 03:49:45 +000070 computeRegisterProperties();
Andrew Lenharth304d0f32005-01-22 23:41:55 +000071
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000072 addLegalFPImmediate(+0.0); //F31
Andrew Lenharth12dd2622005-02-03 21:01:15 +000073 addLegalFPImmediate(-0.0); //-F31
Andrew Lenharth304d0f32005-01-22 23:41:55 +000074 }
75
76 /// LowerArguments - This hook must be implemented to indicate how we should
77 /// lower the arguments for the specified function, into the specified DAG.
78 virtual std::vector<SDOperand>
79 LowerArguments(Function &F, SelectionDAG &DAG);
80
81 /// LowerCallTo - This hook lowers an abstract call to a function into an
82 /// actual call.
83 virtual std::pair<SDOperand, SDOperand>
84 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
85 ArgListTy &Args, SelectionDAG &DAG);
86
87 virtual std::pair<SDOperand, SDOperand>
88 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
89
90 virtual std::pair<SDOperand,SDOperand>
91 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
92 const Type *ArgTy, SelectionDAG &DAG);
93
94 virtual std::pair<SDOperand, SDOperand>
95 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
96 SelectionDAG &DAG);
97
98 void restoreGP(MachineBasicBlock* BB)
99 {
100 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
101 }
102 };
103}
104
105//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
106
107//For now, just use variable size stack frame format
108
109//In a standard call, the first six items are passed in registers $16
110//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
111//of argument-to-register correspondence.) The remaining items are
112//collected in a memory argument list that is a naturally aligned
113//array of quadwords. In a standard call, this list, if present, must
114//be passed at 0(SP).
115//7 ... n 0(SP) ... (n-7)*8(SP)
116
117std::vector<SDOperand>
118AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
119{
120 std::vector<SDOperand> ArgValues;
121
122 // //#define FP $15
123 // //#define RA $26
124 // //#define PV $27
125 // //#define GP $29
126 // //#define SP $30
127
128 // assert(0 && "TODO");
129 MachineFunction &MF = DAG.getMachineFunction();
130 MachineFrameInfo *MFI = MF.getFrameInfo();
131
132 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
133 MachineBasicBlock& BB = MF.front();
134
135 //Handle the return address
136 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
137
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000138 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
139 Alpha::R19, Alpha::R20, Alpha::R21};
140 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
141 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000142 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000143 std::vector<unsigned> argPreg;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000144 std::vector<unsigned> argOpc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000145 int count = 0;
146 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
147 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000148 SDOperand newroot, argt;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000149 if (count < 6) {
150 switch (getValueType(I->getType())) {
151 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
152 case MVT::f64:
153 case MVT::f32:
154 BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
155 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
156 argPreg.push_back(args_float[count]);
157 argOpc.push_back(Alpha::CPYS);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000158 argt = newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth684f2292005-01-30 00:35:27 +0000159 break;
160 case MVT::i1:
161 case MVT::i8:
162 case MVT::i16:
163 case MVT::i32:
164 case MVT::i64:
165 BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
166 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
167 argPreg.push_back(args_int[count]);
168 argOpc.push_back(Alpha::BIS);
169 argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
170 if (getValueType(I->getType()) != MVT::i64)
171 argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
172 break;
173 }
174 } else { //more args
175 // Create the frame index object for this incoming parameter...
176 int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
177
178 // Create the SelectionDAG nodes corresponding to a load from this parameter
179 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
180 argt = newroot = DAG.getLoad(getValueType(I->getType()), DAG.getEntryNode(), FIN);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000181 }
182 DAG.setRoot(newroot.getValue(1));
183 ArgValues.push_back(argt);
Andrew Lenharth684f2292005-01-30 00:35:27 +0000184 ++count;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000185 }
186
187 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
188 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000189 for (int i = 0; i < std::min(count,6); ++i)
Andrew Lenharth40831c52005-01-28 06:57:18 +0000190 BuildMI(&BB, argOpc[i], 2, argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
191
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000192 return ArgValues;
193}
194
195std::pair<SDOperand, SDOperand>
196AlphaTargetLowering::LowerCallTo(SDOperand Chain,
197 const Type *RetTy, SDOperand Callee,
198 ArgListTy &Args, SelectionDAG &DAG) {
199 int NumBytes = 0;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000200 if (Args.size() > 6)
201 NumBytes = (Args.size() - 6) * 8;
202
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000203 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:
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000214 // 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 Lenharth40831c52005-01-28 06:57:18 +0000217 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000218 else
Andrew Lenharth40831c52005-01-28 06:57:18 +0000219 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000220 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000221 case MVT::i64:
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000222 case MVT::f64:
223 case MVT::f32:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000224 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000225 }
226 args_to_use.push_back(Args[i].first);
227 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000228
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000229 std::vector<MVT::ValueType> RetVals;
230 MVT::ValueType RetTyVT = getValueType(RetTy);
231 if (RetTyVT != MVT::isVoid)
232 RetVals.push_back(RetTyVT);
233 RetVals.push_back(MVT::Other);
234
235 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
236 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
237 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
238 DAG.getConstant(NumBytes, getPointerTy()));
239 return std::make_pair(TheCall, Chain);
240}
241
242std::pair<SDOperand, SDOperand>
243AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
244 //vastart just returns the address of the VarArgsFrameIndex slot.
245 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
246}
247
248std::pair<SDOperand,SDOperand> AlphaTargetLowering::
249LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
250 const Type *ArgTy, SelectionDAG &DAG) {
251 abort();
252}
253
254
255std::pair<SDOperand, SDOperand> AlphaTargetLowering::
256LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
257 SelectionDAG &DAG) {
258 abort();
259}
260
261
262
263
264
265namespace {
266
267 //===--------------------------------------------------------------------===//
268 /// ISel - Alpha specific code to select Alpha machine instructions for
269 /// SelectionDAG operations.
270 ///
271 class ISel : public SelectionDAGISel {
272
273 /// AlphaLowering - This object fully describes how to lower LLVM code to an
274 /// Alpha-specific SelectionDAG.
275 AlphaTargetLowering AlphaLowering;
276
277
278 /// ExprMap - As shared expressions are codegen'd, we keep track of which
279 /// vreg the value is produced in, so we only emit one copy of each compiled
280 /// tree.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000281 static const unsigned notIn = (unsigned)(-1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000282 std::map<SDOperand, unsigned> ExprMap;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000283
284 public:
285 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
286 }
287
288 /// InstructionSelectBasicBlock - This callback is invoked by
289 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
290 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
291 // Codegen the basic block.
292 Select(DAG.getRoot());
293
294 // Clear state used for selection.
295 ExprMap.clear();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000296 }
297
298 unsigned SelectExpr(SDOperand N);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000299 unsigned SelectExprFP(SDOperand N, unsigned Result);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000300 void Select(SDOperand N);
301 };
302}
303
Andrew Lenharth40831c52005-01-28 06:57:18 +0000304unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
305{
306 unsigned Tmp1, Tmp2, Tmp3;
307 unsigned Opc = 0;
308 SDNode *Node = N.Val;
309 MVT::ValueType DestType = N.getValueType();
310 unsigned opcode = N.getOpcode();
311
312 switch (opcode) {
313 default:
314 Node->dump();
315 assert(0 && "Node not handled!\n");
Andrew Lenharth2c594352005-01-29 15:42:07 +0000316
Andrew Lenharth9818c052005-02-05 13:19:12 +0000317 case ISD::SELECT:
318 {
319 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
320 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
321 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
322 // Get the condition into the zero flag.
323 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
324 return Result;
325 }
326
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000327 case ISD::FP_ROUND:
328 assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here");
329 Tmp1 = SelectExpr(N.getOperand(0));
330 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
331 return Result;
332
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000333 case ISD::FP_EXTEND:
334 assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here");
335 Tmp1 = SelectExpr(N.getOperand(0));
336 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
337 return Result;
338
Andrew Lenharth2c594352005-01-29 15:42:07 +0000339 case ISD::CopyFromReg:
340 {
341 // Make sure we generate both values.
342 if (Result != notIn)
343 ExprMap[N.getValue(1)] = notIn; // Generate the token
344 else
345 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
346
347 SDOperand Chain = N.getOperand(0);
348
349 Select(Chain);
350 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
351 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
352 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
353 return Result;
354 }
355
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000356 case ISD::LOAD:
357 {
358 // Make sure we generate both values.
359 if (Result != notIn)
360 ExprMap[N.getValue(1)] = notIn; // Generate the token
361 else
362 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000363
364 //DestType = N.getValue(0).getValueType();
365
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000366 SDOperand Chain = N.getOperand(0);
367 SDOperand Address = N.getOperand(1);
368
369 if (Address.getOpcode() == ISD::GlobalAddress)
370 {
371 Select(Chain);
372 AlphaLowering.restoreGP(BB);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000373 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000374 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
375 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000376 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
377 AlphaLowering.restoreGP(BB);
378 if (DestType == MVT::f64) {
379 BuildMI(BB, Alpha::LDT_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
380 } else {
381 BuildMI(BB, Alpha::LDS_SYM, 1, Result).addConstantPoolIndex(CP->getIndex());
382 }
383 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000384 else
385 {
386 Select(Chain);
387 Tmp2 = SelectExpr(Address);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000388 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000389 BuildMI(BB, Opc, 2, Result).addImm(0).addReg(Tmp2);
390 }
391 return Result;
392 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000393 case ISD::ConstantFP:
394 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
395 if (CN->isExactlyValue(+0.0)) {
396 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000397 } else if ( CN->isExactlyValue(-0.0)) {
398 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000399 } else {
400 abort();
401 }
402 }
403 return Result;
404
405 case ISD::MUL:
406 case ISD::ADD:
407 case ISD::SUB:
408 case ISD::SDIV:
409 switch( opcode ) {
410 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
411 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
412 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
413 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
414 };
415 Tmp1 = SelectExpr(N.getOperand(0));
416 Tmp2 = SelectExpr(N.getOperand(1));
417 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
418 return Result;
419
Andrew Lenharth2c594352005-01-29 15:42:07 +0000420 case ISD::EXTLOAD:
421 //include a conversion sequence for float loads to double
422 if (Result != notIn)
423 ExprMap[N.getValue(1)] = notIn; // Generate the token
424 else
425 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
426
427 Tmp2 = MakeReg(MVT::f32);
428
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000429 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
430 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
431
432 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))) {
433 AlphaLowering.restoreGP(BB);
434 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp2).addConstantPoolIndex(CP->getIndex());
435 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
436 return Result;
437 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000438 Select(Node->getOperand(0)); // chain
439 Tmp1 = SelectExpr(Node->getOperand(1));
440 BuildMI(BB, Alpha::LDS, 1, Tmp2).addReg(Tmp1);
441 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
442 return Result;
443
444
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000445 case ISD::UINT_TO_FP:
446 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000447 {
448 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
449 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000450 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000451
452 //The hard way:
453 // Spill the integer to memory and reload it from there.
454 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
455 MachineFunction *F = BB->getParent();
456 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
457
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000458 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
459 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
460 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
461 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000462
463 //The easy way: doesn't work
464// //so these instructions are not supported on ev56
465// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
466// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
467// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
468// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
469
Andrew Lenharth40831c52005-01-28 06:57:18 +0000470 return Result;
471 }
472 }
473 assert(0 && "should not get here");
474 return 0;
475}
476
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000477unsigned ISel::SelectExpr(SDOperand N) {
478 unsigned Result;
479 unsigned Tmp1, Tmp2, Tmp3;
480 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000481 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000482
483 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000484 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000485
486 unsigned &Reg = ExprMap[N];
487 if (Reg) return Reg;
488
489 if (N.getOpcode() != ISD::CALL)
490 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000491 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000492 else {
493 // If this is a call instruction, make sure to prepare ALL of the result
494 // values as well as the chain.
495 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000496 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000497 else {
498 Result = MakeReg(Node->getValueType(0));
499 ExprMap[N.getValue(0)] = Result;
500 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
501 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000502 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000503 }
504 }
505
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000506 if (DestType == MVT::f64 || DestType == MVT::f32 ||
507 (opcode == ISD::LOAD &&
508 (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)))
Andrew Lenharth40831c52005-01-28 06:57:18 +0000509 return SelectExprFP(N, Result);
510
511 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000512 default:
513 Node->dump();
514 assert(0 && "Node not handled!\n");
515
Andrew Lenharth2c594352005-01-29 15:42:07 +0000516 case ISD::ConstantPool:
517 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
518 AlphaLowering.restoreGP(BB);
519 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(Tmp1);
520 return Result;
521
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000522 case ISD::FrameIndex:
523 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Andrew Lenharth684f2292005-01-30 00:35:27 +0000524 BuildMI(BB, Alpha::LDA, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000525 return Result;
526
527 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000528 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000529 if (Result != notIn)
530 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000531 else
532 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
533
534 Select(Node->getOperand(0)); // chain
535 Tmp1 = SelectExpr(Node->getOperand(1));
536
537 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000538 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000539 case MVT::i64:
540 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
541 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000542 Node->dump();
543 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000544 case MVT::i64:
545 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
546 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000547 case MVT::i32:
548 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
549 break;
550 case MVT::i16:
551 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
552 break;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000553 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000554 case MVT::i8:
555 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
556 break;
557 }
558 break;
559 }
560 return Result;
561
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000562 case ISD::SEXTLOAD:
563 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000564 if (Result != notIn)
565 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000566 else
567 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
568
569 Select(Node->getOperand(0)); // chain
570 Tmp1 = SelectExpr(Node->getOperand(1));
571 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000572 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000573 case MVT::i64:
574 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
575 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000576 Node->dump();
577 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000578 case MVT::i32:
579 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
580 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000581 }
582 break;
583 }
584 return Result;
585
586 case ISD::ZEXTLOAD:
587 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000588 if (Result != notIn)
589 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000590 else
591 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
592
593 Select(Node->getOperand(0)); // chain
594 Tmp1 = SelectExpr(Node->getOperand(1));
595 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000596 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000597 case MVT::i64:
598 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
599 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000600 Node->dump();
601 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000602 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000603 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000604 break;
605 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000606 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000607 break;
608 }
609 break;
610 }
611 return Result;
612
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000613
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000614 case ISD::GlobalAddress:
615 AlphaLowering.restoreGP(BB);
616 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
617 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
618 return Result;
619
620 case ISD::CALL:
621 {
622 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000623
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000624 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000625 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000626
627 //grab the arguments
628 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000629 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000630 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000631 argvregs.push_back(SelectExpr(N.getOperand(i)));
632
Andrew Lenharth684f2292005-01-30 00:35:27 +0000633 //in reg args
634 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
635 {
636 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
637 Alpha::R19, Alpha::R20, Alpha::R21};
638 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
639 Alpha::F19, Alpha::F20, Alpha::F21};
640 switch(N.getOperand(i+2).getValueType()) {
641 default:
642 Node->dump();
643 N.getOperand(i).Val->dump();
644 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
645 assert(0 && "Unknown value type for call");
646 case MVT::i1:
647 case MVT::i8:
648 case MVT::i16:
649 case MVT::i32:
650 case MVT::i64:
651 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
652 break;
653 case MVT::f32:
654 case MVT::f64:
655 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
656 break;
657 }
658 }
659 //in mem args
660 for (int i = 6, e = argvregs.size(); i < e; ++i)
661 {
662 switch(N.getOperand(i+2).getValueType()) {
663 default:
664 Node->dump();
665 N.getOperand(i).Val->dump();
666 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
667 assert(0 && "Unknown value type for call");
668 case MVT::i1:
669 case MVT::i8:
670 case MVT::i16:
671 case MVT::i32:
672 case MVT::i64:
673 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
674 break;
675 case MVT::f32:
676 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
677 break;
678 case MVT::f64:
679 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
680 break;
681 }
682 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000683 //build the right kind of call
684 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000685 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
686 {
687 AlphaLowering.restoreGP(BB);
688 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
689 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000690 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000691 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
692 {
693 AlphaLowering.restoreGP(BB);
694 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
695 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000696 else
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000697 {
698 //no need to restore GP as we are doing an indirect call
699 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000700 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
701 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000702 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000703
704 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000705
706 switch (Node->getValueType(0)) {
707 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000708 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000709 case MVT::i1:
710 case MVT::i8:
711 case MVT::i16:
712 case MVT::i32:
713 case MVT::i64:
714 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
715 break;
716 case MVT::f32:
717 case MVT::f64:
718 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
719 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000720 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000721 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000722 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000723
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000724 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000725 abort();
726
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000727 case ISD::SIGN_EXTEND_INREG:
728 {
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000729 //Alpha has instructions for a bunch of signed 32 bit stuff
730 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
731 {
732 switch (N.getOperand(0).getOpcode()) {
733 case ISD::ADD:
734 case ISD::SUB:
735 case ISD::MUL:
736 {
737 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
738 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
739 //FIXME: first check for Scaled Adds and Subs!
740 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
741 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
742 { //Normal imm add/sub
743 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
744 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
745 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
746 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
747 }
748 else
749 { //Normal add/sub
750 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
751 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
752 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
753 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
754 }
755 return Result;
756 }
757 default: break; //Fall Though;
758 }
759 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000760 Tmp1 = SelectExpr(N.getOperand(0));
761 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000762 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000763 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000764 {
765 default:
766 Node->dump();
767 assert(0 && "Sign Extend InReg not there yet");
768 break;
769 case MVT::i32:
770 {
771 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
772 break;
773 }
774 case MVT::i16:
775 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
776 break;
777 case MVT::i8:
778 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
779 break;
780 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000781 return Result;
782 }
783 case ISD::ZERO_EXTEND_INREG:
784 {
785 Tmp1 = SelectExpr(N.getOperand(0));
786 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000787 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000788 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000789 {
790 default:
791 Node->dump();
792 assert(0 && "Zero Extend InReg not there yet");
793 break;
794 case MVT::i32: Tmp2 = 0xf0; break;
795 case MVT::i16: Tmp2 = 0xfc; break;
796 case MVT::i8: Tmp2 = 0xfe; break;
797 case MVT::i1: //handle this one special
798 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
799 return Result;
800 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000801 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000802 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000803 }
804
805 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000806 {
807 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
808 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
809 bool isConst1 = false;
810 bool isConst2 = false;
811 int dir;
Andrew Lenharth9818c052005-02-05 13:19:12 +0000812
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000813 //Tmp1 = SelectExpr(N.getOperand(0));
814 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000815 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
816 isConst1 = true;
817 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000818 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
819 isConst2 = true;
820
821 switch (SetCC->getCondition()) {
822 default: Node->dump(); assert(0 && "Unknown integer comparison!");
823 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
824 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
825 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
826 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
827 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
828 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
829 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
830 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
831 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000832 case ISD::SETNE: {//Handle this one special
833 //std::cerr << "Alpha does not have a setne.\n";
834 //abort();
835 Tmp1 = SelectExpr(N.getOperand(0));
836 Tmp2 = SelectExpr(N.getOperand(1));
837 Tmp3 = MakeReg(MVT::i64);
838 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
839 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000840 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
841 //BuildMI(BB,Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000842 return Result;
843 }
844 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000845 if (dir == 1) {
846 Tmp1 = SelectExpr(N.getOperand(0));
847 if (isConst2) {
848 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
849 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
850 } else {
851 Tmp2 = SelectExpr(N.getOperand(1));
852 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
853 }
854 } else if (dir == 2) {
855 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +0000856 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000857 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
858 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
859 } else {
860 Tmp2 = SelectExpr(N.getOperand(0));
861 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
862 }
863 } else { //dir == 0
864 if (isConst1) {
865 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
866 Tmp2 = SelectExpr(N.getOperand(1));
867 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
868 } else if (isConst2) {
869 Tmp1 = SelectExpr(N.getOperand(0));
870 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
871 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
872 } else {
873 Tmp1 = SelectExpr(N.getOperand(0));
874 Tmp2 = SelectExpr(N.getOperand(1));
875 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
876 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000877 }
878 } else {
879 bool rev = false;
880 bool inv = false;
881
882 switch (SetCC->getCondition()) {
883 default: Node->dump(); assert(0 && "Unknown FP comparison!");
884 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
885 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
886 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
887 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
888 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
889 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
890 }
891
892 Tmp1 = SelectExpr(N.getOperand(0));
893 Tmp2 = SelectExpr(N.getOperand(1));
894 if (rev) std::swap(Tmp1, Tmp2);
895 Tmp3 = MakeReg(MVT::f64);
896 //do the comparison
897 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
898
899 //now arrange for Result (int) to have a 1 or 0
900
901 // Spill the FP to memory and reload it from there.
902 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
903 MachineFunction *F = BB->getParent();
904 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
905 unsigned Tmp4 = MakeReg(MVT::f64);
906 BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
907 BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
908 unsigned Tmp5 = MakeReg(MVT::i64);
909 BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
910
911 //now, set result based on Tmp5
912 //Set Tmp6 if fp cmp was false
913 unsigned Tmp6 = MakeReg(MVT::i64);
914 BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
915 //and invert
916 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
917
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000918 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000919// else
920// {
921// Node->dump();
922// assert(0 && "Not a setcc in setcc");
923// }
924 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000925 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000926 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000927
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000928 case ISD::CopyFromReg:
929 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000930 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000931 if (Result != notIn)
932 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +0000933 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000934 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +0000935
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000936 SDOperand Chain = N.getOperand(0);
937
938 Select(Chain);
939 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
940 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
941 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
942 return Result;
943 }
944
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000945 //Most of the plain arithmetic and logic share the same form, and the same
946 //constant immediate test
947 case ISD::AND:
948 case ISD::OR:
949 case ISD::XOR:
950 case ISD::SHL:
951 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +0000952 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000953 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000954 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
955 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000956 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
957 {
958 switch(opcode) {
959 case ISD::AND: Opc = Alpha::ANDi; break;
960 case ISD::OR: Opc = Alpha::BISi; break;
961 case ISD::XOR: Opc = Alpha::XORi; break;
962 case ISD::SHL: Opc = Alpha::SLi; break;
963 case ISD::SRL: Opc = Alpha::SRLi; break;
964 case ISD::SRA: Opc = Alpha::SRAi; break;
965 case ISD::MUL: Opc = Alpha::MULQi; break;
966 };
967 Tmp1 = SelectExpr(N.getOperand(0));
968 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
969 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
970 }
971 else
972 {
973 switch(opcode) {
974 case ISD::AND: Opc = Alpha::AND; break;
975 case ISD::OR: Opc = Alpha::BIS; break;
976 case ISD::XOR: Opc = Alpha::XOR; break;
977 case ISD::SHL: Opc = Alpha::SL; break;
978 case ISD::SRL: Opc = Alpha::SRL; break;
979 case ISD::SRA: Opc = Alpha::SRA; break;
980 case ISD::MUL: Opc = Alpha::MULQ; break;
981 };
982 Tmp1 = SelectExpr(N.getOperand(0));
983 Tmp2 = SelectExpr(N.getOperand(1));
984 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
985 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000986 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000987
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000988 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000989 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000990 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000991 bool isAdd = opcode == ISD::ADD;
992
993 //FIXME: first check for Scaled Adds and Subs!
994 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000995 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
996 { //Normal imm add/sub
997 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
998 Tmp1 = SelectExpr(N.getOperand(0));
999 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1000 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1001 }
1002 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001003 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
1004 { //LDA //FIXME: expand the above condition a bit
1005 Tmp1 = SelectExpr(N.getOperand(0));
1006 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1007 if (!isAdd)
1008 Tmp2 = -Tmp2;
1009 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1010 }
1011 else
1012 { //Normal add/sub
1013 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1014 Tmp1 = SelectExpr(N.getOperand(0));
1015 Tmp2 = SelectExpr(N.getOperand(1));
1016 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1017 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001018 return Result;
1019 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001020
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001021 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001022 case ISD::SREM:
1023 case ISD::SDIV:
1024 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001025 //FIXME: alpha really doesn't support any of these operations,
1026 // the ops are expanded into special library calls with
1027 // special calling conventions
1028 switch(opcode) {
1029 case ISD::UREM: Opc = Alpha::REMQU; break;
1030 case ISD::SREM: Opc = Alpha::REMQ; break;
1031 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1032 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001033 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001034 Tmp1 = SelectExpr(N.getOperand(0));
1035 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +00001036 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001037 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001038
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001039 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001040 case ISD::FP_TO_SINT:
1041 {
1042 assert (DestType == MVT::i64 && "only quads can be loaded to");
1043 MVT::ValueType SrcType = N.getOperand(0).getValueType();
1044 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1045
1046 //The hard way:
1047 // Spill the integer to memory and reload it from there.
1048 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1049 MachineFunction *F = BB->getParent();
1050 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1051
1052 //CVTTQ STT LDQ
1053 //CVTST CVTTQ STT LDQ
1054 if (SrcType == MVT::f32)
1055 {
1056 Tmp2 = MakeReg(MVT::f64);
1057 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1058 Tmp1 = Tmp2;
1059 }
1060 Tmp2 = MakeReg(MVT::f64);
1061 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1062 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1063 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1064
1065 return Result;
1066 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001067
1068// // case ISD::FP_TO_UINT:
1069
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001070 case ISD::SELECT:
1071 {
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001072 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001073 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1074 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001075 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001076 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001077 return Result;
1078 }
1079
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001080 case ISD::Constant:
1081 {
Andrew Lenharth22d5a412005-02-02 00:51:15 +00001082 unsigned long val = cast<ConstantSDNode>(N)->getValue();
1083 if (val < 32000 && (long)val > -32000)
1084 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
1085 else
1086 {
1087 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1088 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1089 unsigned CPI = CP->getConstantPoolIndex(C);
1090 AlphaLowering.restoreGP(BB);
1091 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CPI);
1092 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001093 return Result;
1094 }
1095
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001096 case ISD::LOAD:
1097 {
1098 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001099 if (Result != notIn)
1100 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001101 else
1102 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1103
1104 SDOperand Chain = N.getOperand(0);
1105 SDOperand Address = N.getOperand(1);
1106
Andrew Lenharthc23d6962005-02-02 04:35:44 +00001107 assert(N.getValue(0).getValueType() == MVT::i64 && "unknown Load dest type");
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001108
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001109 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001110 {
1111 Select(Chain);
1112 AlphaLowering.restoreGP(BB);
1113 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1114 }
1115 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1116 AlphaLowering.restoreGP(BB);
1117 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CP->getIndex());
1118 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001119 else
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001120 {
1121 Select(Chain);
1122 Tmp2 = SelectExpr(Address);
1123 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
1124 }
1125 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001126 }
1127 }
1128
1129 return 0;
1130}
1131
1132void ISel::Select(SDOperand N) {
1133 unsigned Tmp1, Tmp2, Opc;
1134
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001135 // FIXME: Disable for our current expansion model!
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001136 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001137 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001138
1139 SDNode *Node = N.Val;
1140
1141 switch (N.getOpcode()) {
1142
1143 default:
1144 Node->dump(); std::cerr << "\n";
1145 assert(0 && "Node not handled yet!");
1146
1147 case ISD::BRCOND: {
1148 MachineBasicBlock *Dest =
1149 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
1150
Andrew Lenharth9818c052005-02-05 13:19:12 +00001151 Select(N.getOperand(0)); //chain
1152
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001153 Tmp1 = SelectExpr(N.getOperand(1));
1154 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
1155 return;
1156 }
1157
1158 case ISD::BR: {
1159 MachineBasicBlock *Dest =
1160 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1161
1162 Select(N.getOperand(0));
1163 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1164 return;
1165 }
1166
1167 case ISD::ImplicitDef:
1168 Select(N.getOperand(0));
1169 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1170 return;
1171
1172 case ISD::EntryToken: return; // Noop
1173
1174 case ISD::TokenFactor:
1175 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1176 Select(Node->getOperand(i));
1177
1178 //N.Val->dump(); std::cerr << "\n";
1179 //assert(0 && "Node not handled yet!");
1180
1181 return;
1182
1183 case ISD::CopyToReg:
1184 Select(N.getOperand(0));
1185 Tmp1 = SelectExpr(N.getOperand(1));
1186 Tmp2 = cast<RegSDNode>(N)->getReg();
1187
1188 if (Tmp1 != Tmp2) {
1189 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1190 }
1191 return;
1192
1193 case ISD::RET:
1194 switch (N.getNumOperands()) {
1195 default:
1196 std::cerr << N.getNumOperands() << "\n";
1197 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1198 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001199 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001200 assert(0 && "Unknown return instruction!");
1201 case 2:
1202 Select(N.getOperand(0));
1203 Tmp1 = SelectExpr(N.getOperand(1));
1204 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001205 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
1206 case MVT::f64:
1207 case MVT::f32:
1208 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1209 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001210 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001211 case MVT::i64:
1212 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1213 break;
1214 }
1215 break;
1216 case 1:
1217 Select(N.getOperand(0));
1218 break;
1219 }
1220 //Tmp2 = AlphaLowering.getRetAddr();
1221 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1222 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1223 return;
1224
1225 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001226 {
1227 Select(N.getOperand(0));
1228 Tmp1 = SelectExpr(N.getOperand(1)); //value
1229 MVT::ValueType DestType = N.getOperand(1).getValueType();
1230 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
1231 {
1232 AlphaLowering.restoreGP(BB);
1233 if (DestType == MVT::i64) Opc = Alpha::STORE;
1234 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1235 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1236 else assert(0 && "unknown Type in store");
1237 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
1238 }
1239 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(2)))
1240 {
1241 AlphaLowering.restoreGP(BB);
1242 if (DestType == MVT::i64) Opc = Alpha::STORE;
1243 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1244 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1245 else assert(0 && "unknown Type in store");
1246 BuildMI(BB, Opc, 2).addReg(Tmp1).addConstantPoolIndex(CP->getIndex());
1247 }
1248 else
1249 {
1250 Tmp2 = SelectExpr(N.getOperand(2)); //address
1251 if (DestType == MVT::i64) Opc = Alpha::STQ;
1252 else if (DestType == MVT::f64) Opc = Alpha::STT;
1253 else if (DestType == MVT::f32) Opc = Alpha::STS;
1254 else assert(0 && "unknown Type in store");
1255 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
1256 }
1257 return;
1258 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001259
1260 case ISD::EXTLOAD:
1261 case ISD::SEXTLOAD:
1262 case ISD::ZEXTLOAD:
1263 case ISD::LOAD:
1264 case ISD::CopyFromReg:
1265 case ISD::CALL:
1266// case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001267 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001268 SelectExpr(N);
1269 return;
1270
1271
1272 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1273 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001274 if (StoredTy == MVT::i64) {
1275 Node->dump();
1276 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1277 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001278
1279 Select(N.getOperand(0));
1280 Tmp1 = SelectExpr(N.getOperand(1));
1281 Tmp2 = SelectExpr(N.getOperand(2));
1282
1283 switch (StoredTy) {
Chris Lattnerd7b59d02005-01-30 16:32:48 +00001284 default: Node->dump(); assert(0 && "Unhandled Type");
Andrew Lenharthd279b412005-01-25 19:58:40 +00001285 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001286 case MVT::i8: Opc = Alpha::STB; break;
1287 case MVT::i16: Opc = Alpha::STW; break;
1288 case MVT::i32: Opc = Alpha::STL; break;
1289 }
1290
1291 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1292 return;
1293 }
1294
1295 case ISD::ADJCALLSTACKDOWN:
1296 case ISD::ADJCALLSTACKUP:
1297 Select(N.getOperand(0));
1298 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1299
1300 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1301 Alpha::ADJUSTSTACKUP;
1302 BuildMI(BB, Opc, 1).addImm(Tmp1);
1303 return;
1304 }
1305 assert(0 && "Should not be reached!");
1306}
1307
1308
1309/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1310/// into a machine code representation using pattern matching and a machine
1311/// description file.
1312///
1313FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1314 return new ISel(TM);
1315}