mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 06:09:05 +00:00
Fix VLDMQ and VSTMQ instructions to use the correct encoding and address modes.
These instructions are only needed for codegen, so I've removed all the explicit encoding bits for now; they should be set in the same way as the for VLDMD and VSTMD whenever we add encodings for VFP. The use of addrmode5 requires that the instructions be custom-selected so that the number of registers can be set in the AM5Opc value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99309 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b2dc2df7d2
commit
df9a4f0591
@ -745,7 +745,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
} else {
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQ)).
|
||||
addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
||||
.addFrameIndex(FI)
|
||||
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||
.addMemOperand(MMO));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -793,7 +795,9 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
.addMemOperand(MMO));
|
||||
} else {
|
||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQ), DestReg)
|
||||
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
|
||||
.addFrameIndex(FI)
|
||||
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||
.addMemOperand(MMO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1701,6 +1701,35 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
|
||||
ResNode = SelectARMIndexedLoad(N);
|
||||
if (ResNode)
|
||||
return ResNode;
|
||||
|
||||
// VLDMQ must be custom-selected for "v2f64 load" to set the AM5Opc value.
|
||||
if (Subtarget->hasVFP2() &&
|
||||
N->getValueType(0).getSimpleVT().SimpleTy == MVT::v2f64) {
|
||||
SDValue Chain = N->getOperand(0);
|
||||
SDValue AM5Opc =
|
||||
CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32);
|
||||
SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
|
||||
SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
|
||||
SDValue Ops[] = { N->getOperand(1), AM5Opc, Pred, PredReg, Chain };
|
||||
return CurDAG->getMachineNode(ARM::VLDMQ, dl, MVT::v2f64, MVT::Other,
|
||||
Ops, 5);
|
||||
}
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
case ISD::STORE: {
|
||||
// VSTMQ must be custom-selected for "v2f64 store" to set the AM5Opc value.
|
||||
if (Subtarget->hasVFP2() &&
|
||||
N->getOperand(1).getValueType().getSimpleVT().SimpleTy == MVT::v2f64) {
|
||||
SDValue Chain = N->getOperand(0);
|
||||
SDValue AM5Opc =
|
||||
CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32);
|
||||
SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
|
||||
SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
|
||||
SDValue Ops[] = { N->getOperand(1), N->getOperand(2),
|
||||
AM5Opc, Pred, PredReg, Chain };
|
||||
return CurDAG->getMachineNode(ARM::VSTMQ, dl, MVT::Other, Ops, 6);
|
||||
}
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
|
@ -1503,12 +1503,6 @@ class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm,
|
||||
pattern> {
|
||||
}
|
||||
|
||||
class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: NeonXI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "",
|
||||
pattern> {
|
||||
}
|
||||
|
||||
class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
|
||||
dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string dt, string asm, string cstr, list<dag> pattern>
|
||||
|
@ -115,19 +115,20 @@ def h64imm : Operand<i64> {
|
||||
// NEON load / store instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Use vldmia to load a Q register as a D register pair.
|
||||
// This is equivalent to VLDMD except that it has a Q register operand.
|
||||
def VLDMQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
|
||||
"vldmia", "$addr, ${dst:dregpair}",
|
||||
[(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
|
||||
let Inst{27-25} = 0b110;
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{23} = 1; // U bit
|
||||
let Inst{20} = 1;
|
||||
let Inst{11-8} = 0b1011;
|
||||
}
|
||||
|
||||
let mayLoad = 1 in {
|
||||
// Use vldmia to load a Q register as a D register pair.
|
||||
// This is equivalent to VLDMD except that it has a Q register operand
|
||||
// instead of a pair of D registers.
|
||||
def VLDMQ
|
||||
: AXDI5<(outs QPR:$dst), (ins addrmode5:$addr, pred:$p),
|
||||
IndexModeNone, IIC_fpLoadm,
|
||||
"vldm${addr:submode}${p}\t${addr:base}, ${dst:dregpair}", "", []>;
|
||||
def VLDMQ_UPD
|
||||
: AXDI5<(outs QPR:$dst, GPR:$wb), (ins addrmode5:$addr, pred:$p),
|
||||
IndexModeUpd, IIC_fpLoadm,
|
||||
"vldm${addr:submode}${p}\t${addr:base}!, ${dst:dregpair}",
|
||||
"$addr.base = $wb", []>;
|
||||
|
||||
// Use vld1 to load a Q register as a D register pair.
|
||||
// This alternative to VLDMQ allows an alignment to be specified.
|
||||
// This is equivalent to VLD1q64 except that it has a Q register operand.
|
||||
@ -140,19 +141,20 @@ def VLD1q_UPD
|
||||
"${dst:dregpair}, $addr$offset", "$addr.addr = $wb", []>;
|
||||
} // mayLoad = 1
|
||||
|
||||
// Use vstmia to store a Q register as a D register pair.
|
||||
// This is equivalent to VSTMD except that it has a Q register operand.
|
||||
def VSTMQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem,
|
||||
"vstmia", "$addr, ${src:dregpair}",
|
||||
[(store (v2f64 QPR:$src), addrmode4:$addr)]> {
|
||||
let Inst{27-25} = 0b110;
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{23} = 1; // U bit
|
||||
let Inst{20} = 0;
|
||||
let Inst{11-8} = 0b1011;
|
||||
}
|
||||
|
||||
let mayStore = 1 in {
|
||||
// Use vstmia to store a Q register as a D register pair.
|
||||
// This is equivalent to VSTMD except that it has a Q register operand
|
||||
// instead of a pair of D registers.
|
||||
def VSTMQ
|
||||
: AXDI5<(outs), (ins QPR:$src, addrmode5:$addr, pred:$p),
|
||||
IndexModeNone, IIC_fpStorem,
|
||||
"vstm${addr:submode}${p}\t${addr:base}, ${src:dregpair}", "", []>;
|
||||
def VSTMQ_UPD
|
||||
: AXDI5<(outs GPR:$wb), (ins QPR:$src, addrmode5:$addr, pred:$p),
|
||||
IndexModeUpd, IIC_fpStorem,
|
||||
"vstm${addr:submode}${p}\t${addr:base}!, ${src:dregpair}",
|
||||
"$addr.base = $wb", []>;
|
||||
|
||||
// Use vst1 to store a Q register as a D register pair.
|
||||
// This alternative to VSTMQ allows an alignment to be specified.
|
||||
// This is equivalent to VST1q64 except that it has a Q register operand.
|
||||
|
Loading…
Reference in New Issue
Block a user