mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Use VLDM / VSTM to spill/reload 128-bit Neon registers
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78468 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -655,11 +655,15 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
|
||||||
.addReg(SrcReg, getKillRegState(isKill))
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
.addFrameIndex(FI).addImm(0));
|
.addFrameIndex(FI).addImm(0));
|
||||||
} else {
|
} else if (RC == ARM::SPRRegisterClass) {
|
||||||
assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
|
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
|
||||||
.addReg(SrcReg, getKillRegState(isKill))
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
.addFrameIndex(FI).addImm(0));
|
.addFrameIndex(FI).addImm(0));
|
||||||
|
} else {
|
||||||
|
assert(RC == ARM::QPRRegisterClass && "Unknown regclass!");
|
||||||
|
// FIXME: Neon instructions should support predicates
|
||||||
|
BuildMI(MBB, I, DL, get(ARM::VSTRQ)).addReg(SrcReg, getKillRegState(isKill))
|
||||||
|
.addFrameIndex(FI).addImm(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,10 +680,13 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
} else if (RC == ARM::DPRRegisterClass || RC == ARM::DPR_VFP2RegisterClass) {
|
} else if (RC == ARM::DPRRegisterClass || RC == ARM::DPR_VFP2RegisterClass) {
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
|
||||||
.addFrameIndex(FI).addImm(0));
|
.addFrameIndex(FI).addImm(0));
|
||||||
} else {
|
} else if (RC == ARM::SPRRegisterClass) {
|
||||||
assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
|
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
|
||||||
.addFrameIndex(FI).addImm(0));
|
.addFrameIndex(FI).addImm(0));
|
||||||
|
} else {
|
||||||
|
assert(RC == ARM::QPRRegisterClass && "Unknown regclass!");
|
||||||
|
// FIXME: Neon instructions should support predicates
|
||||||
|
BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg).addFrameIndex(FI).addImm(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,6 +935,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
|
|||||||
NumBits = 8;
|
NumBits = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ARMII::AddrMode4:
|
||||||
|
break;
|
||||||
case ARMII::AddrMode5: {
|
case ARMII::AddrMode5: {
|
||||||
ImmIdx = FrameRegIdx+1;
|
ImmIdx = FrameRegIdx+1;
|
||||||
InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
|
InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
|
||||||
|
@@ -78,6 +78,8 @@ public:
|
|||||||
SDValue &Offset, SDValue &Opc);
|
SDValue &Offset, SDValue &Opc);
|
||||||
bool SelectAddrMode3Offset(SDValue Op, SDValue N,
|
bool SelectAddrMode3Offset(SDValue Op, SDValue N,
|
||||||
SDValue &Offset, SDValue &Opc);
|
SDValue &Offset, SDValue &Opc);
|
||||||
|
bool SelectAddrMode4(SDValue Op, SDValue N, SDValue &Addr,
|
||||||
|
SDValue &Mode);
|
||||||
bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
|
bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
|
||||||
SDValue &Offset);
|
SDValue &Offset);
|
||||||
bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update,
|
bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update,
|
||||||
@@ -383,6 +385,12 @@ bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARMDAGToDAGISel::SelectAddrMode4(SDValue Op, SDValue N,
|
||||||
|
SDValue &Addr, SDValue &Mode) {
|
||||||
|
Addr = N;
|
||||||
|
Mode = CurDAG->getTargetConstant(0, MVT::i32);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
|
bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
|
||||||
SDValue &Base, SDValue &Offset) {
|
SDValue &Base, SDValue &Offset) {
|
||||||
|
@@ -1199,6 +1199,10 @@ class NI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
|
|||||||
: NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, asm, "", pattern> {
|
: NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, asm, "", pattern> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NI4<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern>
|
||||||
|
: NeonI<oops, iops, AddrMode4, IndexModeNone, itin, asm, "", pattern> {
|
||||||
|
}
|
||||||
|
|
||||||
class NLdSt<dag oops, dag iops, InstrItinClass itin,
|
class NLdSt<dag oops, dag iops, InstrItinClass itin,
|
||||||
string asm, list<dag> pattern>
|
string asm, list<dag> pattern>
|
||||||
: NeonI<oops, iops, AddrMode6, IndexModeNone, itin, asm, "", pattern> {
|
: NeonI<oops, iops, AddrMode6, IndexModeNone, itin, asm, "", pattern> {
|
||||||
|
@@ -298,7 +298,7 @@ def am3offset : Operand<i32>,
|
|||||||
// addrmode4 := reg, <mode|W>
|
// addrmode4 := reg, <mode|W>
|
||||||
//
|
//
|
||||||
def addrmode4 : Operand<i32>,
|
def addrmode4 : Operand<i32>,
|
||||||
ComplexPattern<i32, 2, "", []> {
|
ComplexPattern<i32, 2, "SelectAddrMode4", []> {
|
||||||
let PrintMethod = "printAddrMode4Operand";
|
let PrintMethod = "printAddrMode4Operand";
|
||||||
let MIOperandInfo = (ops GPR, i32imm);
|
let MIOperandInfo = (ops GPR, i32imm);
|
||||||
}
|
}
|
||||||
|
@@ -138,10 +138,10 @@ def VLDMS : NI<(outs),
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Use vldmia to load a Q register as a D register pair.
|
// Use vldmia to load a Q register as a D register pair.
|
||||||
def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr),
|
def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr),
|
||||||
NoItinerary,
|
NoItinerary,
|
||||||
"vldmia $addr, ${dst:dregpair}",
|
"vldmia $addr, ${dst:dregpair}",
|
||||||
[(set QPR:$dst, (v2f64 (load GPR:$addr)))]> {
|
[(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> {
|
||||||
let Inst{27-25} = 0b110;
|
let Inst{27-25} = 0b110;
|
||||||
let Inst{24} = 0; // P bit
|
let Inst{24} = 0; // P bit
|
||||||
let Inst{23} = 1; // U bit
|
let Inst{23} = 1; // U bit
|
||||||
@@ -150,10 +150,10 @@ def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr),
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use vstmia to store a Q register as a D register pair.
|
// Use vstmia to store a Q register as a D register pair.
|
||||||
def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr),
|
def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr),
|
||||||
NoItinerary,
|
NoItinerary,
|
||||||
"vstmia $addr, ${src:dregpair}",
|
"vstmia $addr, ${src:dregpair}",
|
||||||
[(store (v2f64 QPR:$src), GPR:$addr)]> {
|
[(store (v2f64 QPR:$src), addrmode4:$addr)]> {
|
||||||
let Inst{27-25} = 0b110;
|
let Inst{27-25} = 0b110;
|
||||||
let Inst{24} = 0; // P bit
|
let Inst{24} = 0; // P bit
|
||||||
let Inst{23} = 1; // U bit
|
let Inst{23} = 1; // U bit
|
||||||
@@ -161,7 +161,6 @@ def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr),
|
|||||||
let Inst{11-9} = 0b101;
|
let Inst{11-9} = 0b101;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// VLD1 : Vector Load (multiple single elements)
|
// VLD1 : Vector Load (multiple single elements)
|
||||||
class VLD1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
|
class VLD1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
|
||||||
: NLdSt<(outs DPR:$dst), (ins addrmode6:$addr),
|
: NLdSt<(outs DPR:$dst), (ins addrmode6:$addr),
|
||||||
|
Reference in New Issue
Block a user