mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 19:29:31 +00:00
Set shift amount to Extend
Implement ISD::FABS and ISD::FNEG nodes Implement SHL_PARTS, SRL_PARTS, and SRA_PARTS Generate PowerPC 'fneg', 'fabs', and 'fnabs' instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21018 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e21710757d
commit
27eeb00a1a
@ -54,10 +54,7 @@ namespace {
|
|||||||
setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
|
setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
|
||||||
setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
|
setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
|
||||||
|
|
||||||
// We don't support these yet.
|
setShiftAmountFlavor(Extend); // shl X, 32 == 0
|
||||||
setOperationAction(ISD::FNEG , MVT::f64 , Expand);
|
|
||||||
setOperationAction(ISD::FABS , MVT::f64 , Expand);
|
|
||||||
|
|
||||||
addLegalFPImmediate(+0.0); // Necessary for FSEL
|
addLegalFPImmediate(+0.0); // Necessary for FSEL
|
||||||
addLegalFPImmediate(-0.0); //
|
addLegalFPImmediate(-0.0); //
|
||||||
|
|
||||||
@ -762,7 +759,22 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
|||||||
.addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
|
.addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ISD::FNEG:
|
||||||
|
if (ISD::FABS == N.getOperand(0).getOpcode()) {
|
||||||
|
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
|
||||||
|
BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
|
||||||
|
} else {
|
||||||
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
|
BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
case ISD::FABS:
|
||||||
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
|
BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
|
||||||
|
return Result;
|
||||||
|
|
||||||
case ISD::FP_ROUND:
|
case ISD::FP_ROUND:
|
||||||
assert (DestType == MVT::f32 &&
|
assert (DestType == MVT::f32 &&
|
||||||
N.getOperand(0).getValueType() == MVT::f64 &&
|
N.getOperand(0).getValueType() == MVT::f64 &&
|
||||||
@ -874,29 +886,34 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
unsigned &Reg = ExprMap[N];
|
unsigned &Reg = ExprMap[N];
|
||||||
if (Reg) return Reg;
|
if (Reg) return Reg;
|
||||||
|
|
||||||
if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::ADD_PARTS &&
|
switch (N.getOpcode()) {
|
||||||
N.getOpcode() != ISD::SUB_PARTS)
|
default:
|
||||||
Reg = Result = (N.getValueType() != MVT::Other) ?
|
Reg = Result = (N.getValueType() != MVT::Other) ?
|
||||||
MakeReg(N.getValueType()) : 1;
|
MakeReg(N.getValueType()) : 1;
|
||||||
else {
|
break;
|
||||||
|
case ISD::CALL:
|
||||||
// If this is a call instruction, make sure to prepare ALL of the result
|
// If this is a call instruction, make sure to prepare ALL of the result
|
||||||
// values as well as the chain.
|
// values as well as the chain.
|
||||||
if (N.getOpcode() == ISD::CALL) {
|
if (Node->getNumValues() == 1)
|
||||||
if (Node->getNumValues() == 1)
|
Reg = Result = 1; // Void call, just a chain.
|
||||||
Reg = Result = 1; // Void call, just a chain.
|
else {
|
||||||
else {
|
|
||||||
Result = MakeReg(Node->getValueType(0));
|
|
||||||
ExprMap[N.getValue(0)] = Result;
|
|
||||||
for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
|
|
||||||
ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
|
|
||||||
ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Result = MakeReg(Node->getValueType(0));
|
Result = MakeReg(Node->getValueType(0));
|
||||||
ExprMap[N.getValue(0)] = Result;
|
ExprMap[N.getValue(0)] = Result;
|
||||||
for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i)
|
for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
|
||||||
ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
|
ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
|
||||||
|
ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ISD::ADD_PARTS:
|
||||||
|
case ISD::SUB_PARTS:
|
||||||
|
case ISD::SHL_PARTS:
|
||||||
|
case ISD::SRL_PARTS:
|
||||||
|
case ISD::SRA_PARTS:
|
||||||
|
Result = MakeReg(Node->getValueType(0));
|
||||||
|
ExprMap[N.getValue(0)] = Result;
|
||||||
|
for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i)
|
||||||
|
ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DestType == MVT::f64 || DestType == MVT::f32)
|
if (DestType == MVT::f64 || DestType == MVT::f32)
|
||||||
@ -1265,11 +1282,71 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)
|
||||||
InVals.push_back(SelectExpr(N.getOperand(i)));
|
InVals.push_back(SelectExpr(N.getOperand(i)));
|
||||||
if (N.getOpcode() == ISD::ADD_PARTS) {
|
if (N.getOpcode() == ISD::ADD_PARTS) {
|
||||||
BuildMI(BB, PPC::ADDC, 2, Result+1).addReg(InVals[0]).addReg(InVals[2]);
|
BuildMI(BB, PPC::ADDC, 2, Result).addReg(InVals[0]).addReg(InVals[2]);
|
||||||
BuildMI(BB, PPC::ADDE, 2, Result).addReg(InVals[1]).addReg(InVals[3]);
|
BuildMI(BB, PPC::ADDE, 2, Result+1).addReg(InVals[1]).addReg(InVals[3]);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(BB, PPC::SUBFC, 2, Result+1).addReg(InVals[2]).addReg(InVals[0]);
|
BuildMI(BB, PPC::SUBFC, 2, Result).addReg(InVals[2]).addReg(InVals[0]);
|
||||||
BuildMI(BB, PPC::SUBFE, 2, Result).addReg(InVals[3]).addReg(InVals[1]);
|
BuildMI(BB, PPC::SUBFE, 2, Result+1).addReg(InVals[3]).addReg(InVals[1]);
|
||||||
|
}
|
||||||
|
return Result+N.ResNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ISD::SHL_PARTS:
|
||||||
|
case ISD::SRA_PARTS:
|
||||||
|
case ISD::SRL_PARTS: {
|
||||||
|
assert(N.getNumOperands() == 3 && N.getValueType() == MVT::i32 &&
|
||||||
|
"Not an i64 shift!");
|
||||||
|
unsigned ShiftOpLo = SelectExpr(N.getOperand(0));
|
||||||
|
unsigned ShiftOpHi = SelectExpr(N.getOperand(1));
|
||||||
|
unsigned SHReg = SelectExpr(N.getOperand(2));
|
||||||
|
Tmp1 = MakeReg(MVT::i32);
|
||||||
|
Tmp2 = MakeReg(MVT::i32);
|
||||||
|
Tmp3 = MakeReg(MVT::i32);
|
||||||
|
unsigned Tmp4 = MakeReg(MVT::i32);
|
||||||
|
unsigned Tmp5 = MakeReg(MVT::i32);
|
||||||
|
unsigned Tmp6 = MakeReg(MVT::i32);
|
||||||
|
BuildMI(BB, PPC::SUBFIC, 2, Tmp1).addReg(SHReg).addSImm(32);
|
||||||
|
if (ISD::SHL_PARTS == opcode) {
|
||||||
|
BuildMI(BB, PPC::SLW, 2, Tmp2).addReg(ShiftOpHi).addReg(SHReg);
|
||||||
|
BuildMI(BB, PPC::SRW, 2, Tmp3).addReg(ShiftOpLo).addReg(Tmp1);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
|
||||||
|
BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32);
|
||||||
|
BuildMI(BB, PPC::SLW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Result+1).addReg(Tmp4).addReg(Tmp6);
|
||||||
|
BuildMI(BB, PPC::SLW, 2, Result).addReg(ShiftOpLo).addReg(SHReg);
|
||||||
|
} else if (ISD::SRL_PARTS == opcode) {
|
||||||
|
BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg);
|
||||||
|
BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
|
||||||
|
BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32);
|
||||||
|
BuildMI(BB, PPC::SRW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp4).addReg(Tmp6);
|
||||||
|
BuildMI(BB, PPC::SRW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg);
|
||||||
|
} else {
|
||||||
|
MachineBasicBlock *TmpMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *OldMBB = BB;
|
||||||
|
MachineFunction *F = BB->getParent();
|
||||||
|
ilist<MachineBasicBlock>::iterator It = BB; ++It;
|
||||||
|
F->getBasicBlockList().insert(It, TmpMBB);
|
||||||
|
F->getBasicBlockList().insert(It, PhiMBB);
|
||||||
|
BB->addSuccessor(TmpMBB);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg);
|
||||||
|
BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
|
||||||
|
BuildMI(BB, PPC::ADDICo, 2, Tmp5).addReg(SHReg).addSImm(-32);
|
||||||
|
BuildMI(BB, PPC::SRAW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5);
|
||||||
|
BuildMI(BB, PPC::SRAW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg);
|
||||||
|
BuildMI(BB, PPC::BLE, 2).addReg(PPC::CR0).addMBB(PhiMBB);
|
||||||
|
// Select correct least significant half if the shift amount > 32
|
||||||
|
BB = TmpMBB;
|
||||||
|
unsigned Tmp7 = MakeReg(MVT::i32);
|
||||||
|
BuildMI(BB, PPC::OR, 2, Tmp7).addReg(Tmp6).addReg(Tmp6);
|
||||||
|
TmpMBB->addSuccessor(PhiMBB);
|
||||||
|
BB = PhiMBB;
|
||||||
|
BuildMI(BB, PPC::PHI, 4, Result).addReg(Tmp4).addMBB(OldMBB)
|
||||||
|
.addReg(Tmp7).addMBB(TmpMBB);
|
||||||
}
|
}
|
||||||
return Result+N.ResNo;
|
return Result+N.ResNo;
|
||||||
}
|
}
|
||||||
|
@ -308,8 +308,12 @@ def FCTIDZ : XForm_26<63, 815, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB),
|
|||||||
"fctidz $frD, $frB">;
|
"fctidz $frD, $frB">;
|
||||||
def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"fctiwz $frD, $frB">;
|
"fctiwz $frD, $frB">;
|
||||||
|
def FABS : XForm_26<63, 264, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
"fabs $frD, $frB">;
|
||||||
def FMR : XForm_26<63, 72, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FMR : XForm_26<63, 72, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"fmr $frD, $frB">;
|
"fmr $frD, $frB">;
|
||||||
|
def FNABS : XForm_26<63, 136, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
"fnabs $frD, $frB">;
|
||||||
def FNEG : XForm_26<63, 40, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FNEG : XForm_26<63, 40, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"fneg $frD, $frB">;
|
"fneg $frD, $frB">;
|
||||||
def FRSP : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FRSP : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
Loading…
Reference in New Issue
Block a user