From 3e98fde96bfeb346fb32bc1be3d667da66436592 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Wed, 26 Jan 2005 21:54:09 +0000 Subject: [PATCH] initial fp support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19847 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Alpha/AlphaISelPattern.cpp | 448 ++++++++++++++++--------- lib/Target/Alpha/AlphaInstrFormats.td | 4 +- lib/Target/Alpha/AlphaInstrInfo.cpp | 2 +- lib/Target/Alpha/AlphaInstrInfo.td | 111 +++--- lib/Target/Alpha/AlphaRegisterInfo.cpp | 31 +- 5 files changed, 364 insertions(+), 232 deletions(-) diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index c5220bc9017..befcc3ff1bd 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -53,6 +53,14 @@ namespace { setOperationAction(ISD::ZERO_EXTEND_INREG, MVT::i1, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); + // setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand); + // setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand); + setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote); + setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Promote); + + setOperationAction(ISD::FP_TO_SINT , MVT::f32 , Promote); computeRegisterProperties(); @@ -124,18 +132,35 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) //Handle the return address //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26); - unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, - Alpha::R19, Alpha::R20, Alpha::R21}; + 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}; std::vector argVreg; - + std::vector argPreg; int count = 0; for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) { ++count; assert(count <= 6 && "More than 6 args not supported"); - assert(getValueType(I->getType()) != MVT::f64 && "No floats yet"); - BuildMI(&BB, Alpha::IDEF, 0, args[count - 1]); - argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64))); + 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 - 1]); + argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType())))); + argPreg.push_back(args_float[count - 1]); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(&BB, Alpha::IDEF, 0, args_int[count - 1]); + argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType())))); + argPreg.push_back(args_int[count - 1]); + break; + } } BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); @@ -143,25 +168,30 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) count = 0; for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) { - BuildMI(&BB, Alpha::BIS, 2, argVreg[count]).addReg(args[count]).addReg(args[count]); - - SDOperand argt, newroot; + SDOperand newroot; + unsigned Opc; switch (getValueType(I->getType())) { + default: assert(0 && "Unhandled type"); case MVT::i64: - argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); - break; case MVT::i32: - argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i32, DAG.getRoot()); + case MVT::i16: + case MVT::i8: + case MVT::i1: + Opc = Alpha::BIS; + break; + case MVT::f32: + case MVT::f64: + Opc = Alpha::CPYS; break; - default: - newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); - argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); } + BuildMI(&BB, Opc, 2, argVreg[count]).addReg(argPreg[count]).addReg(argPreg[count]); + newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot()); DAG.setRoot(newroot.getValue(1)); - ArgValues.push_back(argt); + ArgValues.push_back(newroot); ++count; } + return ArgValues; } @@ -184,9 +214,9 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, // 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); + Args[i].first = DAG.getNode(ISD::SIGN_EXTEND_INREG, MVT::i64, Args[i].first); else - Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); + Args[i].first = DAG.getNode(ISD::ZERO_EXTEND_INREG, MVT::i64, Args[i].first); break; case MVT::i64: break; @@ -317,18 +347,12 @@ unsigned ISel::SelectExpr(SDOperand N) { Tmp1 = SelectExpr(Node->getOperand(1)); switch(Node->getValueType(0)) { - default: assert(0 && "Unknown type to sign extend to."); + default: Node->dump(); assert(0 && "Unknown type to sign extend to."); case MVT::i64: switch (cast(Node)->getExtraValueType()) { default: - std::cerr << cast(Node)->getExtraValueType() - << "(i1 is " << MVT::i1 - << " i8 is " << MVT::i8 - << " i16 is " << MVT::i16 - << " i32 is " << MVT::i32 - << " i64 is " << MVT::i64 - << ")\n"; - assert(0 && "Bad extend load!"); + Node->dump(); + assert(0 && "Bad extend load!"); case MVT::i64: BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp1); break; @@ -357,11 +381,12 @@ unsigned ISel::SelectExpr(SDOperand N) { Select(Node->getOperand(0)); // chain Tmp1 = SelectExpr(Node->getOperand(1)); switch(Node->getValueType(0)) { - default: assert(0 && "Unknown type to sign extend to."); + default: Node->dump(); assert(0 && "Unknown type to sign extend to."); case MVT::i64: switch (cast(Node)->getExtraValueType()) { default: - assert(0 && "Bad sign extend!"); + Node->dump(); + assert(0 && "Bad sign extend!"); case MVT::i32: BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1); break; @@ -386,11 +411,12 @@ unsigned ISel::SelectExpr(SDOperand N) { Select(Node->getOperand(0)); // chain Tmp1 = SelectExpr(Node->getOperand(1)); switch(Node->getValueType(0)) { - default: assert(0 && "Unknown type to zero extend to."); + default: Node->dump(); assert(0 && "Unknown type to zero extend to."); case MVT::i64: switch (cast(Node)->getExtraValueType()) { default: - assert(0 && "Bad sign extend!"); + Node->dump(); + assert(0 && "Bad sign extend!"); case MVT::i16: BuildMI(BB, Alpha::LDWU, 2, Result).addImm(0).addReg(Tmp1); break; @@ -412,7 +438,7 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::CALL: { Select(N.getOperand(0)); - + // The chain for this call is now lowered. ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1)); @@ -420,67 +446,86 @@ 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))); + for(int i = 0, e = argvregs.size(); i < e; ++i) - { - unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, - Alpha::R19, Alpha::R20, Alpha::R21}; - - BuildMI(BB, Alpha::BIS, 2, args[i]).addReg(argvregs[i]).addReg(argvregs[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).getValueType()) { + default: Node->dump(); 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; + } + + } + //build the right kind of call + if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(1))) + { + Select(N.getOperand(0)); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); + } + else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N.getOperand(1))) + { + Select(N.getOperand(0)); + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); + } + else + { + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1); + AlphaLowering.restoreGP(BB); + } + + //push the result into a virtual register + // if (Result != 1) + // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); + + switch (Node->getValueType(0)) { + default: Node->dump(); assert(0 && "Unknown value type for call result!"); + case MVT::Other: return 1; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); + break; + case MVT::f32: + case MVT::f64: + BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0); + break; } - - //build the right kind of call - if (GlobalAddressSDNode *GASD = - dyn_cast(N.getOperand(1))) - { - Select(N.getOperand(0)); - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); - } - else if (ExternalSymbolSDNode *ESSDN = - dyn_cast(N.getOperand(1))) - { - Select(N.getOperand(0)); - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); - } - else { - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1); - AlphaLowering.restoreGP(BB); - } - - //push the result into a virtual register - // if (Result != 1) - // BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); - - switch (Node->getValueType(0)) { - default: assert(0 && "Unknown value type for call result!"); - case MVT::Other: return 1; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); - break; - } - return Result+N.ResNo; + return Result+N.ResNo; } - + case ISD::SIGN_EXTEND: case ISD::SIGN_EXTEND_INREG: { Tmp1 = SelectExpr(N.getOperand(0)); MVTSDNode* MVN = dyn_cast(Node); - std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; + //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; switch(MVN->getExtraValueType()) { default: - assert(0 && "Sign Extend InReg not there yet"); + Node->dump(); + assert(0 && "Sign Extend InReg not there yet"); break; case MVT::i32: { @@ -500,11 +545,12 @@ unsigned ISel::SelectExpr(SDOperand N) { { Tmp1 = SelectExpr(N.getOperand(0)); MVTSDNode* MVN = dyn_cast(Node); - std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; + //std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n"; switch(MVN->getExtraValueType()) { default: - assert(0 && "Zero Extend InReg not there yet"); + Node->dump(); + assert(0 && "Zero Extend InReg not there yet"); break; case MVT::i32: Tmp2 = 0xf0; break; case MVT::i16: Tmp2 = 0xfc; break; @@ -520,7 +566,7 @@ unsigned ISel::SelectExpr(SDOperand N) { if (SetCCSDNode *SetCC = dyn_cast(Node)) { if (MVT::isInteger(SetCC->getOperand(0).getValueType())) { switch (SetCC->getCondition()) { - default: assert(0 && "Unknown integer comparison!"); + default: Node->dump(); assert(0 && "Unknown integer comparison!"); case ISD::SETEQ: BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2); break; @@ -558,11 +604,16 @@ unsigned ISel::SelectExpr(SDOperand N) { } } else - assert(0 && "only integer"); + { + Node->dump(); + assert(0 && "only integer"); + } } else - assert(0 && "Not a setcc in setcc"); - + { + Node->dump(); + assert(0 && "Not a setcc in setcc"); + } return Result; case ISD::CopyFromReg: @@ -587,94 +638,159 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::SHL: case ISD::SRL: case ISD::MUL: - if(N.getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1))->getValue() >= 0 && - cast(N.getOperand(1))->getValue() <= 255) - { - switch(N.getOpcode()) { - 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(N.getOpcode()) { - 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 (N.getValueType()) { + default: Node->dump(); assert (0 && "unhandled type"); + case MVT::f64: + assert(N.getOpcode() == ISD::MUL && "only mul here please"); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::MULT, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case MVT::f32: + assert(N.getOpcode() == ISD::MUL && "only mul here please"); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::MULS, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case MVT::i64: + if(N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() >= 0 && + cast(N.getOperand(1))->getValue() <= 255) + { + switch(N.getOpcode()) { + 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(N.getOpcode()) { + 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); + } + break; + } return Result; case ISD::ADD: case ISD::SUB: { bool isAdd = N.getOpcode() == ISD::ADD; - - //FIXME: first check for Scaled Adds and Subs! - if(N.getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1))->getValue() >= 0 && - 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); - } - else if(N.getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1))->getValue() >= 0 && - 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); - - } - return Result; + + switch (N.getValueType()) { + default: Node->dump(); assert(0 && "Unhandled type"); + case MVT::i64: { + //FIXME: first check for Scaled Adds and Subs! + if(N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() >= 0 && + 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); + } + else if(N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() >= 0 && + 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); + } + } break; + case MVT::f64: + case MVT::f32: + if (N.getValueType() == MVT::f64) + Opc = isAdd ? Alpha::ADDT : Alpha::SUBT; + else + Opc = isAdd ? Alpha::ADDS : Alpha::SUBS; + // + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; } + return Result; + } case ISD::UREM: case ISD::SREM: case ISD::SDIV: case ISD::UDIV: - //FIXME: alpha really doesn't support any of these operations, - // the ops are expanded into special library calls with - // special calling conventions - switch(N.getOpcode()) { - 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; - }; + switch (N.getValueType()) { + default: Node->dump(); assert (0 && "unhandled type"); + case MVT::f64: + assert(N.getOpcode() == ISD::SDIV && "only div here please"); + Opc = Alpha::DIVT; + break; + case MVT::f32: + assert(N.getOpcode() == ISD::SDIV && "only div here please"); + Opc = Alpha::DIVS; + break; + case MVT::i64: + //FIXME: alpha really doesn't support any of these operations, + // the ops are expanded into special library calls with + // special calling conventions + switch(N.getOpcode()) { + 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; + } + break; + } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; +// case ISD::SINT_TO_FP: +// MVT::ValueType DestTy = N.getValueType(); +// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register +// Tmp2 = MakeReg(DestTy); +// Opc = DestTy == MVT::f64 ? ITOFT : ITOFS; +// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1); +// Opc = DestTy == MVT::f64 ? CVTQT : CVTQS; +// BuildMI(BB, Opc, 1, Result).addReg(Tmp1); +// // case ISD::UINT_TO_FP: + +// case ISD::FP_TO_SINT: +// assert (N.getValueType() == MVT::f64 && "Only can convert for doubles"); +// Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register +// Tmp2 = MakeReg(SrcTy); +// BuildMI(BB, CVTTQ, 1, Tmp2).addReg(Tmp1); +// BuildMI(BB, FTOIT, 1, Result).addReg(Tmp2); +// return result; + +// // case ISD::FP_TO_UINT: + case ISD::SELECT: { Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE @@ -790,12 +906,17 @@ void ISel::Select(SDOperand N) { 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: assert(0 && "All other types should have been promoted!!"); + 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); @@ -839,14 +960,17 @@ void ISel::Select(SDOperand N) { case ISD::TRUNCSTORE: { // truncstore chain, val, ptr :storety MVT::ValueType StoredTy = cast(Node)->getExtraValueType(); - assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!"); + if (StoredTy == MVT::i64) { + Node->dump(); + assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!"); + } Select(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(2)); switch (StoredTy) { - default: assert(0 && "Unhandled Type"); break; + default: Node->dump(); assert(0 && "Unhandled Type"); break; case MVT::i1: //FIXME: DAG does not promote this load case MVT::i8: Opc = Alpha::STB; break; case MVT::i16: Opc = Alpha::STW; break; diff --git a/lib/Target/Alpha/AlphaInstrFormats.td b/lib/Target/Alpha/AlphaInstrFormats.td index 39a2b043c69..44970b24354 100644 --- a/lib/Target/Alpha/AlphaInstrFormats.td +++ b/lib/Target/Alpha/AlphaInstrFormats.td @@ -83,10 +83,10 @@ class OFormL opcode, bits<7> fun, dag OL, string asmstr> : InstAlpha opcode, dag OL, string asmstr> : InstAlpha { +class FPForm opcode, bits<11> fun, dag OL, string asmstr> : InstAlpha { bits<5> Fa; bits<5> Fb; - bits<11> Function; + bits<11> Function = fun; bits<5> Fc; let Inst{25-21} = Fa; diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp index 9bb9accb424..1a730b31e77 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.cpp +++ b/lib/Target/Alpha/AlphaInstrInfo.cpp @@ -26,7 +26,7 @@ bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI, unsigned& sourceReg, unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); - if (oc == Alpha::BIS) { // or r1, r2, r2 + if (oc == Alpha::BIS || oc == Alpha::CPYS) { // or r1, r2, r2 // cpys r1 r2 r2 assert(MI.getNumOperands() == 3 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 1d5820f1526..61d615de204 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -43,7 +43,10 @@ let Defs = [R29] in let isCall = 1, Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, - R20, R21, R22, R23, R24, R25, R26, R27, R29], + R20, R21, R22, R23, R24, R25, R26, R27, 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 = [R27, R29] in def CALL : PseudoInstAlpha< (ops s64imm:$TARGET), "jsr $TARGET">; //Jump to subroutine @@ -250,19 +253,32 @@ let isCall = 1 in let Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27, R29] in def BSR : BForm<0x34, (ops GPRC:$RD, s21imm:$DISP), "bsr $RD,$DISP">; //Branch to subroutine +//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 def STL : MForm<0x2C, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stl $RA,$DISP($RB)">; // Store longword def STQ : MForm<0x2D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stq $RA,$DISP($RB)">; //Store quadword +//Load address def LDA : MForm<0x08, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "lda $RA,$DISP($RB)">; //Load address +def LDAH : MForm<0x08, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldah $RA,$DISP($RB)">; //Load address high +//Loads, int def LDL : MForm<0x28, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; // Load sign-extended longword def LDQ : MForm<0x29, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; //Load quadword def LDBU : MForm<0x0A, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldbu $RA,$DISP($RB)">; //Load zero-extended byte def LDWU : MForm<0x0C, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldwu $RA,$DISP($RB)">; //Load zero-extended word +//Stores, float +def STS : MForm<0x26, (ops FPRC:$RA, s16imm:$DISP, GPRC:$RB), "sts $RA,$DISP($RB)">; //Store S_floating +def STT : MForm<0x27, (ops FPRC:$RA, s16imm:$DISP, GPRC:$RB), "stt $RA,$DISP($RB)">; //Store T_floating +//Loads, float +def LDS : MForm<0x22, (ops FPRC:$RA, s16imm:$DISP, GPRC:$RB), "lds $RA,$DISP($RB)">; //Load S_floating +def LDT : MForm<0x23, (ops FPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldt $RA,$DISP($RB)">; //Load T_floating + + +//Branches, int def BEQ : BForm<0x39, (ops GPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Branch if = zero def BGE : BForm<0x3E, (ops GPRC:$RA, s21imm:$DISP), "bge $RA,$DISP">; //Branch if >= zero def BGT : BForm<0x3F, (ops GPRC:$RA, s21imm:$DISP), "bgt $RA,$DISP">; //Branch if > zero @@ -272,19 +288,42 @@ def BLE : BForm<0x3B, (ops GPRC:$RA, s21imm:$DISP), "ble $RA,$DISP">; //Branch i def BLT : BForm<0x3A, (ops GPRC:$RA, s21imm:$DISP), "blt $RA,$DISP">; //Branch if < zero def BNE : BForm<0x3D, (ops GPRC:$RA, s21imm:$DISP), "bne $RA,$DISP">; //Branch if != zero +//Branches, float +def FBEQ : BForm<0x31, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if = zero +def FBGE : BForm<0x36, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if >= zero +def FBGT : BForm<0x37, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if > zero +def FBLE : BForm<0x33, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if <= zero +def FBLT : BForm<0x32, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if < zero +def FBNE : BForm<0x35, (ops FPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Floating branch if != zero + +//Funky Floating point ops +def CPYS : FPForm<0x17, 0x020, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "cpys $RA,$RB,$RC">; //Copy sign +def CPYSE : FPForm<0x17, 0x022, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "cpyse $RA,$RB,$RC">; //Copy sign and exponent +def CPYSN : FPForm<0x17, 0x021, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "cpysn $RA,$RB,$RC">; //Copy sign negate + +//Basic Floating point ops +def ADDS : FPForm<0x16, 0x080, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "adds $RA,$RB,$RC">; //Add S_floating +def ADDT : FPForm<0x16, 0x0A0, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "addt $RA,$RB,$RC">; //Add T_floating +def SUBS : FPForm<0x16, 0x081, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subs $RA,$RB,$RC">; //Subtract S_floating +def SUBT : FPForm<0x16, 0x0A1, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subt $RA,$RB,$RC">; //Subtract T_floating +def DIVS : FPForm<0x16, 0x083, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divs $RA,$RB,$RC">; //Divide S_floating +def DIVT : FPForm<0x16, 0x0A3, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divt $RA,$RB,$RC">; //Divide T_floating +def MULS : FPForm<0x16, 0x082, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "muls $RA,$RB,$RC">; //Multiply S_floating +def MULT : FPForm<0x16, 0x0A2, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "mult $RA,$RB,$RC">; //Multiply T_floating +def SQRTS : FPForm<0x14, 0x08B, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "sqrts $RA,$RB,$RC">; //Square root S_floating +def SQRTT : FPForm<0x14, 0x0AB, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "sqrtt $RA,$RB,$RC">; //Square root T_floating + +//S_floating : IEEE Single +//T_floating : IEEE Double + //Mnemonic Format Opcode Description -//ADDF F-P 15.080 Add F_floating -//ADDG F-P 15.0A0 Add G_floating -//ADDS F-P 16.080 Add S_floating -//ADDT F-P 16.0A0 Add T_floating + //CALL_PAL Pcd 00 Trap to PALcode //ECB Mfc 18.E800 Evict cache block //EXCB Mfc 18.0400 Exception barrier //FETCH Mfc 18.8000 Prefetch data //FETCH_M Mfc 18.A000 Prefetch data, modify intent -//LDAH Mem 09 Load address high -//LDBU Mem 0A Load zero-extended byte -//LDWU Mem 0C Load zero-extended word + //LDL_L Mem 2A Load sign-extended longword locked //LDQ_L Mem 2B Load quadword locked //LDQ_U Mem 0B Load unaligned quadword @@ -292,77 +331,39 @@ def BNE : BForm<0x3D, (ops GPRC:$RA, s21imm:$DISP), "bne $RA,$DISP">; //Branch i //RC Mfc 18.E000 Read and clear //RPCC Mfc 18.C000 Read process cycle counter //RS Mfc 18.F000 Read and set + //STL_C Mem 2E Store longword conditional //STQ_C Mem 2F Store quadword conditional //STQ_U Mem 0F Store unaligned quadword + //TRAPB Mfc 18.0000 Trap barrier //WH64 Mfc 18.F800 Write hint  64 bytes //WMB Mfc 18.4400 Write memory barrier - -//CMPGEQ F-P 15.0A5 Compare G_floating equal -//CMPGLE F-P 15.0A7 Compare G_floating less than or equal -//CMPGLT F-P 15.0A6 Compare G_floating less than //CMPTEQ F-P 16.0A5 Compare T_floating equal //CMPTLE F-P 16.0A7 Compare T_floating less than or equal //CMPTLT F-P 16.0A6 Compare T_floating less than //CMPTUN F-P 16.0A4 Compare T_floating unordered -//CPYS F-P 17.020 Copy sign -//CPYSE F-P 17.022 Copy sign and exponent -//CPYSN F-P 17.021 Copy sign negate -//CVTDG F-P 15.09E Convert D_floating to G_floating -//CVTGD F-P 15.0AD Convert G_floating to D_floating -//CVTGF F-P 15.0AC Convert G_floating to F_floating -//CVTGQ F-P 15.0AF Convert G_floating to quadword + //CVTLQ F-P 17.010 Convert longword to quadword -//CVTQF F-P 15.0BC Convert quadword to F_floating -//CVTQG F-P 15.0BE Convert quadword to G_floating //CVTQL F-P 17.030 Convert quadword to longword //CVTQS F-P 16.0BC Convert quadword to S_floating //CVTQT F-P 16.0BE Convert quadword to T_floating //CVTST F-P 16.2AC Convert S_floating to T_floating //CVTTQ F-P 16.0AF Convert T_floating to quadword //CVTTS F-P 16.0AC Convert T_floating to S_floating -//DIVF F-P 15.083 Divide F_floating -//DIVG F-P 15.0A3 Divide G_floating -//DIVS F-P 16.083 Divide S_floating -//DIVT F-P 16.0A3 Divide T_floating -//FBEQ Bra 31 Floating branch if = zero -//FBGE Bra 36 Floating branch if ³ zero -//FBGT Bra 37 Floating branch if > zero -//FBLE Bra 33 Floating branch if £ zero -//FBLT Bra 32 Floating branch if < zero -//FBNE Bra 35 Floating branch if ¹ zero + //FCMOVEQ F-P 17.02A FCMOVE if = zero -//FCMOVGE F-P 17.02D FCMOVE if ³ zero +//FCMOVGE F-P 17.02D FCMOVE if >= zero //FCMOVGT F-P 17.02F FCMOVE if > zero -//FCMOVLE F-P 17.02E FCMOVE if £ zero +//FCMOVLE F-P 17.02E FCMOVE if <= zero //FCMOVLT F-P 17.02C FCMOVE if < zero -//FCMOVNE F-P 17.02B FCMOVE if ¹ zero +//FCMOVNE F-P 17.02B FCMOVE if != zero + //FTOIS F-P 1C.78 Floating to integer move, S_floating //FTOIT F-P 1C.70 Floating to integer move, T_floating -//ITOFF F-P 14.014 Integer to floating move, F_floating //ITOFS F-P 14.004 Integer to floating move, S_floating //ITOFT F-P 14.024 Integer to floating move, T_floating -//LDF Mem 20 Load F_floating -//LDG Mem 21 Load G_floating -//LDS Mem 22 Load S_floating -//LDT Mem 23 Load T_floating + //MF_FPCR F-P 17.025 Move from FPCR //MT_FPCR F-P 17.024 Move to FPCR -//MULF F-P 15.082 Multiply F_floating -//MULG F-P 15.0A2 Multiply G_floating -//MULS F-P 16.082 Multiply S_floating -//MULT F-P 16.0A2 Multiply T_floating -//SQRTF F-P 14.08A Square root F_floating -//SQRTG F-P 14.0AA Square root G_floating -//SQRTS F-P 14.08B Square root S_floating -//SQRTT F-P 14.0AB Square root T_floating -//STF Mem 24 Store F_floating -//STG Mem 25 Store G_floating -//STS Mem 26 Store S_floating -//STT Mem 27 Store T_floating -//SUBF F-P 15.081 Subtract F_floating -//SUBG F-P 15.0A1 Subtract G_floating -//SUBS F-P 16.081 Subtract S_floating -//SUBT F-P 16.0A1 Subtract T_floating diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index 807193a3877..0c5ca352020 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -48,7 +48,7 @@ void AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, int FrameIdx) const { - std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; + //std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addImm(FrameIdx * 8).addReg(Alpha::R30); // assert(0 && "TODO"); @@ -58,7 +58,7 @@ void AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx) const{ - std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; + //std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0, DestReg); BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addImm(FrameIdx * 8).addReg(Alpha::R30); // assert(0 && "TODO"); @@ -71,8 +71,8 @@ void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, // std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; if (RC == Alpha::GPRCRegisterClass) { BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); -// } else if (RC == Alpha::FPRCRegisterClass) { -// BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg); + } else if (RC == Alpha::FPRCRegisterClass) { + BuildMI(MBB, MI, Alpha::CPYS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); } else { std::cerr << "Attempt to copy register that is not GPR or FPR"; abort(); @@ -205,14 +205,21 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { // adjust stack pointer: r30 -= numbytes - if (NumBytes <= 32000) //FIXME: do this better - { - MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-NumBytes).addReg(Alpha::R30); - MBB.insert(MBBI, MI); - } else { - std::cerr << "Too big a stack frame\n"; - abort(); - } + if (NumBytes <= 32767) { + MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-NumBytes).addReg(Alpha::R30); + MBB.insert(MBBI, MI); + } else if (NumBytes <= 32767 * 65536) { + long y = NumBytes / 65536; + if (NumBytes % 65536 > 32767) + ++y; + MI=BuildMI(Alpha::LDAH, 2, Alpha::R30).addImm(-y).addReg(Alpha::R30); + MBB.insert(MBBI, MI); + MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-(NumBytes - y * 65536)).addReg(Alpha::R30); + MBB.insert(MBBI, MI); + } else { + std::cerr << "Too big a stack frame\n"; + abort(); + } } void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,