mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-04 07:32:13 +00:00
Various Thumb mode load / store isel bug fixes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33472 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9e38e32dcd
commit
79d4326b00
@ -71,6 +71,9 @@ public:
|
||||
|
||||
bool SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base,
|
||||
SDOperand &Offset);
|
||||
bool SelectThumbAddrModeRI5(SDOperand Op, SDOperand N, unsigned Scale,
|
||||
SDOperand &Base, SDOperand &Offset,
|
||||
SDOperand &OffImm);
|
||||
bool SelectThumbAddrModeS1(SDOperand Op, SDOperand N, SDOperand &Base,
|
||||
SDOperand &Offset, SDOperand &OffImm);
|
||||
bool SelectThumbAddrModeS2(SDOperand Op, SDOperand N, SDOperand &Base,
|
||||
@ -78,7 +81,7 @@ public:
|
||||
bool SelectThumbAddrModeS4(SDOperand Op, SDOperand N, SDOperand &Base,
|
||||
SDOperand &Offset, SDOperand &OffImm);
|
||||
bool SelectThumbAddrModeSP(SDOperand Op, SDOperand N, SDOperand &Base,
|
||||
SDOperand &Offset);
|
||||
SDOperand &OffImm);
|
||||
|
||||
bool SelectShifterOperandReg(SDOperand Op, SDOperand N, SDOperand &A,
|
||||
SDOperand &B, SDOperand &C);
|
||||
@ -355,13 +358,16 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale,
|
||||
TargetLowering &TLI, SelectionDAG *CurDAG,
|
||||
SDOperand &Base, SDOperand &Offset,
|
||||
SDOperand &OffImm) {
|
||||
if (N.getOpcode() == ISD::FrameIndex)
|
||||
return false;
|
||||
|
||||
bool
|
||||
ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDOperand Op, SDOperand N,
|
||||
unsigned Scale, SDOperand &Base,
|
||||
SDOperand &Offset, SDOperand &OffImm) {
|
||||
if (Scale == 4) {
|
||||
SDOperand TmpBase, TmpOffImm;
|
||||
if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm))
|
||||
return false; // We want to select tLDRspi / tSTRspi instead.
|
||||
}
|
||||
|
||||
if (N.getOpcode() != ISD::ADD) {
|
||||
Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
|
||||
Offset = CurDAG->getRegister(0, MVT::i32);
|
||||
@ -392,29 +398,46 @@ static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale,
|
||||
bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op, SDOperand N,
|
||||
SDOperand &Base, SDOperand &Offset,
|
||||
SDOperand &OffImm) {
|
||||
return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset, OffImm);
|
||||
return SelectThumbAddrModeRI5(Op, N, 1, Base, Offset, OffImm);
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op, SDOperand N,
|
||||
SDOperand &Base, SDOperand &Offset,
|
||||
SDOperand &OffImm) {
|
||||
return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset, OffImm);
|
||||
return SelectThumbAddrModeRI5(Op, N, 2, Base, Offset, OffImm);
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op, SDOperand N,
|
||||
SDOperand &Base, SDOperand &Offset,
|
||||
SDOperand &OffImm) {
|
||||
return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset, OffImm);
|
||||
return SelectThumbAddrModeRI5(Op, N, 4, Base, Offset, OffImm);
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op, SDOperand N,
|
||||
SDOperand &Base, SDOperand &Offset) {
|
||||
SDOperand &Base, SDOperand &OffImm) {
|
||||
if (N.getOpcode() == ISD::FrameIndex) {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
OffImm = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (N.getOpcode() == ISD::ADD &&
|
||||
N.getOperand(0).getOpcode() == ISD::FrameIndex) {
|
||||
// If the RHS is + imm8 * scale, fold into addr mode.
|
||||
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
||||
int RHSC = (int)RHS->getValue();
|
||||
if ((RHSC & 3) == 0) { // The constant is implicitly multiplied.
|
||||
RHSC >>= 2;
|
||||
if (RHSC >= 0 && RHSC < 256) {
|
||||
int FI = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
|
||||
Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
|
||||
OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -492,6 +515,8 @@ SDNode *ARMDAGToDAGISel::Select(SDOperand Op) {
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
}
|
||||
case ISD::MUL:
|
||||
if (Subtarget->isThumb())
|
||||
break;
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
|
||||
unsigned RHSV = C->getValue();
|
||||
if (!RHSV) break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user