From 63f2ab2d1be025b6f9c6cd47bf98f200e68b1af4 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Thu, 10 Feb 2005 06:25:22 +0000 Subject: [PATCH] so, if you beat on it, you too can talk emacs into having a sane indenting policy... Also, optimize many function calls with pc-relative calls (partial prologue skipping for that case coming soon), try to fix the random jumps to strange places problem by pesimizing div et. al. register usage and fixing up GP before using, some calling convention tweaks, and make frame pointer unallocatable (not strickly necessary, but let's go for correctness first) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20106 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Alpha/AlphaISelPattern.cpp | 1105 +++++++++++++------------ lib/Target/Alpha/AlphaInstrInfo.td | 12 +- lib/Target/Alpha/AlphaRegisterInfo.td | 3 +- 3 files changed, 573 insertions(+), 547 deletions(-) diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index d4d2812f396..7d2c823806e 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -46,7 +46,7 @@ namespace { addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); - + setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); @@ -56,7 +56,8 @@ namespace { setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); //what is the sign expansion of 1? 1 or -1? + //what is the sign expansion of 1? 1 or -1? + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); setOperationAction(ISD::SREM , MVT::f32 , Expand); setOperationAction(ISD::SREM , MVT::f64 , Expand); @@ -65,26 +66,26 @@ namespace { setOperationAction(ISD::MEMSET , MVT::Other, Expand); setOperationAction(ISD::MEMCPY , MVT::Other, Expand); - computeRegisterProperties(); + computeRegisterProperties(); - addLegalFPImmediate(+0.0); //F31 - addLegalFPImmediate(-0.0); //-F31 + addLegalFPImmediate(+0.0); //F31 + addLegalFPImmediate(-0.0); //-F31 } /// LowerArguments - This hook must be implemented to indicate how we should /// lower the arguments for the specified function, into the specified DAG. virtual std::vector LowerArguments(Function &F, SelectionDAG &DAG); - + /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - + virtual std::pair LowerVAStart(SDOperand Chain, SelectionDAG &DAG); - + virtual std::pair LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); @@ -144,57 +145,69 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) int count = 0; for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) - { - SDOperand newroot, argt; - if (count < 6) { - switch (getValueType(I->getType())) { - default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort(); - case MVT::f64: - case MVT::f32: - BuildMI(&BB, Alpha::IDEF, 0, args_float[count]); - argVreg[count] = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType()))); - argPreg[count] = args_float[count]; - argOpc[count] = Alpha::CPYS; - argt = newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot()); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - BuildMI(&BB, Alpha::IDEF, 0, args_int[count]); - argVreg[count] =MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); - argPreg[count] = args_int[count]; - argOpc[count] = Alpha::BIS; - argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); - if (getValueType(I->getType()) != MVT::i64) - argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); - break; - } - ++count; - } else { //more args - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); - - // Create the SelectionDAG nodes corresponding to a load from this parameter - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); - argt = newroot = DAG.getLoad(getValueType(I->getType()), DAG.getEntryNode(), FIN); + { + SDOperand newroot, argt; + if (count < 6) { + switch (getValueType(I->getType())) { + default: + std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; + abort(); + case MVT::f64: + case MVT::f32: + BuildMI(&BB, Alpha::IDEF, 0, args_float[count]); + argVreg[count] = + MF.getSSARegMap()->createVirtualRegister( + getRegClassFor(getValueType(I->getType()))); + argPreg[count] = args_float[count]; + argOpc[count] = Alpha::CPYS; + argt = newroot = DAG.getCopyFromReg(argVreg[count], + getValueType(I->getType()), + DAG.getRoot()); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(&BB, Alpha::IDEF, 0, args_int[count]); + argVreg[count] = + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + argPreg[count] = args_int[count]; + argOpc[count] = Alpha::BIS; + argt = newroot = + DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); + if (getValueType(I->getType()) != MVT::i64) + argt = + DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); + break; } - DAG.setRoot(newroot.getValue(1)); - ArgValues.push_back(argt); + ++count; + } else { //more args + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); + + // Create the SelectionDAG nodes corresponding to a load + //from this parameter + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); + argt = newroot = DAG.getLoad(getValueType(I->getType()), + DAG.getEntryNode(), FIN); } + DAG.setRoot(newroot.getValue(1)); + ArgValues.push_back(argt); + } BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29); - for (int i = 0; i < count; ++i) + for (int i = 0; i < count; ++i) { + if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 || + argPreg[i] == Alpha::F18 || argPreg[i] == Alpha::F19 || + argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21) { - if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 || argPreg[i] == Alpha::F18 || - argPreg[i] == Alpha::F19 || argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21) - { - assert(argOpc[i] == Alpha::CPYS && "Using BIS for a float??"); - } - BuildMI(&BB, argOpc[i], 2, argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]); + assert(argOpc[i] == Alpha::CPYS && "Using BIS for a float??"); } + BuildMI(&BB, argOpc[i], 2, + argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]); + } return ArgValues; } @@ -211,27 +224,27 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, DAG.getConstant(NumBytes, getPointerTy())); std::vector args_to_use; for (unsigned i = 0, e = Args.size(); i != e; ++i) - { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - // Promote the integer to 64 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); - else - Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); - break; - case MVT::i64: - case MVT::f64: - case MVT::f32: - break; - } - args_to_use.push_back(Args[i].first); + { + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + // Promote the integer to 64 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); + else + Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); + break; + case MVT::i64: + case MVT::f64: + case MVT::f32: + break; } + args_to_use.push_back(Args[i].first); + } std::vector RetVals; MVT::ValueType RetTyVT = getValueType(RetTy); @@ -239,11 +252,12 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, RetVals.push_back(RetTyVT); RetVals.push_back(MVT::Other); - SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0); + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, + Chain, Callee, args_to_use), 0); Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); + return std::make_pair(TheCall, Chain); } std::pair @@ -254,7 +268,7 @@ AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { std::pair AlphaTargetLowering:: LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { + const Type *ArgTy, SelectionDAG &DAG) { abort(); } @@ -271,48 +285,48 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, namespace { - //===--------------------------------------------------------------------===// - /// ISel - Alpha specific code to select Alpha machine instructions for - /// SelectionDAG operations. - /// - class ISel : public SelectionDAGISel { - - /// AlphaLowering - This object fully describes how to lower LLVM code to an - /// Alpha-specific SelectionDAG. - AlphaTargetLowering AlphaLowering; - - - /// ExprMap - As shared expressions are codegen'd, we keep track of which - /// vreg the value is produced in, so we only emit one copy of each compiled - /// tree. - static const unsigned notIn = (unsigned)(-1); - std::map ExprMap; - - //CCInvMap sometimes (SetNE) we have the inverse CC code for free - std::map CCInvMap; - - public: - ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) { - } - - /// InstructionSelectBasicBlock - This callback is invoked by - /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { - // Codegen the basic block. - Select(DAG.getRoot()); - - // Clear state used for selection. - ExprMap.clear(); - CCInvMap.clear(); - } - - unsigned SelectExpr(SDOperand N); - unsigned SelectExprFP(SDOperand N, unsigned Result); - void Select(SDOperand N); - - void SelectAddr(SDOperand N, unsigned& Reg, long& offset); - void SelectBranchCC(SDOperand N); - }; +//===--------------------------------------------------------------------===// +/// ISel - Alpha specific code to select Alpha machine instructions for +/// SelectionDAG operations. +//===--------------------------------------------------------------------===// +class ISel : public SelectionDAGISel { + + /// AlphaLowering - This object fully describes how to lower LLVM code to an + /// Alpha-specific SelectionDAG. + AlphaTargetLowering AlphaLowering; + + + /// ExprMap - As shared expressions are codegen'd, we keep track of which + /// vreg the value is produced in, so we only emit one copy of each compiled + /// tree. + static const unsigned notIn = (unsigned)(-1); + std::map ExprMap; + + //CCInvMap sometimes (SetNE) we have the inverse CC code for free + std::map CCInvMap; + +public: + ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) + {} + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { + // Codegen the basic block. + Select(DAG.getRoot()); + + // Clear state used for selection. + ExprMap.clear(); + CCInvMap.clear(); + } + + unsigned SelectExpr(SDOperand N); + unsigned SelectExprFP(SDOperand N, unsigned Result); + void Select(SDOperand N); + + void SelectAddr(SDOperand N, unsigned& Reg, long& offset); + void SelectBranchCC(SDOperand N); +}; } static unsigned GetSymVersion(unsigned opcode) @@ -341,18 +355,20 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset) { unsigned opcode = N.getOpcode(); if (opcode == ISD::ADD) { - if(N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->getValue() <= 32767) - { //Normal imm add - Reg = SelectExpr(N.getOperand(0)); - offset = cast(N.getOperand(1))->getValue(); - return; - } - else if(N.getOperand(0).getOpcode() == ISD::Constant && cast(N.getOperand(0))->getValue() <= 32767) - { - Reg = SelectExpr(N.getOperand(1)); - offset = cast(N.getOperand(0))->getValue(); - return; - } + if(N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() <= 32767) + { //Normal imm add + Reg = SelectExpr(N.getOperand(0)); + offset = cast(N.getOperand(1))->getValue(); + return; + } + else if(N.getOperand(0).getOpcode() == ISD::Constant && + cast(N.getOperand(0))->getValue() <= 32767) + { + Reg = SelectExpr(N.getOperand(1)); + offset = cast(N.getOperand(0))->getValue(); + return; + } } Reg = SelectExpr(N); offset = 0; @@ -362,109 +378,104 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset) void ISel::SelectBranchCC(SDOperand N) { assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); - MachineBasicBlock *Dest = cast(N.getOperand(2))->getBasicBlock(); - unsigned Opc; - + MachineBasicBlock *Dest = + cast(N.getOperand(2))->getBasicBlock(); + unsigned Opc = Alpha::WTF; + Select(N.getOperand(0)); //chain SDOperand CC = N.getOperand(1); - + if (CC.getOpcode() == ISD::SETCC) - { - SetCCSDNode* SetCC = dyn_cast(CC.Val); - if (MVT::isInteger(SetCC->getOperand(0).getValueType())) { - //Dropping the CC is only useful if we are comparing to 0 - bool isZero0 = false; - bool isZero1 = false; - bool isNE = false; + { + SetCCSDNode* SetCC = dyn_cast(CC.Val); + if (MVT::isInteger(SetCC->getOperand(0).getValueType())) { + //Dropping the CC is only useful if we are comparing to 0 + bool isZero0 = false; + bool isZero1 = false; + bool isNE = false; - if(SetCC->getOperand(0).getOpcode() == ISD::Constant && - cast(SetCC->getOperand(0))->getValue() == 0) - isZero0 = true; - if(SetCC->getOperand(1).getOpcode() == ISD::Constant && - cast(SetCC->getOperand(1))->getValue() == 0) - isZero1 = true; - if(SetCC->getCondition() == ISD::SETNE) - isNE = true; - - if (isZero0) - { - switch (SetCC->getCondition()) { - default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); - case ISD::SETEQ: Opc = Alpha::BEQ; break; - case ISD::SETLT: Opc = Alpha::BGT; break; - case ISD::SETLE: Opc = Alpha::BGE; break; - case ISD::SETGT: Opc = Alpha::BLT; break; - case ISD::SETGE: Opc = Alpha::BLE; break; - case ISD::SETULT: Opc = Alpha::BNE; break; - case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break; - case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break; - case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC - case ISD::SETNE: Opc = Alpha::BNE; break; - } - unsigned Tmp1 = SelectExpr(SetCC->getOperand(1)); - BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); - return; - } - else if (isZero1) - { - switch (SetCC->getCondition()) { - default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); - case ISD::SETEQ: Opc = Alpha::BEQ; break; - case ISD::SETLT: Opc = Alpha::BLT; break; - case ISD::SETLE: Opc = Alpha::BLE; break; - case ISD::SETGT: Opc = Alpha::BGT; break; - case ISD::SETGE: Opc = Alpha::BGE; break; - case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break; - case ISD::SETUGT: Opc = Alpha::BNE; break; - case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC - case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break; - case ISD::SETNE: Opc = Alpha::BNE; break; - } - unsigned Tmp1 = SelectExpr(SetCC->getOperand(0)); - BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); - return; - } - else - { - unsigned Tmp1 = SelectExpr(CC); - if (isNE) - BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest); - else - BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); - return; - } - } else { //FP - //Any comparison between 2 values should be codegened as an folded branch, as moving - //CC to the integer register is very expensive - //for a cmp b: c = a - b; - //a = b: c = 0 - //a < b: c < 0 - //a > b: c > 0 - unsigned Tmp1 = SelectExpr(SetCC->getOperand(0)); - unsigned Tmp2 = SelectExpr(SetCC->getOperand(1)); - unsigned Tmp3 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::SUBT, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + if(SetCC->getOperand(0).getOpcode() == ISD::Constant && + cast(SetCC->getOperand(0))->getValue() == 0) + isZero0 = true; + if(SetCC->getOperand(1).getOpcode() == ISD::Constant && + cast(SetCC->getOperand(1))->getValue() == 0) + isZero1 = true; + if(SetCC->getCondition() == ISD::SETNE) + isNE = true; + if (isZero0) { switch (SetCC->getCondition()) { - default: CC.Val->dump(); assert(0 && "Unknown FP comparison!"); - case ISD::SETEQ: Opc = Alpha::FBEQ; break; - case ISD::SETLT: Opc = Alpha::FBLT; break; - case ISD::SETLE: Opc = Alpha::FBLE; break; - case ISD::SETGT: Opc = Alpha::FBGT; break; - case ISD::SETGE: Opc = Alpha::FBGE; break; - case ISD::SETNE: Opc = Alpha::FBNE; break; + default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); + case ISD::SETEQ: Opc = Alpha::BEQ; break; + case ISD::SETLT: Opc = Alpha::BGT; break; + case ISD::SETLE: Opc = Alpha::BGE; break; + case ISD::SETGT: Opc = Alpha::BLT; break; + case ISD::SETGE: Opc = Alpha::BLE; break; + case ISD::SETULT: Opc = Alpha::BNE; break; + case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break; + case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break; + case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC + case ISD::SETNE: Opc = Alpha::BNE; break; } - BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest); + unsigned Tmp1 = SelectExpr(SetCC->getOperand(1)); + BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); + return; + } else if (isZero1) { + switch (SetCC->getCondition()) { + default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); + case ISD::SETEQ: Opc = Alpha::BEQ; break; + case ISD::SETLT: Opc = Alpha::BLT; break; + case ISD::SETLE: Opc = Alpha::BLE; break; + case ISD::SETGT: Opc = Alpha::BGT; break; + case ISD::SETGE: Opc = Alpha::BGE; break; + case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break; + case ISD::SETUGT: Opc = Alpha::BNE; break; + case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC + case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break; + case ISD::SETNE: Opc = Alpha::BNE; break; + } + unsigned Tmp1 = SelectExpr(SetCC->getOperand(0)); + BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); + return; + } else { + unsigned Tmp1 = SelectExpr(CC); + if (isNE) + BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest); + else + BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); return; } - abort(); //Should never be reached - } - else - { //Giveup and do the stupid thing - unsigned Tmp1 = SelectExpr(CC); - BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); + } else { //FP + //Any comparison between 2 values should be codegened as an folded branch, as moving + //CC to the integer register is very expensive + //for a cmp b: c = a - b; + //a = b: c = 0 + //a < b: c < 0 + //a > b: c > 0 + unsigned Tmp1 = SelectExpr(SetCC->getOperand(0)); + unsigned Tmp2 = SelectExpr(SetCC->getOperand(1)); + unsigned Tmp3 = MakeReg(MVT::f64); + BuildMI(BB, Alpha::SUBT, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + + switch (SetCC->getCondition()) { + default: CC.Val->dump(); assert(0 && "Unknown FP comparison!"); + case ISD::SETEQ: Opc = Alpha::FBEQ; break; + case ISD::SETLT: Opc = Alpha::FBLT; break; + case ISD::SETLE: Opc = Alpha::FBLE; break; + case ISD::SETGT: Opc = Alpha::FBGT; break; + case ISD::SETGE: Opc = Alpha::FBGE; break; + case ISD::SETNE: Opc = Alpha::FBNE; break; + } + BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest); return; } + abort(); //Should never be reached + } else { + //Giveup and do the stupid thing + unsigned Tmp1 = SelectExpr(CC); + BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); + return; + } abort(); //Should never be reached } @@ -502,13 +513,17 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) } case ISD::FP_ROUND: - assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here"); + assert (DestType == MVT::f32 && + N.getOperand(0).getValueType() == MVT::f64 && + "only f64 to f32 conversion supported here"); Tmp1 = SelectExpr(N.getOperand(0)); BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1); return Result; case ISD::FP_EXTEND: - assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here"); + assert (DestType == MVT::f64 && + N.getOperand(0).getValueType() == MVT::f32 && + "only f32 to f64 conversion supported here"); Tmp1 = SelectExpr(N.getOperand(0)); BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1); return Result; @@ -545,28 +560,24 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) Select(Chain); Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS; - if (Address.getOpcode() == ISD::GlobalAddress) - { - AlphaLowering.restoreGP(BB); - Opc = GetSymVersion(Opc); - BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); - } + if (Address.getOpcode() == ISD::GlobalAddress) { + AlphaLowering.restoreGP(BB); + Opc = GetSymVersion(Opc); + BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); + } else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); } - else if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp1 = cast(Address)->getIndex(); - BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); - } - else - { - long offset; - SelectAddr(Address, Tmp1, offset); - BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); - } + else if(Address.getOpcode() == ISD::FrameIndex) { + Tmp1 = cast(Address)->getIndex(); + BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); + } else { + long offset; + SelectAddr(Address, Tmp1, offset); + BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); + } return Result; } case ISD::ConstantFP: @@ -606,34 +617,32 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) Tmp1 = MakeReg(MVT::f32); - assert(cast(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32"); + assert(cast(Node)->getExtraValueType() == MVT::f32 && + "EXTLOAD not from f32"); assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64"); SDOperand Chain = N.getOperand(0); SDOperand Address = N.getOperand(1); Select(Chain); - if (Address.getOpcode() == ISD::GlobalAddress) - { - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast(Address)->getGlobal()); - } - else if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(1))) - { - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex()); - } - else if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp2 = cast(Address)->getIndex(); - BuildMI(BB, Alpha::LDS, 2, Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31); - } - else - { - long offset; - SelectAddr(Address, Tmp2, offset); - BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2); - } + if (Address.getOpcode() == ISD::GlobalAddress) { + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast(Address)->getGlobal()); + } + else if (ConstantPoolSDNode *CP = + dyn_cast(N.getOperand(1))) + { + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex()); + } + else if(Address.getOpcode() == ISD::FrameIndex) { + Tmp2 = cast(Address)->getIndex(); + BuildMI(BB, Alpha::LDS, 2, Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31); + } else { + long offset; + SelectAddr(Address, Tmp2, offset); + BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2); + } BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1); return Result; } @@ -641,7 +650,8 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: { - assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from"); + assert (N.getOperand(0).getValueType() == MVT::i64 + && "only quads can be loaded from"); Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register Tmp2 = MakeReg(MVT::f64); @@ -657,11 +667,11 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) BuildMI(BB, Opc, 1, Result).addReg(Tmp2); //The easy way: doesn't work -// //so these instructions are not supported on ev56 -// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS; -// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1); -// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS; -// BuildMI(BB, Opc, 1, Result).addReg(Tmp1); + // //so these instructions are not supported on ev56 + // Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS; + // BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1); + // Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS; + // BuildMI(BB, Opc, 1, Result).addReg(Tmp1); return Result; } @@ -701,8 +711,10 @@ unsigned ISel::SelectExpr(SDOperand N) { if (DestType == MVT::f64 || DestType == MVT::f32 || ( - (opcode == ISD::LOAD || opcode == ISD::CopyFromReg || opcode == ISD::EXTLOAD) && - (N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64) + (opcode == ISD::LOAD || opcode == ISD::CopyFromReg || + opcode == ISD::EXTLOAD) && + (N.getValue(0).getValueType() == MVT::f32 || + N.getValue(0).getValueType() == MVT::f64) ) ) return SelectExprFP(N, Result); @@ -738,40 +750,40 @@ unsigned ISel::SelectExpr(SDOperand N) { SDOperand Address = N.getOperand(1); Select(Chain); - assert(Node->getValueType(0) == MVT::i64 && "Unknown type to sign extend to."); + assert(Node->getValueType(0) == MVT::i64 && + "Unknown type to sign extend to."); if (opcode == ISD::LOAD) Opc = Alpha::LDQ; else switch (cast(Node)->getExtraValueType()) { default: Node->dump(); assert(0 && "Bad sign extend!"); - case MVT::i32: Opc = Alpha::LDL; assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; - case MVT::i16: Opc = Alpha::LDWU; assert(opcode != ISD::SEXTLOAD && "Not zext"); break; + case MVT::i32: Opc = Alpha::LDL; + assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; + case MVT::i16: Opc = Alpha::LDWU; + assert(opcode != ISD::SEXTLOAD && "Not zext"); break; case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise - case MVT::i8: Opc = Alpha::LDBU; assert(opcode != ISD::SEXTLOAD && "Not zext"); break; + case MVT::i8: Opc = Alpha::LDBU; + assert(opcode != ISD::SEXTLOAD && "Not zext"); break; } - if (Address.getOpcode() == ISD::GlobalAddress) - { - AlphaLowering.restoreGP(BB); - Opc = GetSymVersion(Opc); - BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); - } + if (Address.getOpcode() == ISD::GlobalAddress) { + AlphaLowering.restoreGP(BB); + Opc = GetSymVersion(Opc); + BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); + } else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); - BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); + BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); + } + else if(Address.getOpcode() == ISD::FrameIndex) { + Tmp1 = cast(Address)->getIndex(); + BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); + } else { + long offset; + SelectAddr(Address, Tmp1, offset); + BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); } - else if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp1 = cast(Address)->getIndex(); - BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); - } - else - { - long offset; - SelectAddr(Address, Tmp1, offset); - BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); - } return Result; } @@ -792,78 +804,84 @@ unsigned ISel::SelectExpr(SDOperand N) { std::vector argvregs; //assert(Node->getNumOperands() < 8 && "Only 6 args supported"); for(int i = 2, e = Node->getNumOperands(); i < e; ++i) - argvregs.push_back(SelectExpr(N.getOperand(i))); + argvregs.push_back(SelectExpr(N.getOperand(i))); //in reg args for(int i = 0, e = std::min(6, (int)argvregs.size()); i < e; ++i) - { - unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, - Alpha::R19, Alpha::R20, Alpha::R21}; - unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, - Alpha::F19, Alpha::F20, Alpha::F21}; - switch(N.getOperand(i+2).getValueType()) { - default: - Node->dump(); - N.getOperand(i).Val->dump(); - std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n"; - assert(0 && "Unknown value type for call"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]); - break; - case MVT::f32: - case MVT::f64: - BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]); - break; - } + { + unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, + Alpha::R19, Alpha::R20, Alpha::R21}; + unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, + Alpha::F19, Alpha::F20, Alpha::F21}; + switch(N.getOperand(i+2).getValueType()) { + default: + Node->dump(); + N.getOperand(i).Val->dump(); + std::cerr << "Type for " << i << " is: " << + N.getOperand(i+2).getValueType() << "\n"; + assert(0 && "Unknown value type for call"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(BB, Alpha::BIS, 2, args_int[i]).addReg(argvregs[i]).addReg(argvregs[i]); + break; + case MVT::f32: + case MVT::f64: + BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]).addReg(argvregs[i]); + break; } + } //in mem args for (int i = 6, e = argvregs.size(); i < e; ++i) - { - switch(N.getOperand(i+2).getValueType()) { - default: - Node->dump(); - N.getOperand(i).Val->dump(); - std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n"; - assert(0 && "Unknown value type for call"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); - break; - case MVT::f32: - BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); - break; - case MVT::f64: - BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); - break; - } + { + switch(N.getOperand(i+2).getValueType()) { + default: + Node->dump(); + N.getOperand(i).Val->dump(); + std::cerr << "Type for " << i << " is: " << + N.getOperand(i+2).getValueType() << "\n"; + assert(0 && "Unknown value type for call"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(BB, Alpha::STQ, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); + break; + case MVT::f32: + BuildMI(BB, Alpha::STS, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); + break; + case MVT::f64: + BuildMI(BB, Alpha::STT, 3).addReg(argvregs[i]).addImm((i - 6) * 8).addReg(Alpha::R30); + break; } + } //build the right kind of call if (GlobalAddressSDNode *GASD = dyn_cast(N.getOperand(1))) - { + { + if (GASD->getGlobal()->isExternal()) { + //use safe calling convention AlphaLowering.restoreGP(BB); BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); - } + } else { + //use PC relative branch call + BuildMI(BB, Alpha::BSR, 1, Alpha::R26).addGlobalAddress(GASD->getGlobal(),true); + } + } else if (ExternalSymbolSDNode *ESSDN = dyn_cast(N.getOperand(1))) - { - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); - } - else - { - //no need to restore GP as we are doing an indirect call - Tmp1 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1); - BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0); - } + { + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); + } else { + //no need to restore GP as we are doing an indirect call + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, Alpha::JSR, 2, Alpha::R26).addReg(Alpha::R27).addImm(0); + } //push the result into a virtual register @@ -892,56 +910,56 @@ unsigned ISel::SelectExpr(SDOperand N) { { //Alpha has instructions for a bunch of signed 32 bit stuff if( dyn_cast(Node)->getExtraValueType() == MVT::i32) - { - switch (N.getOperand(0).getOpcode()) { - case ISD::ADD: - case ISD::SUB: - case ISD::MUL: - { - bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD; - bool isMul = N.getOperand(0).getOpcode() == ISD::MUL; - //FIXME: first check for Scaled Adds and Subs! - if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(0).getOperand(1))->getValue() <= 255) - { //Normal imm add/sub - Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi); - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = cast(N.getOperand(0).getOperand(1))->getValue(); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); - } - else - { //Normal add/sub - Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL); - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; + { + switch (N.getOperand(0).getOpcode()) { + case ISD::ADD: + case ISD::SUB: + case ISD::MUL: + { + bool isAdd = N.getOperand(0).getOpcode() == ISD::ADD; + bool isMul = N.getOperand(0).getOpcode() == ISD::MUL; + //FIXME: first check for Scaled Adds and Subs! + if(N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(0).getOperand(1))->getValue() <= 255) + { //Normal imm add/sub + Opc = isAdd ? Alpha::ADDLi : (isMul ? Alpha::MULLi : Alpha::SUBLi); + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = cast(N.getOperand(0).getOperand(1))->getValue(); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); } - default: break; //Fall Though; + else + { //Normal add/sub + Opc = isAdd ? Alpha::ADDL : (isMul ? Alpha::MULLi : Alpha::SUBL); + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; } - } //Every thing else fall though too, including unhandled opcodes above + default: break; //Fall Though; + } + } //Every thing else fall though too, including unhandled opcodes above Tmp1 = SelectExpr(N.getOperand(0)); MVTSDNode* MVN = dyn_cast(Node); //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; switch(MVN->getExtraValueType()) + { + default: + Node->dump(); + assert(0 && "Sign Extend InReg not there yet"); + break; + case MVT::i32: { - default: - Node->dump(); - assert(0 && "Sign Extend InReg not there yet"); - break; - case MVT::i32: - { - BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0); - break; - } - case MVT::i16: - BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1); - break; - case MVT::i8: - BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1); + BuildMI(BB, Alpha::ADDLi, 2, Result).addReg(Tmp1).addImm(0); break; } + case MVT::i16: + BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1); + break; + case MVT::i8: + BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1); + break; + } return Result; } case ISD::ZERO_EXTEND_INREG: @@ -950,18 +968,18 @@ unsigned ISel::SelectExpr(SDOperand N) { MVTSDNode* MVN = dyn_cast(Node); //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; switch(MVN->getExtraValueType()) - { - default: - Node->dump(); - assert(0 && "Zero Extend InReg not there yet"); - break; - case MVT::i32: Tmp2 = 0xf0; break; - case MVT::i16: Tmp2 = 0xfc; break; - case MVT::i8: Tmp2 = 0xfe; break; - case MVT::i1: //handle this one special - BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1); - return Result; - } + { + default: + Node->dump(); + assert(0 && "Zero Extend InReg not there yet"); + break; + case MVT::i32: Tmp2 = 0xf0; break; + case MVT::i16: Tmp2 = 0xfc; break; + case MVT::i8: Tmp2 = 0xfe; break; + case MVT::i1: //handle this one special + BuildMI(BB, Alpha::ANDi, 2, Result).addReg(Tmp1).addImm(1); + return Result; + } BuildMI(BB, Alpha::ZAPi, 2, Result).addReg(Tmp1).addImm(Tmp2); return Result; } @@ -985,14 +1003,22 @@ unsigned ISel::SelectExpr(SDOperand N) { switch (SetCC->getCondition()) { default: Node->dump(); assert(0 && "Unknown integer comparison!"); case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break; - case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break; - case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break; - case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break; - case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break; - case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break; - case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break; - case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break; - case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break; + case ISD::SETLT: + Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break; + case ISD::SETLE: + Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break; + case ISD::SETGT: + Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break; + case ISD::SETGE: + Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break; + case ISD::SETULT: + Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break; + case ISD::SETUGT: + Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break; + case ISD::SETULE: + Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break; + case ISD::SETUGE: + Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break; case ISD::SETNE: {//Handle this one special //std::cerr << "Alpha does not have a setne.\n"; //abort(); @@ -1059,17 +1085,17 @@ unsigned ISel::SelectExpr(SDOperand N) { Tmp2 = SelectExpr(N.getOperand(1)); //Can only compare doubles, and dag won't promote for me if (SetCC->getOperand(0).getValueType() == MVT::f32) - { - Tmp3 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1); - Tmp1 = Tmp3; - } + { + Tmp3 = MakeReg(MVT::f64); + BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1); + Tmp1 = Tmp3; + } if (SetCC->getOperand(1).getValueType() == MVT::f32) - { - Tmp3 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2); - Tmp1 = Tmp2; - } + { + Tmp3 = MakeReg(MVT::f64); + BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2); + Tmp1 = Tmp2; + } if (rev) std::swap(Tmp1, Tmp2); Tmp3 = MakeReg(MVT::f64); @@ -1134,35 +1160,33 @@ unsigned ISel::SelectExpr(SDOperand N) { assert (DestType == MVT::i64 && "Only do arithmetic on i64s!"); if(N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->getValue() <= 255) - { - switch(opcode) { - case ISD::AND: Opc = Alpha::ANDi; break; - case ISD::OR: Opc = Alpha::BISi; break; - case ISD::XOR: Opc = Alpha::XORi; break; - case ISD::SHL: Opc = Alpha::SLi; break; - case ISD::SRL: Opc = Alpha::SRLi; break; - case ISD::SRA: Opc = Alpha::SRAi; break; - case ISD::MUL: Opc = Alpha::MULQi; break; - }; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = cast(N.getOperand(1))->getValue(); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); - } - else - { - switch(opcode) { - case ISD::AND: Opc = Alpha::AND; break; - case ISD::OR: Opc = Alpha::BIS; break; - case ISD::XOR: Opc = Alpha::XOR; break; - case ISD::SHL: Opc = Alpha::SL; break; - case ISD::SRL: Opc = Alpha::SRL; break; - case ISD::SRA: Opc = Alpha::SRA; break; - case ISD::MUL: Opc = Alpha::MULQ; break; - }; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + { + switch(opcode) { + case ISD::AND: Opc = Alpha::ANDi; break; + case ISD::OR: Opc = Alpha::BISi; break; + case ISD::XOR: Opc = Alpha::XORi; break; + case ISD::SHL: Opc = Alpha::SLi; break; + case ISD::SRL: Opc = Alpha::SRLi; break; + case ISD::SRA: Opc = Alpha::SRAi; break; + case ISD::MUL: Opc = Alpha::MULQi; break; + }; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = cast(N.getOperand(1))->getValue(); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + switch(opcode) { + case ISD::AND: Opc = Alpha::AND; break; + case ISD::OR: Opc = Alpha::BIS; break; + case ISD::XOR: Opc = Alpha::XOR; break; + case ISD::SHL: Opc = Alpha::SL; break; + case ISD::SRL: Opc = Alpha::SRL; break; + case ISD::SRA: Opc = Alpha::SRA; break; + case ISD::MUL: Opc = Alpha::MULQ; break; + }; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; case ISD::ADD: @@ -1173,28 +1197,27 @@ unsigned ISel::SelectExpr(SDOperand N) { //FIXME: first check for Scaled Adds and Subs! if(N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->getValue() <= 255) - { //Normal imm add/sub - Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = cast(N.getOperand(1))->getValue(); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); - } + { //Normal imm add/sub + Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = cast(N.getOperand(1))->getValue(); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else if(N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->getValue() <= 32767) - { //LDA //FIXME: expand the above condition a bit - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = cast(N.getOperand(1))->getValue(); - if (!isAdd) - Tmp2 = -Tmp2; - BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1); - } - else - { //Normal add/sub - Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - } + { //LDA //FIXME: expand the above condition a bit + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = cast(N.getOperand(1))->getValue(); + if (!isAdd) + Tmp2 = -Tmp2; + BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1); + } else { + //Normal add/sub + Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } @@ -1205,11 +1228,12 @@ unsigned ISel::SelectExpr(SDOperand N) { //FIXME: alpha really doesn't support any of these operations, // the ops are expanded into special library calls with // special calling conventions + //Restore GP because it is a call after all... switch(opcode) { - case ISD::UREM: Opc = Alpha::REMQU; break; - case ISD::SREM: Opc = Alpha::REMQ; break; - case ISD::UDIV: Opc = Alpha::DIVQU; break; - case ISD::SDIV: Opc = Alpha::DIVQ; break; + case ISD::UREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQU; break; + case ISD::SREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQ; break; + case ISD::UDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQU; break; + case ISD::SDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQ; break; } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1218,7 +1242,7 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::FP_TO_UINT: case ISD::FP_TO_SINT: - { + { assert (DestType == MVT::i64 && "only quads can be loaded to"); MVT::ValueType SrcType = N.getOperand(0).getValueType(); assert (SrcType == MVT::f32 || SrcType == MVT::f64); @@ -1233,20 +1257,20 @@ unsigned ISel::SelectExpr(SDOperand N) { //CVTTQ STT LDQ //CVTST CVTTQ STT LDQ if (SrcType == MVT::f32) - { - Tmp2 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1); - Tmp1 = Tmp2; - } + { + Tmp2 = MakeReg(MVT::f64); + BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1); + Tmp1 = Tmp2; + } Tmp2 = MakeReg(MVT::f64); BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1); BuildMI(BB, Alpha::STT, 3).addReg(Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31); BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdx).addReg(Alpha::F31); return Result; - } + } -// // case ISD::FP_TO_UINT: + // // case ISD::FP_TO_UINT: case ISD::SELECT: { @@ -1261,17 +1285,16 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::Constant: { unsigned long val = cast(N)->getValue(); - if (val < 32000 && (long)val > -32000) - BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val); - else - { - MachineConstantPool *CP = BB->getParent()->getConstantPool(); - ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); - unsigned CPI = CP->getConstantPoolIndex(C); - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(CPI); - } - return Result; + if (val < 32000 && (long)val > -32000) + BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val); + else { + MachineConstantPool *CP = BB->getParent()->getConstantPool(); + ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); + unsigned CPI = CP->getConstantPoolIndex(C); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::LDQ_SYM, 1, Result).addConstantPoolIndex(CPI); + } + return Result; } } @@ -1331,44 +1354,46 @@ void ISel::Select(SDOperand N) { Tmp2 = cast(N)->getReg(); if (Tmp1 != Tmp2) { - if (N.getOperand(1).getValueType() == MVT::f64 || N.getOperand(1).getValueType() == MVT::f32) + if (N.getOperand(1).getValueType() == MVT::f64 || + N.getOperand(1).getValueType() == MVT::f32) BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); else BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); } return; - case ISD::RET: - switch (N.getNumOperands()) { - default: - std::cerr << N.getNumOperands() << "\n"; - for (unsigned i = 0; i < N.getNumOperands(); ++i) - std::cerr << N.getOperand(i).getValueType() << "\n"; - Node->dump(); - assert(0 && "Unknown return instruction!"); - case 2: - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - switch (N.getOperand(1).getValueType()) { - default: Node->dump(); assert(0 && "All other types should have been promoted!!"); - case MVT::f64: - case MVT::f32: - BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); - break; - case MVT::i32: - case MVT::i64: - BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1); - break; - } - break; - case 1: - Select(N.getOperand(0)); - break; - } - //Tmp2 = AlphaLowering.getRetAddr(); - //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2); - BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction - return; + case ISD::RET: + switch (N.getNumOperands()) { + default: + std::cerr << N.getNumOperands() << "\n"; + for (unsigned i = 0; i < N.getNumOperands(); ++i) + std::cerr << N.getOperand(i).getValueType() << "\n"; + Node->dump(); + assert(0 && "Unknown return instruction!"); + case 2: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + switch (N.getOperand(1).getValueType()) { + default: Node->dump(); + assert(0 && "All other types should have been promoted!!"); + case MVT::f64: + case MVT::f32: + BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); + break; + case MVT::i32: + case MVT::i64: + BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1); + break; + } + break; + case 1: + Select(N.getOperand(0)); + break; + } + //Tmp2 = AlphaLowering.getRetAddr(); + //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2); + BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction + return; case ISD::TRUNCSTORE: case ISD::STORE: @@ -1398,22 +1423,22 @@ void ISel::Select(SDOperand N) { } if (Address.getOpcode() == ISD::GlobalAddress) - { - AlphaLowering.restoreGP(BB); - Opc = GetSymVersion(Opc); - BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast(Address)->getGlobal()); - } + { + AlphaLowering.restoreGP(BB); + Opc = GetSymVersion(Opc); + BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast(Address)->getGlobal()); + } else if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp2 = cast(Address)->getIndex(); - BuildMI(BB, Opc, 3).addReg(Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31); - } + { + Tmp2 = cast(Address)->getIndex(); + BuildMI(BB, Opc, 3).addReg(Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31); + } else - { - long offset; - SelectAddr(Address, Tmp2, offset); - BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); - } + { + long offset; + SelectAddr(Address, Tmp2, offset); + BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); + } return; } @@ -1423,7 +1448,7 @@ void ISel::Select(SDOperand N) { case ISD::LOAD: case ISD::CopyFromReg: case ISD::CALL: -// case ISD::DYNAMIC_STACKALLOC: + // case ISD::DYNAMIC_STACKALLOC: ExprMap.erase(N); SelectExpr(N); return; diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 882b5dea3e6..dd8bc790c39 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -53,7 +53,7 @@ let isCall = 1, let isReturn = 1, isTerminator = 1 in def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine -let Uses = [R28] in +let Uses = [R28, R29] in def LOAD_IMM : PseudoInstAlpha<(ops GPRC:$RC, s64imm:$IMM), "ldiq $RC,$IMM">; //Load Immediate Quadword let Uses = [R29, R28] in { @@ -79,7 +79,8 @@ let Uses = [R29, R28] in { def STT_SYM : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "stt $RA,$DISP">; //store double } -let Uses = [R28, R23, R24, R25, R26] in +let Uses = [R28, R23, R24, R25, R26, R29], + Defs = [R29] in { def REMQU : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remqu $RA,$RB,$RC">; //unsigned remander def REMQ : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remq $RA,$RB,$RC">; //unsigned remander @@ -274,11 +275,10 @@ let isReturn = 1, isTerminator = 1 in def JMP : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jmp $RD,($RS),0">; //Jump let isCall = 1, Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, - R20, R21, R22, R23, R24, R25, R27, R29, + R20, R21, R22, R23, R24, R25, R27, R28, R29, F0, F1, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, - F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], - Uses = [R29] in { + F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30] in { def JSR : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine def BSR : BForm<0x34, (ops GPRC:$RD, s21imm:$DISP), "bsr $RD,$DISP">; //Branch to subroutine } @@ -286,7 +286,7 @@ let isCall = 1, def JSR_COROUTINE : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jsr_coroutine $RD,($RS),1">; //Jump to subroutine return def BR : BForm<0x30, (ops GPRC:$RD, s21imm:$DISP), "br $RD,$DISP">; //Branch -let Uses = [R29, R28] in { +let Uses = [R28] in { //Stores, int def STB : MForm<0x0E, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stb $RA,$DISP($RB)">; // Store byte def STW : MForm<0x0D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stw $RA,$DISP($RB)">; // Store word diff --git a/lib/Target/Alpha/AlphaRegisterInfo.td b/lib/Target/Alpha/AlphaRegisterInfo.td index 3ed2b5539d0..7957bedbf74 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.td +++ b/lib/Target/Alpha/AlphaRegisterInfo.td @@ -83,8 +83,9 @@ def GPRC : RegisterClass; + R9, R10, R11, R12, R13, R14, /*R15,*/ R26, /* R28, */ R29 /* R30, R31*/ ]>; // Note: R28 is reserved for the assembler + //leave FP alone // Don't allocate 15, 29, 30, 31 // Allocation volatiles only for now