From: Andrew Lenharth Date: Sat, 2 Apr 2005 21:06:51 +0000 (+0000) Subject: Try several things. 1) drop /i from FP ops 2) factor out FP to Int moves and provide... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0eaf6ce2ef61f7769849baecded6a0deaa5c5f25;p=oota-llvm.git Try several things. 1) drop /i from FP ops 2) factor out FP to Int moves and provide 21264 support for those 3) match not 4) match ornot andnot xornot git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21046 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index 4a40aa93e11..9393b92373d 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -36,7 +36,7 @@ namespace llvm { cl::opt EnableAlphaIDIV("enable-alpha-intfpdiv", cl::desc("Use the FP div instruction for integer div when possible"), cl::Hidden); - cl::opt EnableAlpha("enable-alpha-ftoi", + cl::opt EnableAlphaFTOI("enable-alpha-ftoi", cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"), cl::Hidden); } @@ -333,6 +333,8 @@ public: void SelectAddr(SDOperand N, unsigned& Reg, long& offset); void SelectBranchCC(SDOperand N); + void MoveFP2Int(unsigned src, unsigned dst, bool isDouble); + void MoveInt2FP(unsigned src, unsigned dst, bool isDouble); }; } @@ -376,6 +378,46 @@ static unsigned GetSymVersion(unsigned opcode) } } +void ISel::MoveFP2Int(unsigned src, unsigned dst, bool isDouble) +{ + unsigned Opc; + if (EnableAlphaFTOI) { + Opc = isDouble ? Alpha::FTOIT : Alpha::FTOIS; + BuildMI(BB, Opc, 1, dst).addReg(src); + } else { + //The hard way: + // Spill the integer to memory and reload it from there. + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8); + + Opc = isDouble ? Alpha::STT : Alpha::STS; + BuildMI(BB, Opc, 3).addReg(src).addFrameIndex(FrameIdx).addReg(Alpha::F31); + Opc = isDouble ? Alpha::LDQ : Alpha::LDL; + BuildMI(BB, Alpha::LDQ, 2, dst).addFrameIndex(FrameIdx).addReg(Alpha::F31); + } +} + +void ISel::MoveInt2FP(unsigned src, unsigned dst, bool isDouble) +{ + unsigned Opc; + if (EnableAlphaFTOI) { + Opc = isDouble?Alpha::ITOFT:Alpha::ITOFS; + BuildMI(BB, Opc, 1, dst).addReg(src); + } else { + //The hard way: + // Spill the integer to memory and reload it from there. + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8); + + Opc = isDouble ? Alpha::STQ : Alpha::STL; + BuildMI(BB, Opc, 3).addReg(src).addFrameIndex(FrameIdx).addReg(Alpha::F31); + Opc = isDouble ? Alpha::LDT : Alpha::LDS; + BuildMI(BB, Opc, 2, dst).addFrameIndex(FrameIdx).addReg(Alpha::F31); + } +} + //Check to see if the load is a constant offset from a base register void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset) { @@ -615,16 +657,13 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) else { Tmp1 = SelectExpr(N.getOperand(0)); //Cond - // Spill the cond to memory and reload it from there. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; - MachineFunction *F = BB->getParent(); - int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8); - unsigned Tmp4 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31); - //now ideally, we don't have to do anything to the flag... - // Get the condition into the zero flag. - BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4); + BuildMI(BB, Alpha::FCMOVEQ_INT, 3, Result).addReg(TV).addReg(FV).addReg(Tmp1); +// // Spill the cond to memory and reload it from there. +// unsigned Tmp4 = MakeReg(MVT::f64); +// MoveIntFP(Tmp1, Tmp4, true); +// //now ideally, we don't have to do anything to the flag... +// // Get the condition into the zero flag. +// BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4); return Result; } } @@ -784,25 +823,9 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) && "only quads can be loaded from"); Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register Tmp2 = MakeReg(MVT::f64); - - //The hard way: - // Spill the integer to memory and reload it from there. - unsigned Size = MVT::getSizeInBits(MVT::i64)/8; - MachineFunction *F = BB->getParent(); - int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size); - - BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdx).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDT, 2, Tmp2).addFrameIndex(FrameIdx).addReg(Alpha::F31); + MoveInt2FP(Tmp1, Tmp2, true); Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS; 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); - return Result; } } @@ -1082,38 +1105,27 @@ unsigned ISel::SelectExpr(SDOperand N) { return Result+N.ResNo; } - case ISD::SIGN_EXTEND: - abort(); - case ISD::SIGN_EXTEND_INREG: { //do SDIV opt for all levels of ints if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV) { - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; - MachineFunction *F = BB->getParent(); - int FrameIdxL = F->getFrameInfo()->CreateStackObject(Size, 8); - int FrameIdxR = F->getFrameInfo()->CreateStackObject(Size, 8); - int FrameIdxF = F->getFrameInfo()->CreateStackObject(Size, 8); unsigned Tmp4 = MakeReg(MVT::f64); unsigned Tmp5 = MakeReg(MVT::f64); unsigned Tmp6 = MakeReg(MVT::f64); unsigned Tmp7 = MakeReg(MVT::f64); unsigned Tmp8 = MakeReg(MVT::f64); unsigned Tmp9 = MakeReg(MVT::f64); - - BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxL).addReg(Alpha::F31); - BuildMI(BB, Alpha::STQ, 3).addReg(Tmp2).addFrameIndex(FrameIdxR).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdxL).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDT, 2, Tmp5).addFrameIndex(FrameIdxR).addReg(Alpha::F31); + + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + MoveInt2FP(Tmp1, Tmp4, true); + MoveInt2FP(Tmp2, Tmp5, true); BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4); BuildMI(BB, Alpha::CVTQT, 1, Tmp7).addReg(Tmp5); BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7); BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8); - BuildMI(BB, Alpha::STT, 3).addReg(Tmp9).addFrameIndex(FrameIdxF).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31); + MoveFP2Int(Tmp9, Result, true); return Result; } @@ -1362,30 +1374,7 @@ unsigned ISel::SelectExpr(SDOperand N) { BuildMI(BB, Alpha::ADDQi, 2, Tmp4).addReg(Alpha::R31).addImm(1); Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP; BuildMI(BB, Opc, 3, Result).addReg(Tmp4).addImm(0).addReg(Tmp3); - -// // Spill the FP to memory and reload it from there. -// unsigned Size = MVT::getSizeInBits(MVT::f64)/8; -// MachineFunction *F = BB->getParent(); -// int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8); -// unsigned Tmp4 = MakeReg(MVT::f64); -// BuildMI(BB, Alpha::CVTTQ, 1, Tmp4).addReg(Tmp3); -// BuildMI(BB, Alpha::STT, 3).addReg(Tmp4).addFrameIndex(FrameIdx).addReg(Alpha::F31); -// unsigned Tmp5 = MakeReg(MVT::i64); -// BuildMI(BB, Alpha::LDQ, 2, Tmp5).addFrameIndex(FrameIdx).addReg(Alpha::F31); - -// //now, set result based on Tmp5 -// //Set Tmp6 if fp cmp was false -// unsigned Tmp6 = MakeReg(MVT::i64); -// BuildMI(BB, Alpha::CMPEQ, 2, Tmp6).addReg(Tmp5).addReg(Alpha::R31); -// //and invert -// BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp6).addReg(Alpha::R31); - } - // else - // { - // Node->dump(); - // assert(0 && "Not a setcc in setcc"); - // } } return Result; } @@ -1409,9 +1398,49 @@ unsigned ISel::SelectExpr(SDOperand N) { //Most of the plain arithmetic and logic share the same form, and the same //constant immediate test - case ISD::AND: case ISD::OR: + //Match Not + if (N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->isAllOnesValue()) + { + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp1); + return Result; + } + //Fall through + case ISD::AND: case ISD::XOR: + //Check operand(0) == Not + if (N.getOperand(0).getOpcode() == ISD::OR && + N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(0).getOperand(1))->isAllOnesValue()) + { + switch(opcode) { + case ISD::AND: Opc = Alpha::BIC; break; + case ISD::OR: Opc = Alpha::ORNOT; break; + case ISD::XOR: Opc = Alpha::EQV; break; + } + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } + //Check operand(1) == Not + if (N.getOperand(1).getOpcode() == ISD::OR && + N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1).getOperand(1))->isAllOnesValue()) + { + switch(opcode) { + case ISD::AND: Opc = Alpha::BIC; break; + case ISD::OR: Opc = Alpha::ORNOT; break; + case ISD::XOR: Opc = Alpha::EQV; break; + } + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(0)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } + //Fall through case ISD::SHL: case ISD::SRL: case ISD::SRA: @@ -1512,25 +1541,15 @@ unsigned ISel::SelectExpr(SDOperand N) { MVT::ValueType SrcType = N.getOperand(0).getValueType(); assert (SrcType == MVT::f32 || SrcType == MVT::f64); Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register - - //The hard way: - // Spill the integer to memory and reload it from there. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; - MachineFunction *F = BB->getParent(); - int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, 8); - - //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); + MoveFP2Int(Tmp2, Result, true); return Result; } diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 0cd20dd8f94..6b18f2b74b3 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -96,7 +96,10 @@ let Uses = [R29], // "lda $RES,1($$31)\n\tfbne $COND, 42f\n\tbis $$31,$$31,$RES\n42:\n">; //An even better improvement on the Int = SetCC(FP): SelectCC! +//These are evil because they hide control flow in a MBB +//really the ISel should emit multiple MBB let isTwoAddress = 1 in { +//Conditional move of an int based on a FP CC def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), @@ -106,7 +109,11 @@ let isTwoAddress = 1 in { "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; - +//Conditional move of an FP based on a Int CC + def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; } //*********************** @@ -380,14 +387,14 @@ def CPYSE : FPForm<0x17, 0x022, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "cpyse $RA,$ 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/sui $RA,$RB,$RC">; //Add S_floating -def ADDT : FPForm<0x16, 0x0A0, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "addt/sui $RA,$RB,$RC">; //Add T_floating -def SUBS : FPForm<0x16, 0x081, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subs/sui $RA,$RB,$RC">; //Subtract S_floating -def SUBT : FPForm<0x16, 0x0A1, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subt/sui $RA,$RB,$RC">; //Subtract T_floating -def DIVS : FPForm<0x16, 0x083, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divs/sui $RA,$RB,$RC">; //Divide S_floating -def DIVT : FPForm<0x16, 0x0A3, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divt/sui $RA,$RB,$RC">; //Divide T_floating -def MULS : FPForm<0x16, 0x082, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "muls/sui $RA,$RB,$RC">; //Multiply S_floating -def MULT : FPForm<0x16, 0x0A2, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "mult/sui $RA,$RB,$RC">; //Multiply T_floating +def ADDS : FPForm<0x16, 0x080, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "adds/su $RA,$RB,$RC">; //Add S_floating +def ADDT : FPForm<0x16, 0x0A0, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "addt/su $RA,$RB,$RC">; //Add T_floating +def SUBS : FPForm<0x16, 0x081, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subs/su $RA,$RB,$RC">; //Subtract S_floating +def SUBT : FPForm<0x16, 0x0A1, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "subt/su $RA,$RB,$RC">; //Subtract T_floating +def DIVS : FPForm<0x16, 0x083, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divs/su $RA,$RB,$RC">; //Divide S_floating +def DIVT : FPForm<0x16, 0x0A3, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "divt/su $RA,$RB,$RC">; //Divide T_floating +def MULS : FPForm<0x16, 0x082, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "muls/su $RA,$RB,$RC">; //Multiply S_floating +def MULT : FPForm<0x16, 0x0A2, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "mult/su $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