mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
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
This commit is contained in:
parent
1231aa3fa6
commit
0eaf6ce2ef
@ -36,7 +36,7 @@ namespace llvm {
|
||||
cl::opt<bool> EnableAlphaIDIV("enable-alpha-intfpdiv",
|
||||
cl::desc("Use the FP div instruction for integer div when possible"),
|
||||
cl::Hidden);
|
||||
cl::opt<bool> EnableAlpha("enable-alpha-ftoi",
|
||||
cl::opt<bool> 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<ConstantSDNode>(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<ConstantSDNode>(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<ConstantSDNode>(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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user