blob: 9a198a3cdde62f2033e8599915cc0d04f39e44f9 [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
Andrew Lenharth3d65d312005-01-27 03:49:45 +000068 computeRegisterProperties();
Andrew Lenharth304d0f32005-01-22 23:41:55 +000069
Andrew Lenharthd2bb9602005-01-27 07:50:35 +000070 addLegalFPImmediate(+0.0); //F31
Andrew Lenharth12dd2622005-02-03 21:01:15 +000071 addLegalFPImmediate(-0.0); //-F31
Andrew Lenharth304d0f32005-01-22 23:41:55 +000072 }
73
74 /// LowerArguments - This hook must be implemented to indicate how we should
75 /// lower the arguments for the specified function, into the specified DAG.
76 virtual std::vector<SDOperand>
77 LowerArguments(Function &F, SelectionDAG &DAG);
78
79 /// LowerCallTo - This hook lowers an abstract call to a function into an
80 /// actual call.
81 virtual std::pair<SDOperand, SDOperand>
82 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
83 ArgListTy &Args, SelectionDAG &DAG);
84
85 virtual std::pair<SDOperand, SDOperand>
86 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
87
88 virtual std::pair<SDOperand,SDOperand>
89 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
90 const Type *ArgTy, SelectionDAG &DAG);
91
92 virtual std::pair<SDOperand, SDOperand>
93 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
94 SelectionDAG &DAG);
95
96 void restoreGP(MachineBasicBlock* BB)
97 {
98 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
99 }
100 };
101}
102
103//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
104
105//For now, just use variable size stack frame format
106
107//In a standard call, the first six items are passed in registers $16
108//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
109//of argument-to-register correspondence.) The remaining items are
110//collected in a memory argument list that is a naturally aligned
111//array of quadwords. In a standard call, this list, if present, must
112//be passed at 0(SP).
113//7 ... n 0(SP) ... (n-7)*8(SP)
114
115std::vector<SDOperand>
116AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
117{
118 std::vector<SDOperand> ArgValues;
119
120 // //#define FP $15
121 // //#define RA $26
122 // //#define PV $27
123 // //#define GP $29
124 // //#define SP $30
125
126 // assert(0 && "TODO");
127 MachineFunction &MF = DAG.getMachineFunction();
128 MachineFrameInfo *MFI = MF.getFrameInfo();
129
130 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
131 MachineBasicBlock& BB = MF.front();
132
133 //Handle the return address
134 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
135
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000136 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
137 Alpha::R19, Alpha::R20, Alpha::R21};
138 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
139 Alpha::F19, Alpha::F20, Alpha::F21};
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000140 std::vector<unsigned> argVreg;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000141 std::vector<unsigned> argPreg;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000142 std::vector<unsigned> argOpc;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000143 int count = 0;
144 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
145 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000146 SDOperand newroot, argt;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000147 if (count < 6) {
148 switch (getValueType(I->getType())) {
149 default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
150 case MVT::f64:
151 case MVT::f32:
152 BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
153 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))));
154 argPreg.push_back(args_float[count]);
155 argOpc.push_back(Alpha::CPYS);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000156 argt = newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
Andrew Lenharth684f2292005-01-30 00:35:27 +0000157 break;
158 case MVT::i1:
159 case MVT::i8:
160 case MVT::i16:
161 case MVT::i32:
162 case MVT::i64:
163 BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
164 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
165 argPreg.push_back(args_int[count]);
166 argOpc.push_back(Alpha::BIS);
167 argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
168 if (getValueType(I->getType()) != MVT::i64)
169 argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
170 break;
171 }
172 } else { //more args
173 // Create the frame index object for this incoming parameter...
174 int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
175
176 // Create the SelectionDAG nodes corresponding to a load from this parameter
177 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
178 argt = newroot = DAG.getLoad(getValueType(I->getType()), DAG.getEntryNode(), FIN);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000179 }
180 DAG.setRoot(newroot.getValue(1));
181 ArgValues.push_back(argt);
Andrew Lenharth684f2292005-01-30 00:35:27 +0000182 ++count;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000183 }
184
185 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
186 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000187 for (int i = 0; i < std::min(count,6); ++i)
Andrew Lenharth40831c52005-01-28 06:57:18 +0000188 BuildMI(&BB, argOpc[i], 2, argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
189
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;
Andrew Lenharth684f2292005-01-30 00:35:27 +0000198 if (Args.size() > 6)
199 NumBytes = (Args.size() - 6) * 8;
200
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000201 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
202 DAG.getConstant(NumBytes, getPointerTy()));
203 std::vector<SDOperand> args_to_use;
204 for (unsigned i = 0, e = Args.size(); i != e; ++i)
205 {
206 switch (getValueType(Args[i].second)) {
207 default: assert(0 && "Unexpected ValueType for argument!");
208 case MVT::i1:
209 case MVT::i8:
210 case MVT::i16:
211 case MVT::i32:
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000212 // Promote the integer to 64 bits. If the input type is signed use a
213 // sign extend, otherwise use a zero extend.
214 if (Args[i].second->isSigned())
Andrew Lenharth40831c52005-01-28 06:57:18 +0000215 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000216 else
Andrew Lenharth40831c52005-01-28 06:57:18 +0000217 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000218 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000219 case MVT::i64:
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000220 case MVT::f64:
221 case MVT::f32:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000222 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000223 }
224 args_to_use.push_back(Args[i].first);
225 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000226
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000227 std::vector<MVT::ValueType> RetVals;
228 MVT::ValueType RetTyVT = getValueType(RetTy);
229 if (RetTyVT != MVT::isVoid)
230 RetVals.push_back(RetTyVT);
231 RetVals.push_back(MVT::Other);
232
233 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
234 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
235 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
236 DAG.getConstant(NumBytes, getPointerTy()));
237 return std::make_pair(TheCall, Chain);
238}
239
240std::pair<SDOperand, SDOperand>
241AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
242 //vastart just returns the address of the VarArgsFrameIndex slot.
243 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
244}
245
246std::pair<SDOperand,SDOperand> AlphaTargetLowering::
247LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
248 const Type *ArgTy, SelectionDAG &DAG) {
249 abort();
250}
251
252
253std::pair<SDOperand, SDOperand> AlphaTargetLowering::
254LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
255 SelectionDAG &DAG) {
256 abort();
257}
258
259
260
261
262
263namespace {
264
265 //===--------------------------------------------------------------------===//
266 /// ISel - Alpha specific code to select Alpha machine instructions for
267 /// SelectionDAG operations.
268 ///
269 class ISel : public SelectionDAGISel {
270
271 /// AlphaLowering - This object fully describes how to lower LLVM code to an
272 /// Alpha-specific SelectionDAG.
273 AlphaTargetLowering AlphaLowering;
274
275
276 /// ExprMap - As shared expressions are codegen'd, we keep track of which
277 /// vreg the value is produced in, so we only emit one copy of each compiled
278 /// tree.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000279 static const unsigned notIn = (unsigned)(-1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000280 std::map<SDOperand, unsigned> ExprMap;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000281
282 public:
283 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
284 }
285
286 /// InstructionSelectBasicBlock - This callback is invoked by
287 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
288 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
289 // Codegen the basic block.
290 Select(DAG.getRoot());
291
292 // Clear state used for selection.
293 ExprMap.clear();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000294 }
295
296 unsigned SelectExpr(SDOperand N);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000297 unsigned SelectExprFP(SDOperand N, unsigned Result);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000298 void Select(SDOperand N);
299 };
300}
301
Andrew Lenharth40831c52005-01-28 06:57:18 +0000302unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
303{
304 unsigned Tmp1, Tmp2, Tmp3;
305 unsigned Opc = 0;
306 SDNode *Node = N.Val;
307 MVT::ValueType DestType = N.getValueType();
308 unsigned opcode = N.getOpcode();
309
310 switch (opcode) {
311 default:
312 Node->dump();
313 assert(0 && "Node not handled!\n");
Andrew Lenharth2c594352005-01-29 15:42:07 +0000314
Andrew Lenharth9818c052005-02-05 13:19:12 +0000315 case ISD::SELECT:
316 {
317 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
318 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
319 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000320
321
322 // Spill the cond to memory and reload it from there.
323 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
324 MachineFunction *F = BB->getParent();
325 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
326 unsigned Tmp4 = MakeReg(MVT::f64);
327 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
328 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
329 //now ideally, we don't have to do anything to the flag...
Andrew Lenharth9818c052005-02-05 13:19:12 +0000330 // Get the condition into the zero flag.
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000331 BuildMI(BB, Alpha::FCMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp4);
Andrew Lenharth9818c052005-02-05 13:19:12 +0000332 return Result;
333 }
334
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000335 case ISD::FP_ROUND:
336 assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here");
337 Tmp1 = SelectExpr(N.getOperand(0));
338 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
339 return Result;
340
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000341 case ISD::FP_EXTEND:
342 assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here");
343 Tmp1 = SelectExpr(N.getOperand(0));
344 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
345 return Result;
346
Andrew Lenharth2c594352005-01-29 15:42:07 +0000347 case ISD::CopyFromReg:
348 {
349 // Make sure we generate both values.
350 if (Result != notIn)
351 ExprMap[N.getValue(1)] = notIn; // Generate the token
352 else
353 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
354
355 SDOperand Chain = N.getOperand(0);
356
357 Select(Chain);
358 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
359 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
360 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
361 return Result;
362 }
363
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000364 case ISD::LOAD:
365 {
366 // Make sure we generate both values.
367 if (Result != notIn)
368 ExprMap[N.getValue(1)] = notIn; // Generate the token
369 else
370 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000371
372 //DestType = N.getValue(0).getValueType();
373
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000374 SDOperand Chain = N.getOperand(0);
375 SDOperand Address = N.getOperand(1);
376
377 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000378 {
379 Select(Chain);
380 AlphaLowering.restoreGP(BB);
381 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
382 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
383 }
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000384 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000385 AlphaLowering.restoreGP(BB);
Andrew Lenharth97127a12005-02-05 17:41:39 +0000386 Opc = DestType == MVT::f64 ? Alpha::LDT_SYM : Alpha::LDS_SYM;
387 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000388 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000389 else
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000390 {
391 Select(Chain);
392 Tmp2 = SelectExpr(Address);
393 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
394 BuildMI(BB, Opc, 2, Result).addImm(0).addReg(Tmp2);
395 }
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000396 return Result;
397 }
Andrew Lenharth40831c52005-01-28 06:57:18 +0000398 case ISD::ConstantFP:
399 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
400 if (CN->isExactlyValue(+0.0)) {
401 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000402 } else if ( CN->isExactlyValue(-0.0)) {
403 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
Andrew Lenharth40831c52005-01-28 06:57:18 +0000404 } else {
405 abort();
406 }
407 }
408 return Result;
409
410 case ISD::MUL:
411 case ISD::ADD:
412 case ISD::SUB:
413 case ISD::SDIV:
414 switch( opcode ) {
415 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
416 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
417 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
418 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
419 };
420 Tmp1 = SelectExpr(N.getOperand(0));
421 Tmp2 = SelectExpr(N.getOperand(1));
422 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
423 return Result;
424
Andrew Lenharth2c594352005-01-29 15:42:07 +0000425 case ISD::EXTLOAD:
426 //include a conversion sequence for float loads to double
427 if (Result != notIn)
428 ExprMap[N.getValue(1)] = notIn; // Generate the token
429 else
430 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
431
432 Tmp2 = MakeReg(MVT::f32);
433
Andrew Lenharth12dd2622005-02-03 21:01:15 +0000434 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
435 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
436
437 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))) {
438 AlphaLowering.restoreGP(BB);
439 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp2).addConstantPoolIndex(CP->getIndex());
440 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
441 return Result;
442 }
Andrew Lenharth2c594352005-01-29 15:42:07 +0000443 Select(Node->getOperand(0)); // chain
444 Tmp1 = SelectExpr(Node->getOperand(1));
445 BuildMI(BB, Alpha::LDS, 1, Tmp2).addReg(Tmp1);
446 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp2);
447 return Result;
448
449
Andrew Lenharthe76797c2005-02-01 20:40:27 +0000450 case ISD::UINT_TO_FP:
451 case ISD::SINT_TO_FP:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000452 {
453 assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
454 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000455 Tmp2 = MakeReg(MVT::f64);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000456
457 //The hard way:
458 // Spill the integer to memory and reload it from there.
459 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
460 MachineFunction *F = BB->getParent();
461 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
462
Andrew Lenharth7efadce2005-01-31 01:44:26 +0000463 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
464 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
465 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
466 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
Andrew Lenharth2c594352005-01-29 15:42:07 +0000467
468 //The easy way: doesn't work
469// //so these instructions are not supported on ev56
470// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
471// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
472// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
473// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
474
Andrew Lenharth40831c52005-01-28 06:57:18 +0000475 return Result;
476 }
477 }
478 assert(0 && "should not get here");
479 return 0;
480}
481
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000482unsigned ISel::SelectExpr(SDOperand N) {
483 unsigned Result;
484 unsigned Tmp1, Tmp2, Tmp3;
485 unsigned Opc = 0;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000486 unsigned opcode = N.getOpcode();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000487
488 SDNode *Node = N.Val;
Andrew Lenharth40831c52005-01-28 06:57:18 +0000489 MVT::ValueType DestType = N.getValueType();
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000490
491 unsigned &Reg = ExprMap[N];
492 if (Reg) return Reg;
493
494 if (N.getOpcode() != ISD::CALL)
495 Reg = Result = (N.getValueType() != MVT::Other) ?
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000496 MakeReg(N.getValueType()) : notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000497 else {
498 // If this is a call instruction, make sure to prepare ALL of the result
499 // values as well as the chain.
500 if (Node->getNumValues() == 1)
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000501 Reg = Result = notIn; // Void call, just a chain.
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000502 else {
503 Result = MakeReg(Node->getValueType(0));
504 ExprMap[N.getValue(0)] = Result;
505 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
506 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000507 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000508 }
509 }
510
Andrew Lenharth22088bb2005-02-02 15:05:33 +0000511 if (DestType == MVT::f64 || DestType == MVT::f32 ||
512 (opcode == ISD::LOAD &&
513 (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)))
Andrew Lenharth40831c52005-01-28 06:57:18 +0000514 return SelectExprFP(N, Result);
515
516 switch (opcode) {
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000517 default:
518 Node->dump();
519 assert(0 && "Node not handled!\n");
520
Andrew Lenharth2c594352005-01-29 15:42:07 +0000521 case ISD::ConstantPool:
522 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
523 AlphaLowering.restoreGP(BB);
524 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(Tmp1);
525 return Result;
526
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000527 case ISD::FrameIndex:
528 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Andrew Lenharth684f2292005-01-30 00:35:27 +0000529 BuildMI(BB, Alpha::LDA, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000530 return Result;
531
532 case ISD::EXTLOAD:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000533 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000534 if (Result != notIn)
535 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000536 else
537 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
538
539 Select(Node->getOperand(0)); // chain
540 Tmp1 = SelectExpr(Node->getOperand(1));
541
542 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000543 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000544 case MVT::i64:
545 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
546 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000547 Node->dump();
548 assert(0 && "Bad extend load!");
Andrew Lenharthd279b412005-01-25 19:58:40 +0000549 case MVT::i64:
550 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1);
551 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000552 case MVT::i32:
553 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
554 break;
555 case MVT::i16:
556 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
557 break;
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000558 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000559 case MVT::i8:
560 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
561 break;
562 }
563 break;
564 }
565 return Result;
566
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000567 case ISD::SEXTLOAD:
568 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000569 if (Result != notIn)
570 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000571 else
572 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
573
574 Select(Node->getOperand(0)); // chain
575 Tmp1 = SelectExpr(Node->getOperand(1));
576 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000577 default: Node->dump(); assert(0 && "Unknown type to sign extend to.");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000578 case MVT::i64:
579 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
580 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000581 Node->dump();
582 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000583 case MVT::i32:
584 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
585 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000586 }
587 break;
588 }
589 return Result;
590
591 case ISD::ZEXTLOAD:
592 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000593 if (Result != notIn)
594 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000595 else
596 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
597
598 Select(Node->getOperand(0)); // chain
599 Tmp1 = SelectExpr(Node->getOperand(1));
600 switch(Node->getValueType(0)) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000601 default: Node->dump(); assert(0 && "Unknown type to zero extend to.");
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000602 case MVT::i64:
603 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
604 default:
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000605 Node->dump();
606 assert(0 && "Bad sign extend!");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000607 case MVT::i16:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000608 BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000609 break;
610 case MVT::i8:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000611 BuildMI(BB, Alpha::LDBU, 2, Result).addImm(0).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000612 break;
613 }
614 break;
615 }
616 return Result;
617
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000618
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000619 case ISD::GlobalAddress:
620 AlphaLowering.restoreGP(BB);
621 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
622 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
623 return Result;
624
625 case ISD::CALL:
626 {
627 Select(N.getOperand(0));
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000628
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000629 // The chain for this call is now lowered.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000630 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000631
632 //grab the arguments
633 std::vector<unsigned> argvregs;
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000634 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000635 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000636 argvregs.push_back(SelectExpr(N.getOperand(i)));
637
Andrew Lenharth684f2292005-01-30 00:35:27 +0000638 //in reg args
639 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
640 {
641 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
642 Alpha::R19, Alpha::R20, Alpha::R21};
643 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
644 Alpha::F19, Alpha::F20, Alpha::F21};
645 switch(N.getOperand(i+2).getValueType()) {
646 default:
647 Node->dump();
648 N.getOperand(i).Val->dump();
649 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
650 assert(0 && "Unknown value type for call");
651 case MVT::i1:
652 case MVT::i8:
653 case MVT::i16:
654 case MVT::i32:
655 case MVT::i64:
656 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
657 break;
658 case MVT::f32:
659 case MVT::f64:
660 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
661 break;
662 }
663 }
664 //in mem args
665 for (int i = 6, e = argvregs.size(); i < e; ++i)
666 {
667 switch(N.getOperand(i+2).getValueType()) {
668 default:
669 Node->dump();
670 N.getOperand(i).Val->dump();
671 std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
672 assert(0 && "Unknown value type for call");
673 case MVT::i1:
674 case MVT::i8:
675 case MVT::i16:
676 case MVT::i32:
677 case MVT::i64:
678 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
679 break;
680 case MVT::f32:
681 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
682 break;
683 case MVT::f64:
684 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
685 break;
686 }
687 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000688 //build the right kind of call
689 if (GlobalAddressSDNode *GASD =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000690 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
691 {
692 AlphaLowering.restoreGP(BB);
693 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
694 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000695 else if (ExternalSymbolSDNode *ESSDN =
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000696 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
697 {
698 AlphaLowering.restoreGP(BB);
699 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
700 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000701 else
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000702 {
703 //no need to restore GP as we are doing an indirect call
704 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000705 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
706 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000707 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000708
709 //push the result into a virtual register
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000710
711 switch (Node->getValueType(0)) {
712 default: Node->dump(); assert(0 && "Unknown value type for call result!");
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000713 case MVT::Other: return notIn;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000714 case MVT::i1:
715 case MVT::i8:
716 case MVT::i16:
717 case MVT::i32:
718 case MVT::i64:
719 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
720 break;
721 case MVT::f32:
722 case MVT::f64:
723 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
724 break;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000725 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000726 return Result+N.ResNo;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000727 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000728
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000729 case ISD::SIGN_EXTEND:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000730 abort();
731
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000732 case ISD::SIGN_EXTEND_INREG:
733 {
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000734 //Alpha has instructions for a bunch of signed 32 bit stuff
735 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
736 {
737 switch (N.getOperand(0).getOpcode()) {
738 case ISD::ADD:
739 case ISD::SUB:
740 case ISD::MUL:
741 {
742 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
743 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
744 //FIXME: first check for Scaled Adds and Subs!
745 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
746 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
747 { //Normal imm add/sub
748 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
749 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
750 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
751 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
752 }
753 else
754 { //Normal add/sub
755 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
756 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
757 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
758 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
759 }
760 return Result;
761 }
762 default: break; //Fall Though;
763 }
764 } //Every thing else fall though too, including unhandled opcodes above
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000765 Tmp1 = SelectExpr(N.getOperand(0));
766 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000767 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000768 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000769 {
770 default:
771 Node->dump();
772 assert(0 && "Sign Extend InReg not there yet");
773 break;
774 case MVT::i32:
775 {
776 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
777 break;
778 }
779 case MVT::i16:
780 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
781 break;
782 case MVT::i8:
783 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
784 break;
785 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000786 return Result;
787 }
788 case ISD::ZERO_EXTEND_INREG:
789 {
790 Tmp1 = SelectExpr(N.getOperand(0));
791 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000792 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000793 switch(MVN->getExtraValueType())
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000794 {
795 default:
796 Node->dump();
797 assert(0 && "Zero Extend InReg not there yet");
798 break;
799 case MVT::i32: Tmp2 = 0xf0; break;
800 case MVT::i16: Tmp2 = 0xfc; break;
801 case MVT::i8: Tmp2 = 0xfe; break;
802 case MVT::i1: //handle this one special
803 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
804 return Result;
805 }
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000806 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000807 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000808 }
809
810 case ISD::SETCC:
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000811 {
812 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
813 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
814 bool isConst1 = false;
815 bool isConst2 = false;
816 int dir;
Andrew Lenharth9818c052005-02-05 13:19:12 +0000817
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000818 //Tmp1 = SelectExpr(N.getOperand(0));
819 if(N.getOperand(0).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000820 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
821 isConst1 = true;
822 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000823 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
824 isConst2 = true;
825
826 switch (SetCC->getCondition()) {
827 default: Node->dump(); assert(0 && "Unknown integer comparison!");
828 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
829 case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
830 case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
831 case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
832 case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
833 case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
834 case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
835 case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
836 case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000837 case ISD::SETNE: {//Handle this one special
838 //std::cerr << "Alpha does not have a setne.\n";
839 //abort();
840 Tmp1 = SelectExpr(N.getOperand(0));
841 Tmp2 = SelectExpr(N.getOperand(1));
842 Tmp3 = MakeReg(MVT::i64);
843 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
844 //and invert
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000845 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000846 return Result;
847 }
848 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000849 if (dir == 1) {
850 Tmp1 = SelectExpr(N.getOperand(0));
851 if (isConst2) {
852 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
853 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
854 } else {
855 Tmp2 = SelectExpr(N.getOperand(1));
856 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
857 }
858 } else if (dir == 2) {
859 Tmp1 = SelectExpr(N.getOperand(1));
Andrew Lenharth6b9870a2005-01-28 14:06:46 +0000860 if (isConst1) {
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000861 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
862 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
863 } else {
864 Tmp2 = SelectExpr(N.getOperand(0));
865 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
866 }
867 } else { //dir == 0
868 if (isConst1) {
869 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
870 Tmp2 = SelectExpr(N.getOperand(1));
871 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
872 } else if (isConst2) {
873 Tmp1 = SelectExpr(N.getOperand(0));
874 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
875 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
876 } else {
877 Tmp1 = SelectExpr(N.getOperand(0));
878 Tmp2 = SelectExpr(N.getOperand(1));
879 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
880 }
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000881 }
882 } else {
883 //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
884 bool rev = false;
885 bool inv = false;
886
887 switch (SetCC->getCondition()) {
888 default: Node->dump(); assert(0 && "Unknown FP comparison!");
889 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
890 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
891 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
892 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
893 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
894 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
895 }
896
897 Tmp1 = SelectExpr(N.getOperand(0));
898 Tmp2 = SelectExpr(N.getOperand(1));
899 //Can only compare doubles, and dag won't promote for me
900 if (SetCC->getOperand(0).getValueType() == MVT::f32)
901 {
902 Tmp3 = MakeReg(MVT::f64);
903 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
904 Tmp1 = Tmp3;
905 }
906 if (SetCC->getOperand(1).getValueType() == MVT::f32)
907 {
908 Tmp3 = MakeReg(MVT::f64);
909 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
910 Tmp1 = Tmp2;
911 }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000912
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000913 if (rev) std::swap(Tmp1, Tmp2);
914 Tmp3 = MakeReg(MVT::f64);
915 //do the comparison
916 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
917
918 //now arrange for Result (int) to have a 1 or 0
919
920 // Spill the FP to memory and reload it from there.
921 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
922 MachineFunction *F = BB->getParent();
923 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
924 unsigned Tmp4 = MakeReg(MVT::f64);
925 BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
926 BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
927 unsigned Tmp5 = MakeReg(MVT::i64);
928 BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
Andrew Lenharth9818c052005-02-05 13:19:12 +0000929
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000930 //now, set result based on Tmp5
931 //Set Tmp6 if fp cmp was false
932 unsigned Tmp6 = MakeReg(MVT::i64);
933 BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
934 //and invert
935 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
936
937 }
938 // else
939 // {
940 // Node->dump();
941 // assert(0 && "Not a setcc in setcc");
942 // }
Andrew Lenharth9818c052005-02-05 13:19:12 +0000943 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000944 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000945 }
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000946
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000947 case ISD::CopyFromReg:
948 {
Andrew Lenharth40831c52005-01-28 06:57:18 +0000949 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +0000950 if (Result != notIn)
951 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth40831c52005-01-28 06:57:18 +0000952 else
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000953 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
Andrew Lenharth40831c52005-01-28 06:57:18 +0000954
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000955 SDOperand Chain = N.getOperand(0);
956
957 Select(Chain);
958 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
959 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
960 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
961 return Result;
962 }
963
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000964 //Most of the plain arithmetic and logic share the same form, and the same
965 //constant immediate test
966 case ISD::AND:
967 case ISD::OR:
968 case ISD::XOR:
969 case ISD::SHL:
970 case ISD::SRL:
Andrew Lenharth2c594352005-01-29 15:42:07 +0000971 case ISD::SRA:
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000972 case ISD::MUL:
Andrew Lenharth40831c52005-01-28 06:57:18 +0000973 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
974 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +0000975 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
976 {
977 switch(opcode) {
978 case ISD::AND: Opc = Alpha::ANDi; break;
979 case ISD::OR: Opc = Alpha::BISi; break;
980 case ISD::XOR: Opc = Alpha::XORi; break;
981 case ISD::SHL: Opc = Alpha::SLi; break;
982 case ISD::SRL: Opc = Alpha::SRLi; break;
983 case ISD::SRA: Opc = Alpha::SRAi; break;
984 case ISD::MUL: Opc = Alpha::MULQi; break;
985 };
986 Tmp1 = SelectExpr(N.getOperand(0));
987 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
988 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
989 }
990 else
991 {
992 switch(opcode) {
993 case ISD::AND: Opc = Alpha::AND; break;
994 case ISD::OR: Opc = Alpha::BIS; break;
995 case ISD::XOR: Opc = Alpha::XOR; break;
996 case ISD::SHL: Opc = Alpha::SL; break;
997 case ISD::SRL: Opc = Alpha::SRL; break;
998 case ISD::SRA: Opc = Alpha::SRA; break;
999 case ISD::MUL: Opc = Alpha::MULQ; break;
1000 };
1001 Tmp1 = SelectExpr(N.getOperand(0));
1002 Tmp2 = SelectExpr(N.getOperand(1));
1003 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1004 }
Andrew Lenharth2d6f0222005-01-24 19:44:07 +00001005 return Result;
Andrew Lenharth40831c52005-01-28 06:57:18 +00001006
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001007 case ISD::ADD:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001008 case ISD::SUB:
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001009 {
Andrew Lenharth40831c52005-01-28 06:57:18 +00001010 bool isAdd = opcode == ISD::ADD;
1011
1012 //FIXME: first check for Scaled Adds and Subs!
1013 if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001014 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1015 { //Normal imm add/sub
1016 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
1017 Tmp1 = SelectExpr(N.getOperand(0));
1018 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1019 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1020 }
1021 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
Andrew Lenharth40831c52005-01-28 06:57:18 +00001022 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
1023 { //LDA //FIXME: expand the above condition a bit
1024 Tmp1 = SelectExpr(N.getOperand(0));
1025 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1026 if (!isAdd)
1027 Tmp2 = -Tmp2;
1028 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1029 }
1030 else
1031 { //Normal add/sub
1032 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1033 Tmp1 = SelectExpr(N.getOperand(0));
1034 Tmp2 = SelectExpr(N.getOperand(1));
1035 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1036 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001037 return Result;
1038 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001039
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001040 case ISD::UREM:
Andrew Lenharth02981182005-01-26 01:24:38 +00001041 case ISD::SREM:
1042 case ISD::SDIV:
1043 case ISD::UDIV:
Andrew Lenharth40831c52005-01-28 06:57:18 +00001044 //FIXME: alpha really doesn't support any of these operations,
1045 // the ops are expanded into special library calls with
1046 // special calling conventions
1047 switch(opcode) {
1048 case ISD::UREM: Opc = Alpha::REMQU; break;
1049 case ISD::SREM: Opc = Alpha::REMQ; break;
1050 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1051 case ISD::SDIV: Opc = Alpha::DIVQ; break;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001052 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001053 Tmp1 = SelectExpr(N.getOperand(0));
1054 Tmp2 = SelectExpr(N.getOperand(1));
Andrew Lenharth02981182005-01-26 01:24:38 +00001055 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001056 return Result;
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001057
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001058 case ISD::FP_TO_UINT:
Andrew Lenharth7efadce2005-01-31 01:44:26 +00001059 case ISD::FP_TO_SINT:
1060 {
1061 assert (DestType == MVT::i64 && "only quads can be loaded to");
1062 MVT::ValueType SrcType = N.getOperand(0).getValueType();
1063 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1064
1065 //The hard way:
1066 // Spill the integer to memory and reload it from there.
1067 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1068 MachineFunction *F = BB->getParent();
1069 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1070
1071 //CVTTQ STT LDQ
1072 //CVTST CVTTQ STT LDQ
1073 if (SrcType == MVT::f32)
1074 {
1075 Tmp2 = MakeReg(MVT::f64);
1076 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1077 Tmp1 = Tmp2;
1078 }
1079 Tmp2 = MakeReg(MVT::f64);
1080 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1081 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1082 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1083
1084 return Result;
1085 }
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001086
1087// // case ISD::FP_TO_UINT:
1088
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001089 case ISD::SELECT:
1090 {
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001091 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001092 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1093 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001094 // Get the condition into the zero flag.
Andrew Lenharthe76797c2005-02-01 20:40:27 +00001095 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001096 return Result;
1097 }
1098
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001099 case ISD::Constant:
1100 {
Andrew Lenharth22d5a412005-02-02 00:51:15 +00001101 unsigned long val = cast<ConstantSDNode>(N)->getValue();
1102 if (val < 32000 && (long)val > -32000)
1103 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
1104 else
1105 {
1106 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1107 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1108 unsigned CPI = CP->getConstantPoolIndex(C);
1109 AlphaLowering.restoreGP(BB);
1110 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CPI);
1111 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001112 return Result;
1113 }
1114
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001115 case ISD::LOAD:
1116 {
1117 // Make sure we generate both values.
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001118 if (Result != notIn)
1119 ExprMap[N.getValue(1)] = notIn; // Generate the token
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001120 else
1121 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1122
1123 SDOperand Chain = N.getOperand(0);
1124 SDOperand Address = N.getOperand(1);
1125
Andrew Lenharthc23d6962005-02-02 04:35:44 +00001126 assert(N.getValue(0).getValueType() == MVT::i64 && "unknown Load dest type");
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001127
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001128 if (Address.getOpcode() == ISD::GlobalAddress)
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001129 {
1130 Select(Chain);
1131 AlphaLowering.restoreGP(BB);
1132 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1133 }
1134 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1135 AlphaLowering.restoreGP(BB);
1136 BuildMI(BB, Alpha::LOAD, 1, Result).addConstantPoolIndex(CP->getIndex());
1137 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001138 else
Andrew Lenharth2afc8212005-02-02 03:36:35 +00001139 {
1140 Select(Chain);
1141 Tmp2 = SelectExpr(Address);
1142 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
1143 }
1144 return Result;
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001145 }
1146 }
1147
1148 return 0;
1149}
1150
1151void ISel::Select(SDOperand N) {
1152 unsigned Tmp1, Tmp2, Opc;
1153
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001154 // FIXME: Disable for our current expansion model!
Andrew Lenharthcc1b16f2005-01-28 23:17:54 +00001155 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001156 return; // Already selected.
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001157
1158 SDNode *Node = N.Val;
1159
1160 switch (N.getOpcode()) {
1161
1162 default:
1163 Node->dump(); std::cerr << "\n";
1164 assert(0 && "Node not handled yet!");
1165
1166 case ISD::BRCOND: {
1167 MachineBasicBlock *Dest =
1168 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
1169
Andrew Lenharth9818c052005-02-05 13:19:12 +00001170 Select(N.getOperand(0)); //chain
1171
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001172 Tmp1 = SelectExpr(N.getOperand(1));
1173 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
1174 return;
1175 }
1176
1177 case ISD::BR: {
1178 MachineBasicBlock *Dest =
1179 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1180
1181 Select(N.getOperand(0));
1182 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1183 return;
1184 }
1185
1186 case ISD::ImplicitDef:
1187 Select(N.getOperand(0));
1188 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1189 return;
1190
1191 case ISD::EntryToken: return; // Noop
1192
1193 case ISD::TokenFactor:
1194 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1195 Select(Node->getOperand(i));
1196
1197 //N.Val->dump(); std::cerr << "\n";
1198 //assert(0 && "Node not handled yet!");
1199
1200 return;
1201
1202 case ISD::CopyToReg:
1203 Select(N.getOperand(0));
1204 Tmp1 = SelectExpr(N.getOperand(1));
1205 Tmp2 = cast<RegSDNode>(N)->getReg();
1206
1207 if (Tmp1 != Tmp2) {
1208 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1209 }
1210 return;
1211
1212 case ISD::RET:
1213 switch (N.getNumOperands()) {
1214 default:
1215 std::cerr << N.getNumOperands() << "\n";
1216 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1217 std::cerr << N.getOperand(i).getValueType() << "\n";
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001218 Node->dump();
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001219 assert(0 && "Unknown return instruction!");
1220 case 2:
1221 Select(N.getOperand(0));
1222 Tmp1 = SelectExpr(N.getOperand(1));
1223 switch (N.getOperand(1).getValueType()) {
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001224 default: Node->dump(); assert(0 && "All other types should have been promoted!!");
1225 case MVT::f64:
1226 case MVT::f32:
1227 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1228 break;
Andrew Lenharth2f8fb772005-01-25 00:35:34 +00001229 case MVT::i32:
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001230 case MVT::i64:
1231 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1232 break;
1233 }
1234 break;
1235 case 1:
1236 Select(N.getOperand(0));
1237 break;
1238 }
1239 //Tmp2 = AlphaLowering.getRetAddr();
1240 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1241 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1242 return;
1243
1244 case ISD::STORE:
Andrew Lenharthb014d3e2005-02-02 17:32:39 +00001245 {
1246 Select(N.getOperand(0));
1247 Tmp1 = SelectExpr(N.getOperand(1)); //value
1248 MVT::ValueType DestType = N.getOperand(1).getValueType();
1249 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
1250 {
1251 AlphaLowering.restoreGP(BB);
1252 if (DestType == MVT::i64) Opc = Alpha::STORE;
1253 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1254 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1255 else assert(0 && "unknown Type in store");
1256 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
1257 }
1258 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(2)))
1259 {
1260 AlphaLowering.restoreGP(BB);
1261 if (DestType == MVT::i64) Opc = Alpha::STORE;
1262 else if (DestType == MVT::f64) Opc = Alpha::STT_SYM;
1263 else if (DestType == MVT::f32) Opc = Alpha::STS_SYM;
1264 else assert(0 && "unknown Type in store");
1265 BuildMI(BB, Opc, 2).addReg(Tmp1).addConstantPoolIndex(CP->getIndex());
1266 }
1267 else
1268 {
1269 Tmp2 = SelectExpr(N.getOperand(2)); //address
1270 if (DestType == MVT::i64) Opc = Alpha::STQ;
1271 else if (DestType == MVT::f64) Opc = Alpha::STT;
1272 else if (DestType == MVT::f32) Opc = Alpha::STS;
1273 else assert(0 && "unknown Type in store");
1274 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
1275 }
1276 return;
1277 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001278
1279 case ISD::EXTLOAD:
1280 case ISD::SEXTLOAD:
1281 case ISD::ZEXTLOAD:
1282 case ISD::LOAD:
1283 case ISD::CopyFromReg:
1284 case ISD::CALL:
1285// case ISD::DYNAMIC_STACKALLOC:
Andrew Lenharth6b9870a2005-01-28 14:06:46 +00001286 ExprMap.erase(N);
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001287 SelectExpr(N);
1288 return;
1289
1290
1291 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
1292 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
Andrew Lenharth3e98fde2005-01-26 21:54:09 +00001293 if (StoredTy == MVT::i64) {
1294 Node->dump();
1295 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
1296 }
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001297
1298 Select(N.getOperand(0));
1299 Tmp1 = SelectExpr(N.getOperand(1));
1300 Tmp2 = SelectExpr(N.getOperand(2));
1301
1302 switch (StoredTy) {
Chris Lattnerd7b59d02005-01-30 16:32:48 +00001303 default: Node->dump(); assert(0 && "Unhandled Type");
Andrew Lenharthd279b412005-01-25 19:58:40 +00001304 case MVT::i1: //FIXME: DAG does not promote this load
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001305 case MVT::i8: Opc = Alpha::STB; break;
1306 case MVT::i16: Opc = Alpha::STW; break;
1307 case MVT::i32: Opc = Alpha::STL; break;
1308 }
1309
1310 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
1311 return;
1312 }
1313
1314 case ISD::ADJCALLSTACKDOWN:
1315 case ISD::ADJCALLSTACKUP:
1316 Select(N.getOperand(0));
1317 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1318
1319 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1320 Alpha::ADJUSTSTACKUP;
1321 BuildMI(BB, Opc, 1).addImm(Tmp1);
1322 return;
1323 }
1324 assert(0 && "Should not be reached!");
1325}
1326
1327
1328/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1329/// into a machine code representation using pattern matching and a machine
1330/// description file.
1331///
1332FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1333 return new ISel(TM);
1334}