blob: 4431d8f57f35e788e58b8db3f4ab0de7d5ba28fc [file] [log] [blame]
Andrew Lenharth304d0f32005-01-22 23:41:55 +00001//===-- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha -----===//
2//
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"
15//#include "X86InstrBuilder.h"
16#include "AlphaRegisterInfo.h"
17#include "llvm/Constants.h" // FIXME: REMOVE
18#include "llvm/Function.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/SelectionDAG.h"
24#include "llvm/CodeGen/SelectionDAGISel.h"
25#include "llvm/CodeGen/SSARegMap.h"
26#include "llvm/Target/TargetData.h"
27#include "llvm/Target/TargetLowering.h"
28#include "llvm/Support/MathExtras.h"
29#include "llvm/ADT/Statistic.h"
30#include <set>
31using 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.
42 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
43 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
44
45 setOperationAction(ISD::EXTLOAD , MVT::i1 , Expand);
46 setOperationAction(ISD::EXTLOAD , MVT::i8 , Expand);
47 setOperationAction(ISD::EXTLOAD , MVT::i16 , Expand);
48 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
49 setOperationAction(ISD::ZEXTLOAD , MVT::i8 , Expand);
50 setOperationAction(ISD::ZEXTLOAD , MVT::i16 , Expand);
51 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
52 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
53 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
54 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
55
56 computeRegisterProperties();
57
58 // setOperationUnsupported(ISD::MUL, MVT::i8);
59 // setOperationUnsupported(ISD::SELECT, MVT::i1);
60 // setOperationUnsupported(ISD::SELECT, MVT::i8);
61
62 // addLegalFPImmediate(+0.0); // FLD0
63 // addLegalFPImmediate(+1.0); // FLD1
64 // addLegalFPImmediate(-0.0); // FLD0/FCHS
65 // addLegalFPImmediate(-1.0); // FLD1/FCHS
66 }
67
68 /// LowerArguments - This hook must be implemented to indicate how we should
69 /// lower the arguments for the specified function, into the specified DAG.
70 virtual std::vector<SDOperand>
71 LowerArguments(Function &F, SelectionDAG &DAG);
72
73 /// LowerCallTo - This hook lowers an abstract call to a function into an
74 /// actual call.
75 virtual std::pair<SDOperand, SDOperand>
76 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
77 ArgListTy &Args, SelectionDAG &DAG);
78
79 virtual std::pair<SDOperand, SDOperand>
80 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
81
82 virtual std::pair<SDOperand,SDOperand>
83 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
84 const Type *ArgTy, SelectionDAG &DAG);
85
86 virtual std::pair<SDOperand, SDOperand>
87 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
88 SelectionDAG &DAG);
89
90 void restoreGP(MachineBasicBlock* BB)
91 {
92 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
93 }
94 };
95}
96
97//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
98
99//For now, just use variable size stack frame format
100
101//In a standard call, the first six items are passed in registers $16
102//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
103//of argument-to-register correspondence.) The remaining items are
104//collected in a memory argument list that is a naturally aligned
105//array of quadwords. In a standard call, this list, if present, must
106//be passed at 0(SP).
107//7 ... n 0(SP) ... (n-7)*8(SP)
108
109std::vector<SDOperand>
110AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
111{
112 std::vector<SDOperand> ArgValues;
113
114 // //#define FP $15
115 // //#define RA $26
116 // //#define PV $27
117 // //#define GP $29
118 // //#define SP $30
119
120 // assert(0 && "TODO");
121 MachineFunction &MF = DAG.getMachineFunction();
122 MachineFrameInfo *MFI = MF.getFrameInfo();
123
124 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
125 MachineBasicBlock& BB = MF.front();
126
127 //Handle the return address
128 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
129
130 unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18,
131 Alpha::R19, Alpha::R20, Alpha::R21};
132 std::vector<unsigned> argVreg;
133
134 int count = 0;
135 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
136 {
137 ++count;
138 assert(count <= 6 && "More than 6 args not supported");
139 assert(getValueType(I->getType()) != MVT::f64 && "No floats yet");
140 BuildMI(&BB, Alpha::IDEF, 0, args[count - 1]);
141 argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
142 }
143
144 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
145 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
146 count = 0;
147 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
148 {
149 BuildMI(&BB, Alpha::BIS, 2, argVreg[count]).addReg(args[count]).addReg(args[count]);
150
151 SDOperand argt, newroot;
152 switch (getValueType(I->getType()))
153 {
154 case MVT::i64:
155 argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
156 break;
157 case MVT::i32:
158 argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i32, DAG.getRoot());
159 break;
160 default:
161 newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
162 argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
163 }
164 DAG.setRoot(newroot.getValue(1));
165 ArgValues.push_back(argt);
166 ++count;
167 }
168 return ArgValues;
169}
170
171std::pair<SDOperand, SDOperand>
172AlphaTargetLowering::LowerCallTo(SDOperand Chain,
173 const Type *RetTy, SDOperand Callee,
174 ArgListTy &Args, SelectionDAG &DAG) {
175 int NumBytes = 0;
176 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
177 DAG.getConstant(NumBytes, getPointerTy()));
178 std::vector<SDOperand> args_to_use;
179 for (unsigned i = 0, e = Args.size(); i != e; ++i)
180 {
181 switch (getValueType(Args[i].second)) {
182 default: assert(0 && "Unexpected ValueType for argument!");
183 case MVT::i1:
184 case MVT::i8:
185 case MVT::i16:
186 case MVT::i32:
187 // Promote the integer to 64 bits. If the input type is signed use a
188 // sign extend, otherwise use a zero extend.
189 if (Args[i].second->isSigned())
190 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
191 else
192 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
193 break;
194 case MVT::i64:
195 break;
196 }
197 args_to_use.push_back(Args[i].first);
198 }
199
200 std::vector<MVT::ValueType> RetVals;
201 MVT::ValueType RetTyVT = getValueType(RetTy);
202 if (RetTyVT != MVT::isVoid)
203 RetVals.push_back(RetTyVT);
204 RetVals.push_back(MVT::Other);
205
206 SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
207 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
208 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
209 DAG.getConstant(NumBytes, getPointerTy()));
210 return std::make_pair(TheCall, Chain);
211}
212
213std::pair<SDOperand, SDOperand>
214AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
215 //vastart just returns the address of the VarArgsFrameIndex slot.
216 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
217}
218
219std::pair<SDOperand,SDOperand> AlphaTargetLowering::
220LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
221 const Type *ArgTy, SelectionDAG &DAG) {
222 abort();
223}
224
225
226std::pair<SDOperand, SDOperand> AlphaTargetLowering::
227LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
228 SelectionDAG &DAG) {
229 abort();
230}
231
232
233
234
235
236namespace {
237
238 //===--------------------------------------------------------------------===//
239 /// ISel - Alpha specific code to select Alpha machine instructions for
240 /// SelectionDAG operations.
241 ///
242 class ISel : public SelectionDAGISel {
243
244 /// AlphaLowering - This object fully describes how to lower LLVM code to an
245 /// Alpha-specific SelectionDAG.
246 AlphaTargetLowering AlphaLowering;
247
248
249 /// ExprMap - As shared expressions are codegen'd, we keep track of which
250 /// vreg the value is produced in, so we only emit one copy of each compiled
251 /// tree.
252 std::map<SDOperand, unsigned> ExprMap;
253 std::set<SDOperand> LoweredTokens;
254
255 public:
256 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
257 }
258
259 /// InstructionSelectBasicBlock - This callback is invoked by
260 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
261 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
262 // Codegen the basic block.
263 Select(DAG.getRoot());
264
265 // Clear state used for selection.
266 ExprMap.clear();
267 LoweredTokens.clear();
268 }
269
270 unsigned SelectExpr(SDOperand N);
271 void Select(SDOperand N);
272 };
273}
274
275unsigned ISel::SelectExpr(SDOperand N) {
276 unsigned Result;
277 unsigned Tmp1, Tmp2, Tmp3;
278 unsigned Opc = 0;
279
280 SDNode *Node = N.Val;
281
282 unsigned &Reg = ExprMap[N];
283 if (Reg) return Reg;
284
285 if (N.getOpcode() != ISD::CALL)
286 Reg = Result = (N.getValueType() != MVT::Other) ?
287 MakeReg(N.getValueType()) : 1;
288 else {
289 // If this is a call instruction, make sure to prepare ALL of the result
290 // values as well as the chain.
291 if (Node->getNumValues() == 1)
292 Reg = Result = 1; // Void call, just a chain.
293 else {
294 Result = MakeReg(Node->getValueType(0));
295 ExprMap[N.getValue(0)] = Result;
296 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
297 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
298 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
299 }
300 }
301
302 switch (N.getOpcode()) {
303 default:
304 Node->dump();
305 assert(0 && "Node not handled!\n");
306
307 case ISD::FrameIndex:
308 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
309 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
310 return Result;
311
312 case ISD::EXTLOAD:
313 case ISD::SEXTLOAD:
314 // Make sure we generate both values.
315 if (Result != 1)
316 ExprMap[N.getValue(1)] = 1; // Generate the token
317 else
318 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
319
320 Select(Node->getOperand(0)); // chain
321 Tmp1 = SelectExpr(Node->getOperand(1));
322 switch(Node->getValueType(0)) {
323 default: assert(0 && "Unknown type to sign extend to.");
324 case MVT::i64:
325 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
326 default:
327 assert(0 && "Bad sign extend!");
328 case MVT::i32:
329 BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
330 break;
331 case MVT::i16:
332 BuildMI(BB, Alpha::LDW, 2, Result).addImm(0).addReg(Tmp1);
333 break;
334 case MVT::i8:
335 BuildMI(BB, Alpha::LDB, 2, Result).addImm(0).addReg(Tmp1);
336 break;
337 }
338 break;
339 }
340 return Result;
341
342 case ISD::GlobalAddress:
343 AlphaLowering.restoreGP(BB);
344 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
345 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
346 return Result;
347
348 case ISD::CALL:
349 {
350 Select(N.getOperand(0));
351
352 // The chain for this call is now lowered.
353 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1));
354
355 //grab the arguments
356 std::vector<unsigned> argvregs;
357 assert(Node->getNumOperands() < 8 && "Only 6 args supported");
358 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
359 {
360 argvregs.push_back(SelectExpr(N.getOperand(i)));
361 }
362 for(int i = 0, e = argvregs.size(); i < e; ++i)
363 {
364 unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18,
365 Alpha::R19, Alpha::R20, Alpha::R21};
366
367 BuildMI(BB, Alpha::BIS, 2, args[i]).addReg(argvregs[i]).addReg(argvregs[i]);
368 }
369
370 //build the right kind of call
371 if (GlobalAddressSDNode *GASD =
372 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
373 {
374 Select(N.getOperand(0));
375 AlphaLowering.restoreGP(BB);
376 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
377 }
378 else if (ExternalSymbolSDNode *ESSDN =
379 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
380 {
381 Select(N.getOperand(0));
382 AlphaLowering.restoreGP(BB);
383 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
384 }
385 else {
386 Select(N.getOperand(0));
387 Tmp1 = SelectExpr(N.getOperand(1));
388 BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1);
389 AlphaLowering.restoreGP(BB);
390 }
391
392 //push the result into a virtual register
393 // if (Result != 1)
394 // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
395
396 switch (Node->getValueType(0)) {
397 default: assert(0 && "Unknown value type for call result!");
398 case MVT::Other: return 1;
399 case MVT::i1:
400 case MVT::i8:
401 case MVT::i16:
402 case MVT::i32:
403 case MVT::i64:
404 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
405 break;
406 }
407 return Result+N.ResNo;
408 }
409
410 case ISD::SIGN_EXTEND:
411 {
412 std::cerr << "DestT: " << N.getValueType() << "\n";
413 std::cerr << "SrcT: " << N.getOperand(0).getValueType() << "\n";
414 assert(0 && "Sign Extend not there yet");
415 return Result;
416 }
417 case ISD::SIGN_EXTEND_INREG:
418 {
419 Tmp1 = SelectExpr(N.getOperand(0));
420 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
421 std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
422 switch(MVN->getExtraValueType())
423 {
424 default:
425 assert(0 && "Sign Extend InReg not there yet");
426 break;
427 case MVT::i32:
428 {
429 Tmp2 = MakeReg(MVT::i64);
430 unsigned Tmp3 = MakeReg(MVT::i64);
431 BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(16);
432 BuildMI(BB, Alpha::SL, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
433 BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp3).addReg(Tmp2);
434 break;
435 }
436 case MVT::i16:
437 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
438 break;
439 case MVT::i8:
440 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
441 break;
442 }
443 return Result;
444 }
445 case ISD::ZERO_EXTEND_INREG:
446 {
447 Tmp1 = SelectExpr(N.getOperand(0));
448 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
449 std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
450 switch(MVN->getExtraValueType())
451 {
452 default:
453 assert(0 && "Zero Extend InReg not there yet");
454 break;
455 case MVT::i32:
456 {
457 Tmp2 = MakeReg(MVT::i64);
458 BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xf0);
459 BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
460 break;
461 }
462 case MVT::i16:
463 Tmp2 = MakeReg(MVT::i64);
464 BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfc);
465 BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
466 break;
467 case MVT::i8:
468 Tmp2 = MakeReg(MVT::i64);
469 BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfe);
470 BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
471 break;
472 }
473 return Result;
474 }
475
476 case ISD::SETCC:
477 Tmp1 = SelectExpr(N.getOperand(0));
478 Tmp2 = SelectExpr(N.getOperand(1));
479 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
480 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
481 switch (SetCC->getCondition()) {
482 default: assert(0 && "Unknown integer comparison!");
483 case ISD::SETEQ:
484 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
485 break;
486 case ISD::SETGT:
487 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp2).addReg(Tmp1);
488 break;
489 case ISD::SETGE:
490 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp2).addReg(Tmp1);
491 break;
492 case ISD::SETLT:
493 BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp1).addReg(Tmp2);
494 break;
495 case ISD::SETLE:
496 BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp1).addReg(Tmp2);
497 break;
498 case ISD::SETNE:
499 {
500 unsigned Tmp3 = MakeReg(MVT::i64);
501 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
502 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp3).addReg(Alpha::R31);
503 break;
504 }
505 case ISD::SETULT:
506 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
507 break;
508 case ISD::SETUGT:
509 BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp2).addReg(Tmp1);
510 break;
511 case ISD::SETULE:
512 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp1).addReg(Tmp2);
513 break;
514 case ISD::SETUGE:
515 BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp2).addReg(Tmp1);
516 break;
517 }
518 }
519 else
520 assert(0 && "only integer");
521 }
522 else
523 assert(0 && "Not a setcc in setcc");
524
525 return Result;
526
527 case ISD::CopyFromReg:
528 {
529 if (Result == 1)
530 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
531
532 SDOperand Chain = N.getOperand(0);
533
534 Select(Chain);
535 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
536 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
537 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
538 return Result;
539 }
540
541 case ISD::ADD:
542 Tmp1 = SelectExpr(N.getOperand(0));
543 Tmp2 = SelectExpr(N.getOperand(1));
544 BuildMI(BB, Alpha::ADDQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
545 return Result;
546 case ISD::SUB:
547 Tmp1 = SelectExpr(N.getOperand(0));
548 Tmp2 = SelectExpr(N.getOperand(1));
549 BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
550 return Result;
551
552 case ISD::AND:
553 Tmp1 = SelectExpr(N.getOperand(0));
554 Tmp2 = SelectExpr(N.getOperand(1));
555 BuildMI(BB, Alpha::AND, 2, Result).addReg(Tmp1).addReg(Tmp2);
556 return Result;
557 case ISD::OR:
558 Tmp1 = SelectExpr(N.getOperand(0));
559 Tmp2 = SelectExpr(N.getOperand(1));
560 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Tmp1).addReg(Tmp2);
561 return Result;
562 case ISD::XOR:
563 Tmp1 = SelectExpr(N.getOperand(0));
564 Tmp2 = SelectExpr(N.getOperand(1));
565 BuildMI(BB, Alpha::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
566 return Result;
567
568 case ISD::MUL:
569 Tmp1 = SelectExpr(N.getOperand(0));
570 Tmp2 = SelectExpr(N.getOperand(1));
571 BuildMI(BB, Alpha::MULQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
572 return Result;
573 case ISD::UREM:
574 Tmp1 = SelectExpr(N.getOperand(0));
575 Tmp2 = SelectExpr(N.getOperand(1));
576 BuildMI(BB, Alpha::REMQU, 2, Result).addReg(Tmp1).addReg(Tmp2);
577 return Result;
578
579 case ISD::SELECT:
580 {
581 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
582 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
583 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
584 // Get the condition into the zero flag.
585 unsigned dummy = MakeReg(MVT::i64);
586 BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
587 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
588 return Result;
589 }
590
591 case ISD::SHL:
592 Tmp1 = SelectExpr(N.getOperand(0));
593 Tmp2 = SelectExpr(N.getOperand(1));
594 BuildMI(BB, Alpha::SL, 2, Result).addReg(Tmp1).addReg(Tmp2);
595 return Result;
596 case ISD::SRL:
597 Tmp1 = SelectExpr(N.getOperand(0));
598 Tmp2 = SelectExpr(N.getOperand(1));
599 BuildMI(BB, Alpha::SRL, 1, Result).addReg(Tmp1).addReg(Tmp2);
600 return Result;
601 case ISD::SRA:
602 Tmp1 = SelectExpr(N.getOperand(0));
603 Tmp2 = SelectExpr(N.getOperand(1));
604 BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp1).addReg(Tmp2);
605 return Result;
606
607 case ISD::Constant:
608 {
609 long val = cast<ConstantSDNode>(N)->getValue();
610 BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
611 return Result;
612 }
613
614
615
616 case ISD::LOAD:
617 {
618 // Make sure we generate both values.
619 if (Result != 1)
620 ExprMap[N.getValue(1)] = 1; // Generate the token
621 else
622 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
623
624 SDOperand Chain = N.getOperand(0);
625 SDOperand Address = N.getOperand(1);
626
627 if (Address.getOpcode() == ISD::GlobalAddress)
628 {
629 Select(Chain);
630 AlphaLowering.restoreGP(BB);
631 BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
632 }
633 else
634 {
635 Select(Chain);
636 Tmp2 = SelectExpr(Address);
637 BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
638 }
639 return Result;
640 }
641 }
642
643 return 0;
644}
645
646void ISel::Select(SDOperand N) {
647 unsigned Tmp1, Tmp2, Opc;
648
649 // FIXME: Disable for our current expansion model!
650 if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
651 return; // Already selected.
652
653 SDNode *Node = N.Val;
654
655 switch (N.getOpcode()) {
656
657 default:
658 Node->dump(); std::cerr << "\n";
659 assert(0 && "Node not handled yet!");
660
661 case ISD::BRCOND: {
662 MachineBasicBlock *Dest =
663 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
664
665 Select(N.getOperand(0));
666 Tmp1 = SelectExpr(N.getOperand(1));
667 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
668 return;
669 }
670
671 case ISD::BR: {
672 MachineBasicBlock *Dest =
673 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
674
675 Select(N.getOperand(0));
676 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
677 return;
678 }
679
680 case ISD::ImplicitDef:
681 Select(N.getOperand(0));
682 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
683 return;
684
685 case ISD::EntryToken: return; // Noop
686
687 case ISD::TokenFactor:
688 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
689 Select(Node->getOperand(i));
690
691 //N.Val->dump(); std::cerr << "\n";
692 //assert(0 && "Node not handled yet!");
693
694 return;
695
696 case ISD::CopyToReg:
697 Select(N.getOperand(0));
698 Tmp1 = SelectExpr(N.getOperand(1));
699 Tmp2 = cast<RegSDNode>(N)->getReg();
700
701 if (Tmp1 != Tmp2) {
702 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
703 }
704 return;
705
706 case ISD::RET:
707 switch (N.getNumOperands()) {
708 default:
709 std::cerr << N.getNumOperands() << "\n";
710 for (unsigned i = 0; i < N.getNumOperands(); ++i)
711 std::cerr << N.getOperand(i).getValueType() << "\n";
712 assert(0 && "Unknown return instruction!");
713 case 2:
714 Select(N.getOperand(0));
715 Tmp1 = SelectExpr(N.getOperand(1));
716 switch (N.getOperand(1).getValueType()) {
717 default: assert(0 && "All other types should have been promoted!!");
718 case MVT::i64:
719 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
720 break;
721 }
722 break;
723 case 1:
724 Select(N.getOperand(0));
725 break;
726 }
727 //Tmp2 = AlphaLowering.getRetAddr();
728 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
729 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
730 return;
731
732 case ISD::STORE:
733 Select(N.getOperand(0));
734 Tmp1 = SelectExpr(N.getOperand(1)); //value
735 if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
736 {
737 AlphaLowering.restoreGP(BB);
738 BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
739 }
740 else
741 {
742 Tmp2 = SelectExpr(N.getOperand(2)); //address
743 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
744 }
745 return;
746
747 case ISD::EXTLOAD:
748 case ISD::SEXTLOAD:
749 case ISD::ZEXTLOAD:
750 case ISD::LOAD:
751 case ISD::CopyFromReg:
752 case ISD::CALL:
753// case ISD::DYNAMIC_STACKALLOC:
754 SelectExpr(N);
755 return;
756
757
758 case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety
759 MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
760 assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
761
762 Select(N.getOperand(0));
763 Tmp1 = SelectExpr(N.getOperand(1));
764 Tmp2 = SelectExpr(N.getOperand(2));
765
766 switch (StoredTy) {
767 default: assert(0 && "Unhandled Type"); break;
768 case MVT::i8: Opc = Alpha::STB; break;
769 case MVT::i16: Opc = Alpha::STW; break;
770 case MVT::i32: Opc = Alpha::STL; break;
771 }
772
773 BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
774 return;
775 }
776
777 case ISD::ADJCALLSTACKDOWN:
778 case ISD::ADJCALLSTACKUP:
779 Select(N.getOperand(0));
780 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
781
782 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
783 Alpha::ADJUSTSTACKUP;
784 BuildMI(BB, Opc, 1).addImm(Tmp1);
785 return;
786 }
787 assert(0 && "Should not be reached!");
788}
789
790
791/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
792/// into a machine code representation using pattern matching and a machine
793/// description file.
794///
795FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
796 return new ISel(TM);
797}