mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
Use new PPC-specific nodes to represent shifts which require the 6-bit
amount handling that PPC provides. These are generated by the lowering code and prevents the dag combiner from assuming (rightfully) that the shifts don't only look at 5 bits. This fixes a miscompilation of crafty with the new front-end. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24615 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eda80a0dec
commit
4172b10ca1
@ -279,14 +279,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
||||||
DAG.getConstant(32, MVT::i32), Amt);
|
DAG.getConstant(32, MVT::i32), Amt);
|
||||||
SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt);
|
SDOperand Tmp2 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Amt);
|
||||||
SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1);
|
SDOperand Tmp3 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Tmp1);
|
||||||
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
||||||
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
||||||
DAG.getConstant(-32U, MVT::i32));
|
DAG.getConstant(-32U, MVT::i32));
|
||||||
SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5);
|
SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5);
|
||||||
SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
||||||
SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt);
|
SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt);
|
||||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||||
}
|
}
|
||||||
case ISD::SRL: {
|
case ISD::SRL: {
|
||||||
@ -305,14 +305,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
||||||
DAG.getConstant(32, MVT::i32), Amt);
|
DAG.getConstant(32, MVT::i32), Amt);
|
||||||
SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt);
|
SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt);
|
||||||
SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1);
|
SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1);
|
||||||
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
||||||
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
||||||
DAG.getConstant(-32U, MVT::i32));
|
DAG.getConstant(-32U, MVT::i32));
|
||||||
SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5);
|
SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5);
|
||||||
SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
|
||||||
SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt);
|
SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt);
|
||||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||||
}
|
}
|
||||||
case ISD::SRA: {
|
case ISD::SRA: {
|
||||||
@ -330,13 +330,13 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
|
||||||
DAG.getConstant(32, MVT::i32), Amt);
|
DAG.getConstant(32, MVT::i32), Amt);
|
||||||
SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt);
|
SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt);
|
||||||
SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1);
|
SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1);
|
||||||
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
|
||||||
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
|
||||||
DAG.getConstant(-32U, MVT::i32));
|
DAG.getConstant(-32U, MVT::i32));
|
||||||
SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5);
|
SDOperand Tmp6 = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Tmp5);
|
||||||
SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt);
|
SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt);
|
||||||
SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32),
|
SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32),
|
||||||
Tmp4, Tmp6, ISD::SETLE);
|
Tmp4, Tmp6, ISD::SETLE);
|
||||||
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
|
||||||
|
@ -49,6 +49,12 @@ namespace llvm {
|
|||||||
/// GlobalBaseReg - On Darwin, this node represents the result of the mflr
|
/// GlobalBaseReg - On Darwin, this node represents the result of the mflr
|
||||||
/// at function entry, used for PIC code.
|
/// at function entry, used for PIC code.
|
||||||
GlobalBaseReg,
|
GlobalBaseReg,
|
||||||
|
|
||||||
|
|
||||||
|
/// These nodes represent the 32-bit PPC shifts that operate on 6-bit
|
||||||
|
/// shift amounts. These nodes are generated by the multi-precision shift
|
||||||
|
/// code.
|
||||||
|
SRL, SRA, SHL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,15 @@ def PPCfsel : SDNode<"PPCISD::FSEL",
|
|||||||
def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>;
|
def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>;
|
||||||
def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>;
|
def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>;
|
||||||
|
|
||||||
|
// These nodes represent the 32-bit PPC shifts that operate on 6-bit shift
|
||||||
|
// amounts. These nodes are generated by the multi-precision shift code.
|
||||||
|
def SDT_PPCShiftOp : SDTypeProfile<1, 2, [ // PPCshl, PPCsra, PPCsrl
|
||||||
|
SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>
|
||||||
|
]>;
|
||||||
|
def PPCsrl : SDNode<"PPCISD::SRL" , SDT_PPCShiftOp>;
|
||||||
|
def PPCsra : SDNode<"PPCISD::SRA" , SDT_PPCShiftOp>;
|
||||||
|
def PPCshl : SDNode<"PPCISD::SHL" , SDT_PPCShiftOp>;
|
||||||
|
|
||||||
// These are target-independent nodes, but have target-specific formats.
|
// These are target-independent nodes, but have target-specific formats.
|
||||||
def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
|
def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
|
||||||
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
|
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
|
||||||
@ -430,19 +439,19 @@ def SLD : XForm_6<31, 27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
|||||||
[(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
[(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||||
def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"slw $rA, $rS, $rB", IntGeneral,
|
"slw $rA, $rS, $rB", IntGeneral,
|
||||||
[(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>;
|
[(set GPRC:$rA, (PPCshl GPRC:$rS, GPRC:$rB))]>;
|
||||||
def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||||
"srd $rA, $rS, $rB", IntRotateD,
|
"srd $rA, $rS, $rB", IntRotateD,
|
||||||
[(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
[(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||||
def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"srw $rA, $rS, $rB", IntGeneral,
|
"srw $rA, $rS, $rB", IntGeneral,
|
||||||
[(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>;
|
[(set GPRC:$rA, (PPCsrl GPRC:$rS, GPRC:$rB))]>;
|
||||||
def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||||
"srad $rA, $rS, $rB", IntRotateD,
|
"srad $rA, $rS, $rB", IntRotateD,
|
||||||
[(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
[(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||||
def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||||
"sraw $rA, $rS, $rB", IntShift,
|
"sraw $rA, $rS, $rB", IntShift,
|
||||||
[(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>;
|
[(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>;
|
||||||
let isStore = 1 in {
|
let isStore = 1 in {
|
||||||
def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
||||||
"stbx $rS, $rA, $rB", LdStGeneral>;
|
"stbx $rS, $rA, $rB", LdStGeneral>;
|
||||||
@ -891,6 +900,16 @@ def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI tglobaladdr:$in)>;
|
|||||||
def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)),
|
def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)),
|
||||||
(ADDIS GPRC:$in, tglobaladdr:$g)>;
|
(ADDIS GPRC:$in, tglobaladdr:$g)>;
|
||||||
|
|
||||||
|
// Standard shifts. These are represented separately from the real shifts above
|
||||||
|
// so that we can distinguish between shifts that allow 5-bit and 6-bit shift
|
||||||
|
// amounts.
|
||||||
|
def : Pat<(sra GPRC:$rS, GPRC:$rB),
|
||||||
|
(SRAW GPRC:$rS, GPRC:$rB)>;
|
||||||
|
def : Pat<(srl GPRC:$rS, GPRC:$rB),
|
||||||
|
(SRW GPRC:$rS, GPRC:$rB)>;
|
||||||
|
def : Pat<(shl GPRC:$rS, GPRC:$rB),
|
||||||
|
(SLW GPRC:$rS, GPRC:$rB)>;
|
||||||
|
|
||||||
// Same as above, but using a temporary. FIXME: implement temporaries :)
|
// Same as above, but using a temporary. FIXME: implement temporaries :)
|
||||||
/*
|
/*
|
||||||
def : Pattern<(xor GPRC:$in, imm:$imm),
|
def : Pattern<(xor GPRC:$in, imm:$imm),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user