1 //===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file defines a pattern matching instruction selector for Alpha.
12 //===----------------------------------------------------------------------===//
15 #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 "llvm/Support/Debug.h"
34 //===----------------------------------------------------------------------===//
35 // AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
37 class AlphaTargetLowering : public TargetLowering {
38 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
39 unsigned GP; //GOT vreg
41 AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
42 // Set up the TargetLowering object.
43 //I am having problems with shr n ubyte 1
44 setShiftAmountType(MVT::i64);
45 setSetCCResultType(MVT::i64);
47 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
48 addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
49 addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);
51 setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote);
52 setOperationAction(ISD::EXTLOAD , MVT::f32 , Promote);
54 setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand);
55 setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand);
57 setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand);
58 setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
59 setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
61 setOperationAction(ISD::SREM , MVT::f32 , Expand);
62 setOperationAction(ISD::SREM , MVT::f64 , Expand);
64 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
65 setOperationAction(ISD::MEMSET , MVT::Other, Expand);
66 setOperationAction(ISD::MEMCPY , MVT::Other, Expand);
69 setOperationAction(ISD::SETCC , MVT::f32, Promote);
71 computeRegisterProperties();
73 addLegalFPImmediate(+0.0); //F31
74 addLegalFPImmediate(-0.0); //-F31
77 /// LowerArguments - This hook must be implemented to indicate how we should
78 /// lower the arguments for the specified function, into the specified DAG.
79 virtual std::vector<SDOperand>
80 LowerArguments(Function &F, SelectionDAG &DAG);
82 /// LowerCallTo - This hook lowers an abstract call to a function into an
84 virtual std::pair<SDOperand, SDOperand>
85 LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
86 ArgListTy &Args, SelectionDAG &DAG);
88 virtual std::pair<SDOperand, SDOperand>
89 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
91 virtual std::pair<SDOperand,SDOperand>
92 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
93 const Type *ArgTy, SelectionDAG &DAG);
95 virtual std::pair<SDOperand, SDOperand>
96 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
99 void restoreGP(MachineBasicBlock* BB)
101 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
106 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
108 //For now, just use variable size stack frame format
110 //In a standard call, the first six items are passed in registers $16
111 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
112 //of argument-to-register correspondence.) The remaining items are
113 //collected in a memory argument list that is a naturally aligned
114 //array of quadwords. In a standard call, this list, if present, must
115 //be passed at 0(SP).
116 //7 ... n 0(SP) ... (n-7)*8(SP)
118 std::vector<SDOperand>
119 AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
121 std::vector<SDOperand> ArgValues;
129 // assert(0 && "TODO");
130 MachineFunction &MF = DAG.getMachineFunction();
131 MachineFrameInfo*MFI = MF.getFrameInfo();
133 GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
134 MachineBasicBlock& BB = MF.front();
136 //Handle the return address
137 //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
139 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
140 Alpha::R19, Alpha::R20, Alpha::R21};
141 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
142 Alpha::F19, Alpha::F20, Alpha::F21};
149 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
151 SDOperand newroot, argt;
153 switch (getValueType(I->getType())) {
155 std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n";
159 BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
161 MF.getSSARegMap()->createVirtualRegister(
162 getRegClassFor(getValueType(I->getType())));
163 argPreg[count] = args_float[count];
164 argOpc[count] = Alpha::CPYS;
165 argt = newroot = DAG.getCopyFromReg(argVreg[count],
166 getValueType(I->getType()),
174 BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
176 MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
177 argPreg[count] = args_int[count];
178 argOpc[count] = Alpha::BIS;
180 DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
181 if (getValueType(I->getType()) != MVT::i64)
183 DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
187 // Create the frame index object for this incoming parameter...
188 int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
190 // Create the SelectionDAG nodes corresponding to a load
191 //from this parameter
192 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
193 argt = newroot = DAG.getLoad(getValueType(I->getType()),
194 DAG.getEntryNode(), FIN);
197 DAG.setRoot(newroot.getValue(1));
198 ArgValues.push_back(argt);
201 BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
202 BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
203 for (int i = 0; i < count && i < 6; ++i) {
204 BuildMI(&BB, argOpc[i], 2,
205 argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
211 std::pair<SDOperand, SDOperand>
212 AlphaTargetLowering::LowerCallTo(SDOperand Chain,
213 const Type *RetTy, SDOperand Callee,
214 ArgListTy &Args, SelectionDAG &DAG) {
217 NumBytes = (Args.size() - 6) * 8;
219 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
220 DAG.getConstant(NumBytes, getPointerTy()));
221 std::vector<SDOperand> args_to_use;
222 for (unsigned i = 0, e = Args.size(); i != e; ++i)
224 switch (getValueType(Args[i].second)) {
225 default: assert(0 && "Unexpected ValueType for argument!");
230 // Promote the integer to 64 bits. If the input type is signed use a
231 // sign extend, otherwise use a zero extend.
232 if (Args[i].second->isSigned())
233 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
235 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
242 args_to_use.push_back(Args[i].first);
245 std::vector<MVT::ValueType> RetVals;
246 MVT::ValueType RetTyVT = getValueType(RetTy);
247 if (RetTyVT != MVT::isVoid)
248 RetVals.push_back(RetTyVT);
249 RetVals.push_back(MVT::Other);
251 SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
252 Chain, Callee, args_to_use), 0);
253 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
254 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
255 DAG.getConstant(NumBytes, getPointerTy()));
256 return std::make_pair(TheCall, Chain);
259 std::pair<SDOperand, SDOperand>
260 AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
261 //vastart just returns the address of the VarArgsFrameIndex slot.
262 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
265 std::pair<SDOperand,SDOperand> AlphaTargetLowering::
266 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
267 const Type *ArgTy, SelectionDAG &DAG) {
272 std::pair<SDOperand, SDOperand> AlphaTargetLowering::
273 LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
284 //===--------------------------------------------------------------------===//
285 /// ISel - Alpha specific code to select Alpha machine instructions for
286 /// SelectionDAG operations.
287 //===--------------------------------------------------------------------===//
288 class ISel : public SelectionDAGISel {
290 /// AlphaLowering - This object fully describes how to lower LLVM code to an
291 /// Alpha-specific SelectionDAG.
292 AlphaTargetLowering AlphaLowering;
295 /// ExprMap - As shared expressions are codegen'd, we keep track of which
296 /// vreg the value is produced in, so we only emit one copy of each compiled
298 static const unsigned notIn = (unsigned)(-1);
299 std::map<SDOperand, unsigned> ExprMap;
301 //CCInvMap sometimes (SetNE) we have the inverse CC code for free
302 std::map<SDOperand, unsigned> CCInvMap;
305 ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
308 /// InstructionSelectBasicBlock - This callback is invoked by
309 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
310 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
312 // Codegen the basic block.
313 Select(DAG.getRoot());
315 // Clear state used for selection.
320 unsigned SelectExpr(SDOperand N);
321 unsigned SelectExprFP(SDOperand N, unsigned Result);
322 void Select(SDOperand N);
324 void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
325 void SelectBranchCC(SDOperand N);
329 //These describe LDAx
330 static const int64_t IMM_LOW = 0xffffffffffff8000LL;
331 static const int IMM_HIGH = 0x0000000000007fffLL;
332 static const int IMM_MULT = 65536;
334 static long getUpper16(long l)
336 long y = l / IMM_MULT;
337 if (l % IMM_MULT > IMM_HIGH)
342 static long getLower16(long l)
344 long h = getUpper16(l);
345 return l - h * IMM_MULT;
348 static unsigned GetSymVersion(unsigned opcode)
351 default: assert(0 && "unknown load or store"); return 0;
352 case Alpha::LDQ: return Alpha::LDQ_SYM;
353 case Alpha::LDS: return Alpha::LDS_SYM;
354 case Alpha::LDT: return Alpha::LDT_SYM;
355 case Alpha::LDL: return Alpha::LDL_SYM;
356 case Alpha::LDBU: return Alpha::LDBU_SYM;
357 case Alpha::LDWU: return Alpha::LDWU_SYM;
358 case Alpha::LDW: return Alpha::LDW_SYM;
359 case Alpha::LDB: return Alpha::LDB_SYM;
360 case Alpha::STQ: return Alpha::STQ_SYM;
361 case Alpha::STS: return Alpha::STS_SYM;
362 case Alpha::STT: return Alpha::STT_SYM;
363 case Alpha::STL: return Alpha::STL_SYM;
364 case Alpha::STW: return Alpha::STW_SYM;
365 case Alpha::STB: return Alpha::STB_SYM;
369 //Check to see if the load is a constant offset from a base register
370 void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
372 unsigned opcode = N.getOpcode();
373 if (opcode == ISD::ADD) {
374 if(N.getOperand(1).getOpcode() == ISD::Constant &&
375 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
377 Reg = SelectExpr(N.getOperand(0));
378 offset = cast<ConstantSDNode>(N.getOperand(1))->getValue();
381 else if(N.getOperand(0).getOpcode() == ISD::Constant &&
382 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 32767)
384 Reg = SelectExpr(N.getOperand(1));
385 offset = cast<ConstantSDNode>(N.getOperand(0))->getValue();
394 void ISel::SelectBranchCC(SDOperand N)
396 assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
397 MachineBasicBlock *Dest =
398 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
399 unsigned Opc = Alpha::WTF;
401 Select(N.getOperand(0)); //chain
402 SDOperand CC = N.getOperand(1);
404 if (CC.getOpcode() == ISD::SETCC)
406 SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
407 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
408 //Dropping the CC is only useful if we are comparing to 0
409 bool isZero0 = false;
410 bool isZero1 = false;
413 if(SetCC->getOperand(0).getOpcode() == ISD::Constant &&
414 cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
416 if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
417 cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
419 if(SetCC->getCondition() == ISD::SETNE)
423 switch (SetCC->getCondition()) {
424 default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
425 case ISD::SETEQ: Opc = Alpha::BEQ; break;
426 case ISD::SETLT: Opc = Alpha::BGT; break;
427 case ISD::SETLE: Opc = Alpha::BGE; break;
428 case ISD::SETGT: Opc = Alpha::BLT; break;
429 case ISD::SETGE: Opc = Alpha::BLE; break;
430 case ISD::SETULT: Opc = Alpha::BNE; break;
431 case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break;
432 case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break;
433 case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC
434 case ISD::SETNE: Opc = Alpha::BNE; break;
436 unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
437 BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
439 } else if (isZero1) {
440 switch (SetCC->getCondition()) {
441 default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
442 case ISD::SETEQ: Opc = Alpha::BEQ; break;
443 case ISD::SETLT: Opc = Alpha::BLT; break;
444 case ISD::SETLE: Opc = Alpha::BLE; break;
445 case ISD::SETGT: Opc = Alpha::BGT; break;
446 case ISD::SETGE: Opc = Alpha::BGE; break;
447 case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
448 case ISD::SETUGT: Opc = Alpha::BNE; break;
449 case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
450 case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
451 case ISD::SETNE: Opc = Alpha::BNE; break;
453 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
454 BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
457 unsigned Tmp1 = SelectExpr(CC);
459 BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
461 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
465 //Any comparison between 2 values should be codegened as an folded branch, as moving
466 //CC to the integer register is very expensive
467 //for a cmp b: c = a - b;
472 bool invTest = false;
475 ConstantFPSDNode *CN;
476 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
477 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
478 Tmp3 = SelectExpr(SetCC->getOperand(0));
479 else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
480 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
482 Tmp3 = SelectExpr(SetCC->getOperand(1));
487 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
488 unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
489 bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
490 Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
491 BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
492 .addReg(Tmp1).addReg(Tmp2);
495 switch (SetCC->getCondition()) {
496 default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
497 case ISD::SETEQ: Opc = invTest ? Alpha::FBNE : Alpha::FBEQ; break;
498 case ISD::SETLT: Opc = invTest ? Alpha::FBGT : Alpha::FBLT; break;
499 case ISD::SETLE: Opc = invTest ? Alpha::FBGE : Alpha::FBLE; break;
500 case ISD::SETGT: Opc = invTest ? Alpha::FBLT : Alpha::FBGT; break;
501 case ISD::SETGE: Opc = invTest ? Alpha::FBLE : Alpha::FBGE; break;
502 case ISD::SETNE: Opc = invTest ? Alpha::FBEQ : Alpha::FBNE; break;
504 BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
507 abort(); //Should never be reached
509 //Giveup and do the stupid thing
510 unsigned Tmp1 = SelectExpr(CC);
511 BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
514 abort(); //Should never be reached
517 unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
519 unsigned Tmp1, Tmp2, Tmp3;
521 SDNode *Node = N.Val;
522 MVT::ValueType DestType = N.getValueType();
523 unsigned opcode = N.getOpcode();
528 assert(0 && "Node not handled!\n");
532 //Tmp1 = SelectExpr(N.getOperand(0)); //Cond
533 unsigned TV = SelectExpr(N.getOperand(1)); //Use if TRUE
534 unsigned FV = SelectExpr(N.getOperand(2)); //Use if FALSE
536 SDOperand CC = N.getOperand(0);
537 SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
539 if (CC.getOpcode() == ISD::SETCC &&
540 !MVT::isInteger(SetCC->getOperand(0).getValueType()))
541 { //FP Setcc -> Select yay!
544 //for a cmp b: c = a - b;
549 bool invTest = false;
552 ConstantFPSDNode *CN;
553 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
554 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
555 Tmp3 = SelectExpr(SetCC->getOperand(0));
556 else if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
557 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
559 Tmp3 = SelectExpr(SetCC->getOperand(1));
564 unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
565 unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
566 bool isD = SetCC->getOperand(0).getValueType() == MVT::f64;
567 Tmp3 = MakeReg(isD ? MVT::f64 : MVT::f32);
568 BuildMI(BB, isD ? Alpha::SUBT : Alpha::SUBS, 2, Tmp3)
569 .addReg(Tmp1).addReg(Tmp2);
572 switch (SetCC->getCondition()) {
573 default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
574 case ISD::SETEQ: Opc = invTest ? Alpha::FCMOVNE : Alpha::FCMOVEQ; break;
575 case ISD::SETLT: Opc = invTest ? Alpha::FCMOVGT : Alpha::FCMOVLT; break;
576 case ISD::SETLE: Opc = invTest ? Alpha::FCMOVGE : Alpha::FCMOVLE; break;
577 case ISD::SETGT: Opc = invTest ? Alpha::FCMOVLT : Alpha::FCMOVGT; break;
578 case ISD::SETGE: Opc = invTest ? Alpha::FCMOVLE : Alpha::FCMOVGE; break;
579 case ISD::SETNE: Opc = invTest ? Alpha::FCMOVEQ : Alpha::FCMOVNE; break;
581 BuildMI(BB, Opc, 3, Result).addReg(FV).addReg(TV).addReg(Tmp3);
586 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
587 // Spill the cond to memory and reload it from there.
588 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
589 MachineFunction *F = BB->getParent();
590 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
591 unsigned Tmp4 = MakeReg(MVT::f64);
592 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
593 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
594 //now ideally, we don't have to do anything to the flag...
595 // Get the condition into the zero flag.
596 BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4);
602 assert (DestType == MVT::f32 &&
603 N.getOperand(0).getValueType() == MVT::f64 &&
604 "only f64 to f32 conversion supported here");
605 Tmp1 = SelectExpr(N.getOperand(0));
606 BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
610 assert (DestType == MVT::f64 &&
611 N.getOperand(0).getValueType() == MVT::f32 &&
612 "only f32 to f64 conversion supported here");
613 Tmp1 = SelectExpr(N.getOperand(0));
614 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
617 case ISD::CopyFromReg:
619 // Make sure we generate both values.
621 ExprMap[N.getValue(1)] = notIn; // Generate the token
623 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
625 SDOperand Chain = N.getOperand(0);
628 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
629 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
630 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r);
636 // Make sure we generate both values.
638 ExprMap[N.getValue(1)] = notIn; // Generate the token
640 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
642 DestType = N.getValue(0).getValueType();
644 SDOperand Chain = N.getOperand(0);
645 SDOperand Address = N.getOperand(1);
647 Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
649 if (Address.getOpcode() == ISD::GlobalAddress) {
650 AlphaLowering.restoreGP(BB);
651 Opc = GetSymVersion(Opc);
652 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
654 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
655 AlphaLowering.restoreGP(BB);
656 Opc = GetSymVersion(Opc);
657 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
659 else if(Address.getOpcode() == ISD::FrameIndex) {
660 BuildMI(BB, Opc, 2, Result)
661 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
665 SelectAddr(Address, Tmp1, offset);
666 BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
670 case ISD::ConstantFP:
671 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
672 if (CN->isExactlyValue(+0.0)) {
673 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
674 } else if ( CN->isExactlyValue(-0.0)) {
675 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Alpha::F31);
687 case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break;
688 case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break;
689 case ISD::SUB: Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS; break;
690 case ISD::SDIV: Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS; break;
693 ConstantFPSDNode *CN;
694 if (opcode == ISD::SUB
695 && (CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
696 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
698 Tmp2 = SelectExpr(N.getOperand(1));
699 BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2);
701 Tmp1 = SelectExpr(N.getOperand(0));
702 Tmp2 = SelectExpr(N.getOperand(1));
703 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
709 //include a conversion sequence for float loads to double
711 ExprMap[N.getValue(1)] = notIn; // Generate the token
713 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
715 Tmp1 = MakeReg(MVT::f32);
717 assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 &&
718 "EXTLOAD not from f32");
719 assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
721 SDOperand Chain = N.getOperand(0);
722 SDOperand Address = N.getOperand(1);
725 if (Address.getOpcode() == ISD::GlobalAddress) {
726 AlphaLowering.restoreGP(BB);
727 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
729 else if (ConstantPoolSDNode *CP =
730 dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
732 AlphaLowering.restoreGP(BB);
733 BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
735 else if(Address.getOpcode() == ISD::FrameIndex) {
736 Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
737 BuildMI(BB, Alpha::LDS, 2, Tmp1)
738 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
742 SelectAddr(Address, Tmp2, offset);
743 BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2);
745 BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
749 case ISD::UINT_TO_FP:
750 case ISD::SINT_TO_FP:
752 assert (N.getOperand(0).getValueType() == MVT::i64
753 && "only quads can be loaded from");
754 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
755 Tmp2 = MakeReg(MVT::f64);
758 // Spill the integer to memory and reload it from there.
759 unsigned Size = MVT::getSizeInBits(MVT::i64)/8;
760 MachineFunction *F = BB->getParent();
761 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
763 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31);
764 BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
765 Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
766 BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
768 //The easy way: doesn't work
769 // //so these instructions are not supported on ev56
770 // Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
771 // BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
772 // Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
773 // BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
778 assert(0 && "should not get here");
782 unsigned ISel::SelectExpr(SDOperand N) {
784 unsigned Tmp1, Tmp2, Tmp3;
786 unsigned opcode = N.getOpcode();
788 SDNode *Node = N.Val;
789 MVT::ValueType DestType = N.getValueType();
791 unsigned &Reg = ExprMap[N];
794 if (N.getOpcode() != ISD::CALL)
795 Reg = Result = (N.getValueType() != MVT::Other) ?
796 MakeReg(N.getValueType()) : notIn;
798 // If this is a call instruction, make sure to prepare ALL of the result
799 // values as well as the chain.
800 if (Node->getNumValues() == 1)
801 Reg = Result = notIn; // Void call, just a chain.
803 Result = MakeReg(Node->getValueType(0));
804 ExprMap[N.getValue(0)] = Result;
805 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
806 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
807 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = notIn;
811 if (DestType == MVT::f64 || DestType == MVT::f32 ||
813 (opcode == ISD::LOAD || opcode == ISD::CopyFromReg ||
814 opcode == ISD::EXTLOAD) &&
815 (N.getValue(0).getValueType() == MVT::f32 ||
816 N.getValue(0).getValueType() == MVT::f64)
819 return SelectExprFP(N, Result);
824 assert(0 && "Node not handled!\n");
826 case ISD::DYNAMIC_STACKALLOC:
827 // Generate both result values.
829 ExprMap[N.getValue(1)] = notIn; // Generate the token
831 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
833 // FIXME: We are currently ignoring the requested alignment for handling
834 // greater than the stack alignment. This will need to be revisited at some
835 // point. Align = N.getOperand(2);
837 if (!isa<ConstantSDNode>(N.getOperand(2)) ||
838 cast<ConstantSDNode>(N.getOperand(2))->getValue() != 0) {
839 std::cerr << "Cannot allocate stack object with greater alignment than"
840 << " the stack alignment yet!";
844 Select(N.getOperand(0));
845 if (ConstantSDNode* CN = dyn_cast<ConstantSDNode>(N.getOperand(1)))
847 if (CN->getValue() < 32000)
849 BuildMI(BB, Alpha::LDA, 2, Alpha::R30)
850 .addImm(-CN->getValue()).addReg(Alpha::R30);
852 Tmp1 = SelectExpr(N.getOperand(1));
853 // Subtract size from stack pointer, thereby allocating some space.
854 BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
857 Tmp1 = SelectExpr(N.getOperand(1));
858 // Subtract size from stack pointer, thereby allocating some space.
859 BuildMI(BB, Alpha::SUBQ, 2, Alpha::R30).addReg(Alpha::R30).addReg(Tmp1);
862 // Put a pointer to the space into the result register, by copying the stack
864 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R30).addReg(Alpha::R30);
867 // case ISD::ConstantPool:
868 // Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
869 // AlphaLowering.restoreGP(BB);
870 // BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(Tmp1);
873 case ISD::FrameIndex:
874 BuildMI(BB, Alpha::LDA, 2, Result)
875 .addFrameIndex(cast<FrameIndexSDNode>(N)->getIndex())
884 // Make sure we generate both values.
886 ExprMap[N.getValue(1)] = notIn; // Generate the token
888 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
890 SDOperand Chain = N.getOperand(0);
891 SDOperand Address = N.getOperand(1);
894 assert(Node->getValueType(0) == MVT::i64 &&
895 "Unknown type to sign extend to.");
896 if (opcode == ISD::LOAD)
899 switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
900 default: Node->dump(); assert(0 && "Bad sign extend!");
901 case MVT::i32: Opc = Alpha::LDL;
902 assert(opcode != ISD::ZEXTLOAD && "Not sext"); break;
903 case MVT::i16: Opc = Alpha::LDWU;
904 assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
905 case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
906 case MVT::i8: Opc = Alpha::LDBU;
907 assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
910 if (Address.getOpcode() == ISD::GlobalAddress) {
911 AlphaLowering.restoreGP(BB);
912 Opc = GetSymVersion(Opc);
913 BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
915 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
916 AlphaLowering.restoreGP(BB);
917 Opc = GetSymVersion(Opc);
918 BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
920 else if(Address.getOpcode() == ISD::FrameIndex) {
921 BuildMI(BB, Opc, 2, Result)
922 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
926 SelectAddr(Address, Tmp1, offset);
927 BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
932 case ISD::GlobalAddress:
933 AlphaLowering.restoreGP(BB);
934 BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
935 .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
940 Select(N.getOperand(0));
942 // The chain for this call is now lowered.
943 ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), notIn));
946 std::vector<unsigned> argvregs;
947 //assert(Node->getNumOperands() < 8 && "Only 6 args supported");
948 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
949 argvregs.push_back(SelectExpr(N.getOperand(i)));
952 for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i)
954 unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18,
955 Alpha::R19, Alpha::R20, Alpha::R21};
956 unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18,
957 Alpha::F19, Alpha::F20, Alpha::F21};
958 switch(N.getOperand(i+2).getValueType()) {
961 N.getOperand(i).Val->dump();
962 std::cerr << "Type for " << i << " is: " <<
963 N.getOperand(i+2).getValueType() << "\n";
964 assert(0 && "Unknown value type for call");
970 BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]);
974 BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]);
979 for (int i = 6, e = argvregs.size(); i < e; ++i)
981 switch(N.getOperand(i+2).getValueType()) {
984 N.getOperand(i).Val->dump();
985 std::cerr << "Type for " << i << " is: " <<
986 N.getOperand(i+2).getValueType() << "\n";
987 assert(0 && "Unknown value type for call");
993 BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
996 BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
999 BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30);
1003 //build the right kind of call
1004 if (GlobalAddressSDNode *GASD =
1005 dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
1007 //if (GASD->getGlobal()->isExternal()) {
1008 //use safe calling convention
1009 AlphaLowering.restoreGP(BB);
1010 BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
1012 //use PC relative branch call
1013 //BuildMI(BB, Alpha::BSR, 1, Alpha::R26).addGlobalAddress(GASD->getGlobal(),true);
1016 else if (ExternalSymbolSDNode *ESSDN =
1017 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
1019 AlphaLowering.restoreGP(BB);
1020 BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
1022 //no need to restore GP as we are doing an indirect call
1023 Tmp1 = SelectExpr(N.getOperand(1));
1024 BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
1025 BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0);
1028 //push the result into a virtual register
1030 switch (Node->getValueType(0)) {
1031 default: Node->dump(); assert(0 && "Unknown value type for call result!");
1032 case MVT::Other: return notIn;
1038 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
1042 BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0);
1045 return Result+N.ResNo;
1048 case ISD::SIGN_EXTEND:
1051 case ISD::SIGN_EXTEND_INREG:
1053 //do SDIV opt for all levels of ints
1054 if (N.getOperand(0).getOpcode() == ISD::SDIV)
1056 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1057 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1058 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1059 MachineFunction *F = BB->getParent();
1060 int FrameIdxL = F->getFrameInfo()->CreateStackObject(Size, 8);
1061 int FrameIdxR = F->getFrameInfo()->CreateStackObject(Size, 8);
1062 int FrameIdxF = F->getFrameInfo()->CreateStackObject(Size, 8);
1063 unsigned Tmp4 = MakeReg(MVT::f64);
1064 unsigned Tmp5 = MakeReg(MVT::f64);
1065 unsigned Tmp6 = MakeReg(MVT::f64);
1066 unsigned Tmp7 = MakeReg(MVT::f64);
1067 unsigned Tmp8 = MakeReg(MVT::f64);
1068 unsigned Tmp9 = MakeReg(MVT::f64);
1070 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxL).addReg(Alpha::F31);
1071 BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxR).addReg(Alpha::F31);
1072 BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdxL).addReg(Alpha::F31);
1073 BuildMI(BB, Alpha::LDT, 2, Tmp5).addFrameIndex(FrameIdxR).addReg(Alpha::F31);
1074 BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4);
1075 BuildMI(BB, Alpha::CVTQT, 1, Tmp7).addReg(Tmp5);
1076 BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7);
1077 BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8);
1078 BuildMI(BB, Alpha::STT, 3).addReg(Tmp9).addFrameIndex(FrameIdxF).addReg(Alpha::F31);
1079 BuildMI(BB, Alpha::LDQ, 3).addReg(Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31);
1083 //Alpha has instructions for a bunch of signed 32 bit stuff
1084 if( dyn_cast<MVTSDNode>(Node)->getExtraValueType() == MVT::i32)
1086 switch (N.getOperand(0).getOpcode()) {
1091 bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD;
1092 bool isMul = N.getOperand(0).getOpcode() == ISD::MUL;
1093 //FIXME: first check for Scaled Adds and Subs!
1094 if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
1095 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue() <= 255)
1096 { //Normal imm add/sub
1097 Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi);
1098 //if the value was really originally a i32, skip the up conversion
1099 if (N.getOperand(0).getOperand(0).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1100 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(0).Val)
1101 ->getExtraValueType() == MVT::i32)
1102 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
1104 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1105 Tmp2 = cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getValue();
1106 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1110 Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL);
1111 //if the value was really originally a i32, skip the up conversion
1112 if (N.getOperand(0).getOperand(0).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1113 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(0).Val)
1114 ->getExtraValueType() == MVT::i32)
1115 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
1117 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1118 //if the value was really originally a i32, skip the up conversion
1119 if (N.getOperand(0).getOperand(1).getOpcode() == ISD::SIGN_EXTEND_INREG &&
1120 dyn_cast<MVTSDNode>(N.getOperand(0).getOperand(1).Val)
1121 ->getExtraValueType() == MVT::i32)
1122 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
1124 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1126 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1127 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1128 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1133 //SelectionDag isn't deleting the signextend after sextloads
1134 Reg = Result = SelectExpr(N.getOperand(0));
1136 default: break; //Fall Though;
1138 } //Every thing else fall though too, including unhandled opcodes above
1139 Tmp1 = SelectExpr(N.getOperand(0));
1140 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
1141 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
1142 switch(MVN->getExtraValueType())
1146 assert(0 && "Sign Extend InReg not there yet");
1150 BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0);
1154 BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
1157 BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
1160 Tmp2 = MakeReg(MVT::i64);
1161 BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1);
1162 BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::F31).addReg(Tmp2);
1167 case ISD::ZERO_EXTEND_INREG:
1169 Tmp1 = SelectExpr(N.getOperand(0));
1170 MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
1171 //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
1172 switch(MVN->getExtraValueType())
1176 assert(0 && "Zero Extend InReg not there yet");
1178 case MVT::i32: Tmp2 = 0xf0; break;
1179 case MVT::i16: Tmp2 = 0xfc; break;
1180 case MVT::i8: Tmp2 = 0xfe; break;
1181 case MVT::i1: //handle this one special
1182 BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1);
1185 BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2);
1191 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
1192 if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
1193 bool isConst1 = false;
1194 bool isConst2 = false;
1197 //Tmp1 = SelectExpr(N.getOperand(0));
1198 if(N.getOperand(0).getOpcode() == ISD::Constant &&
1199 cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 255)
1201 if(N.getOperand(1).getOpcode() == ISD::Constant &&
1202 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1205 switch (SetCC->getCondition()) {
1206 default: Node->dump(); assert(0 && "Unknown integer comparison!");
1207 case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
1209 Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
1211 Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
1213 Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
1215 Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
1217 Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
1219 Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
1221 Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
1223 Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
1224 case ISD::SETNE: {//Handle this one special
1225 //std::cerr << "Alpha does not have a setne.\n";
1227 Tmp1 = SelectExpr(N.getOperand(0));
1228 Tmp2 = SelectExpr(N.getOperand(1));
1229 Tmp3 = MakeReg(MVT::i64);
1230 BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
1231 //Remeber we have the Inv for this CC
1234 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
1239 Tmp1 = SelectExpr(N.getOperand(0));
1241 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1242 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1244 Tmp2 = SelectExpr(N.getOperand(1));
1245 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1247 } else if (dir == 2) {
1248 Tmp1 = SelectExpr(N.getOperand(1));
1250 Tmp2 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
1251 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1253 Tmp2 = SelectExpr(N.getOperand(0));
1254 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1258 Tmp1 = cast<ConstantSDNode>(N.getOperand(0))->getValue();
1259 Tmp2 = SelectExpr(N.getOperand(1));
1260 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp2).addImm(Tmp1);
1261 } else if (isConst2) {
1262 Tmp1 = SelectExpr(N.getOperand(0));
1263 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1264 BuildMI(BB, Alpha::CMPEQi, 2, Result).addReg(Tmp1).addImm(Tmp2);
1266 Tmp1 = SelectExpr(N.getOperand(0));
1267 Tmp2 = SelectExpr(N.getOperand(1));
1268 BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
1272 //assert(SetCC->getOperand(0).getValueType() != MVT::f32 && "SetCC f32 should have been promoted");
1276 switch (SetCC->getCondition()) {
1277 default: Node->dump(); assert(0 && "Unknown FP comparison!");
1278 case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
1279 case ISD::SETLT: Opc = Alpha::CMPTLT; break;
1280 case ISD::SETLE: Opc = Alpha::CMPTLE; break;
1281 case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
1282 case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
1283 case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
1286 //FIXME: check for constant 0.0
1287 ConstantFPSDNode *CN;
1288 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(0)))
1289 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
1292 Tmp1 = SelectExpr(N.getOperand(0));
1294 if ((CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
1295 && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
1298 Tmp2 = SelectExpr(N.getOperand(1));
1300 //Can only compare doubles, and dag won't promote for me
1301 if (SetCC->getOperand(0).getValueType() == MVT::f32)
1303 //assert(0 && "Setcc On float?\n");
1304 std::cerr << "Setcc on float!\n";
1305 Tmp3 = MakeReg(MVT::f64);
1306 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1);
1309 if (SetCC->getOperand(1).getValueType() == MVT::f32)
1311 //assert (0 && "Setcc On float?\n");
1312 std::cerr << "Setcc on float!\n";
1313 Tmp3 = MakeReg(MVT::f64);
1314 BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2);
1318 if (rev) std::swap(Tmp1, Tmp2);
1319 Tmp3 = MakeReg(MVT::f64);
1321 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
1323 //now arrange for Result (int) to have a 1 or 0
1324 unsigned Tmp4 = MakeReg(MVT::i64);
1325 BuildMI(BB, Alpha::ADDQi, 2, Tmp4).addReg(Alpha::R31).addImm(1);
1326 Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP;
1327 BuildMI(BB, Opc, 3, Result).addReg(Tmp4).addImm(0).addReg(Tmp3);
1328 // Opc = inv?Alpha::CC2INT_INV:Alpha::CC2INT;
1329 // BuildMI(BB, Opc, 1, Result).addReg(Tmp3);
1331 // // Spill the FP to memory and reload it from there.
1332 // unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1333 // MachineFunction *F = BB->getParent();
1334 // int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1335 // unsigned Tmp4 = MakeReg(MVT::f64);
1336 // BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3);
1337 // BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1338 // unsigned Tmp5 = MakeReg(MVT::i64);
1339 // BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1341 // //now, set result based on Tmp5
1342 // //Set Tmp6 if fp cmp was false
1343 // unsigned Tmp6 = MakeReg(MVT::i64);
1344 // BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31);
1346 // BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31);
1352 // assert(0 && "Not a setcc in setcc");
1358 case ISD::CopyFromReg:
1360 // Make sure we generate both values.
1361 if (Result != notIn)
1362 ExprMap[N.getValue(1)] = notIn; // Generate the token
1364 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1366 SDOperand Chain = N.getOperand(0);
1369 unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
1370 //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
1371 BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
1375 //Most of the plain arithmetic and logic share the same form, and the same
1376 //constant immediate test
1384 assert (DestType == MVT::i64 && "Only do arithmetic on i64s!");
1385 if(N.getOperand(1).getOpcode() == ISD::Constant &&
1386 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1389 case ISD::AND: Opc = Alpha::ANDi; break;
1390 case ISD::OR: Opc = Alpha::BISi; break;
1391 case ISD::XOR: Opc = Alpha::XORi; break;
1392 case ISD::SHL: Opc = Alpha::SLi; break;
1393 case ISD::SRL: Opc = Alpha::SRLi; break;
1394 case ISD::SRA: Opc = Alpha::SRAi; break;
1395 case ISD::MUL: Opc = Alpha::MULQi; break;
1397 Tmp1 = SelectExpr(N.getOperand(0));
1398 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1399 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1402 case ISD::AND: Opc = Alpha::AND; break;
1403 case ISD::OR: Opc = Alpha::BIS; break;
1404 case ISD::XOR: Opc = Alpha::XOR; break;
1405 case ISD::SHL: Opc = Alpha::SL; break;
1406 case ISD::SRL: Opc = Alpha::SRL; break;
1407 case ISD::SRA: Opc = Alpha::SRA; break;
1408 case ISD::MUL: Opc = Alpha::MULQ; break;
1410 Tmp1 = SelectExpr(N.getOperand(0));
1411 Tmp2 = SelectExpr(N.getOperand(1));
1412 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1419 bool isAdd = opcode == ISD::ADD;
1421 //FIXME: first check for Scaled Adds and Subs!
1422 if(N.getOperand(1).getOpcode() == ISD::Constant &&
1423 cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 255)
1424 { //Normal imm add/sub
1425 Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi;
1426 Tmp1 = SelectExpr(N.getOperand(0));
1427 Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1428 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
1430 else if(N.getOperand(1).getOpcode() == ISD::Constant &&
1431 (cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767 ||
1432 (long)cast<ConstantSDNode>(N.getOperand(1))->getValue() >= -32767))
1434 Tmp1 = SelectExpr(N.getOperand(0));
1435 Tmp2 = (long)cast<ConstantSDNode>(N.getOperand(1))->getValue();
1438 BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
1441 Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
1442 Tmp1 = SelectExpr(N.getOperand(0));
1443 Tmp2 = SelectExpr(N.getOperand(1));
1444 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1453 //FIXME: alpha really doesn't support any of these operations,
1454 // the ops are expanded into special library calls with
1455 // special calling conventions
1456 //Restore GP because it is a call after all...
1458 case ISD::UREM: Opc = Alpha::REMQU; break;
1459 case ISD::SREM: Opc = Alpha::REMQ; break;
1460 case ISD::UDIV: Opc = Alpha::DIVQU; break;
1461 case ISD::SDIV: Opc = Alpha::DIVQ; break;
1463 Tmp1 = SelectExpr(N.getOperand(0));
1464 Tmp2 = SelectExpr(N.getOperand(1));
1465 //set up regs explicitly (helps Reg alloc)
1466 BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp1).addReg(Tmp1);
1467 BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp2).addReg(Tmp2);
1468 AlphaLowering.restoreGP(BB);
1469 BuildMI(BB, Opc, 2).addReg(Alpha::R24).addReg(Alpha::R25);
1470 BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R27).addReg(Alpha::R27);
1473 case ISD::FP_TO_UINT:
1474 case ISD::FP_TO_SINT:
1476 assert (DestType == MVT::i64 && "only quads can be loaded to");
1477 MVT::ValueType SrcType = N.getOperand(0).getValueType();
1478 assert (SrcType == MVT::f32 || SrcType == MVT::f64);
1479 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1482 // Spill the integer to memory and reload it from there.
1483 unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
1484 MachineFunction *F = BB->getParent();
1485 int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8);
1488 //CVTST CVTTQ STT LDQ
1489 if (SrcType == MVT::f32)
1491 Tmp2 = MakeReg(MVT::f64);
1492 BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1);
1495 Tmp2 = MakeReg(MVT::f64);
1496 BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1);
1497 BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1498 BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31);
1503 // // case ISD::FP_TO_UINT:
1507 //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) and can save stack use
1508 Tmp1 = SelectExpr(N.getOperand(0)); //Cond
1509 Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
1510 Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
1511 // Get the condition into the zero flag.
1512 BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp3).addReg(Tmp1);
1518 int64_t val = (long)cast<ConstantSDNode>(N)->getValue();
1519 if (val <= IMM_HIGH && val >= IMM_LOW) {
1520 BuildMI(BB, Alpha::LDA, 2, Result).addImm(val).addReg(Alpha::R31);
1522 else if (val <= (int64_t)IMM_HIGH + (int64_t)IMM_HIGH * (int64_t)IMM_MULT &&
1523 val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT) {
1524 Tmp1 = MakeReg(MVT::i64);
1525 BuildMI(BB, Alpha::LDAH, 2, Tmp1).addImm(getUpper16(val)).addReg(Alpha::R31);
1526 BuildMI(BB, Alpha::LDA, 2, Result).addImm(getLower16(val)).addReg(Tmp1);
1529 MachineConstantPool *CP = BB->getParent()->getConstantPool();
1530 ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
1531 unsigned CPI = CP->getConstantPoolIndex(C);
1532 AlphaLowering.restoreGP(BB);
1533 BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(CPI);
1542 void ISel::Select(SDOperand N) {
1543 unsigned Tmp1, Tmp2, Opc;
1544 unsigned opcode = N.getOpcode();
1546 // FIXME: Disable for our current expansion model!
1547 if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second)
1548 return; // Already selected.
1550 SDNode *Node = N.Val;
1555 Node->dump(); std::cerr << "\n";
1556 assert(0 && "Node not handled yet!");
1564 MachineBasicBlock *Dest =
1565 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
1567 Select(N.getOperand(0));
1568 BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
1572 case ISD::ImplicitDef:
1573 Select(N.getOperand(0));
1574 BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
1577 case ISD::EntryToken: return; // Noop
1579 case ISD::TokenFactor:
1580 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
1581 Select(Node->getOperand(i));
1583 //N.Val->dump(); std::cerr << "\n";
1584 //assert(0 && "Node not handled yet!");
1588 case ISD::CopyToReg:
1589 Select(N.getOperand(0));
1590 Tmp1 = SelectExpr(N.getOperand(1));
1591 Tmp2 = cast<RegSDNode>(N)->getReg();
1594 if (N.getOperand(1).getValueType() == MVT::f64 ||
1595 N.getOperand(1).getValueType() == MVT::f32)
1596 BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1598 BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
1603 switch (N.getNumOperands()) {
1605 std::cerr << N.getNumOperands() << "\n";
1606 for (unsigned i = 0; i < N.getNumOperands(); ++i)
1607 std::cerr << N.getOperand(i).getValueType() << "\n";
1609 assert(0 && "Unknown return instruction!");
1611 Select(N.getOperand(0));
1612 Tmp1 = SelectExpr(N.getOperand(1));
1613 switch (N.getOperand(1).getValueType()) {
1614 default: Node->dump();
1615 assert(0 && "All other types should have been promoted!!");
1618 BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
1622 BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
1627 Select(N.getOperand(0));
1630 //Tmp2 = AlphaLowering.getRetAddr();
1631 //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
1632 BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
1635 case ISD::TRUNCSTORE:
1638 SDOperand Chain = N.getOperand(0);
1639 SDOperand Value = N.getOperand(1);
1640 SDOperand Address = N.getOperand(2);
1643 Tmp1 = SelectExpr(Value); //value
1645 if (opcode == ISD::STORE) {
1646 switch(Value.getValueType()) {
1647 default: assert(0 && "unknown Type in store");
1648 case MVT::i64: Opc = Alpha::STQ; break;
1649 case MVT::f64: Opc = Alpha::STT; break;
1650 case MVT::f32: Opc = Alpha::STS; break;
1652 } else { //ISD::TRUNCSTORE
1653 switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
1654 default: assert(0 && "unknown Type in store");
1655 case MVT::i1: //FIXME: DAG does not promote this load
1656 case MVT::i8: Opc = Alpha::STB; break;
1657 case MVT::i16: Opc = Alpha::STW; break;
1658 case MVT::i32: Opc = Alpha::STL; break;
1662 if (Address.getOpcode() == ISD::GlobalAddress)
1664 AlphaLowering.restoreGP(BB);
1665 Opc = GetSymVersion(Opc);
1666 BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
1668 else if(Address.getOpcode() == ISD::FrameIndex)
1670 BuildMI(BB, Opc, 3).addReg(Tmp1)
1671 .addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
1672 .addReg(Alpha::F31);
1677 SelectAddr(Address, Tmp2, offset);
1678 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
1687 case ISD::CopyFromReg:
1689 case ISD::DYNAMIC_STACKALLOC:
1694 case ISD::ADJCALLSTACKDOWN:
1695 case ISD::ADJCALLSTACKUP:
1696 Select(N.getOperand(0));
1697 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
1699 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
1700 Alpha::ADJUSTSTACKUP;
1701 BuildMI(BB, Opc, 1).addImm(Tmp1);
1704 assert(0 && "Should not be reached!");
1708 /// createAlphaPatternInstructionSelector - This pass converts an LLVM function
1709 /// into a machine code representation using pattern matching and a machine
1710 /// description file.
1712 FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
1713 return new ISel(TM);