mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-10 02:25:47 +00:00
Bring back VLD1q and VST1q and use them for reloading / spilling Q registers. This allows folding loads and stores into VMOVQ.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103692 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -776,19 +776,16 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
RC == ARM::QPR_8RegisterClass) {
|
RC == ARM::QPR_8RegisterClass) {
|
||||||
// FIXME: Neon instructions should support predicates
|
// FIXME: Neon instructions should support predicates
|
||||||
if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
|
if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
|
||||||
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST1q64))
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q))
|
||||||
.addFrameIndex(FI).addImm(128);
|
.addFrameIndex(FI).addImm(128)
|
||||||
MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
|
.addMemOperand(MMO));
|
||||||
AddDefaultPred(MIB.addMemOperand(MMO));
|
|
||||||
} else {
|
} else {
|
||||||
MachineInstrBuilder MIB =
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQ))
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD))
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
.addFrameIndex(FI)
|
.addFrameIndex(FI)
|
||||||
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
|
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||||
.addMemOperand(MMO);
|
.addMemOperand(MMO));
|
||||||
MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
|
|
||||||
AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert((RC == ARM::QQPRRegisterClass ||
|
assert((RC == ARM::QQPRRegisterClass ||
|
||||||
@@ -826,7 +823,6 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
MachineFunction &MF = *MBB.getParent();
|
MachineFunction &MF = *MBB.getParent();
|
||||||
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
||||||
unsigned Align = MFI.getObjectAlignment(FI);
|
unsigned Align = MFI.getObjectAlignment(FI);
|
||||||
|
|
||||||
MachineMemOperand *MMO =
|
MachineMemOperand *MMO =
|
||||||
MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
|
MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
|
||||||
MachineMemOperand::MOLoad, 0,
|
MachineMemOperand::MOLoad, 0,
|
||||||
@@ -853,18 +849,14 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
RC == ARM::QPR_VFP2RegisterClass ||
|
RC == ARM::QPR_VFP2RegisterClass ||
|
||||||
RC == ARM::QPR_8RegisterClass) {
|
RC == ARM::QPR_8RegisterClass) {
|
||||||
if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
|
if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
|
||||||
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD1q64));
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q), DestReg)
|
||||||
MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
|
.addFrameIndex(FI).addImm(128)
|
||||||
MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
|
.addMemOperand(MMO));
|
||||||
AddDefaultPred(MIB.addFrameIndex(FI).addImm(128).addMemOperand(MMO));
|
|
||||||
} else {
|
} else {
|
||||||
MachineInstrBuilder MIB =
|
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQ), DestReg)
|
||||||
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD))
|
.addFrameIndex(FI)
|
||||||
.addFrameIndex(FI)
|
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||||
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
|
.addMemOperand(MMO));
|
||||||
.addMemOperand(MMO);
|
|
||||||
MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
|
|
||||||
AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert((RC == ARM::QQPRRegisterClass ||
|
assert((RC == ARM::QQPRRegisterClass ||
|
||||||
@@ -1004,8 +996,7 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
|||||||
DstSubReg)
|
DstSubReg)
|
||||||
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
||||||
}
|
}
|
||||||
}
|
} else if (Opc == ARM::VMOVD || Opc == ARM::VMOVDneon) {
|
||||||
else if (Opc == ARM::VMOVD) {
|
|
||||||
unsigned Pred = MI->getOperand(2).getImm();
|
unsigned Pred = MI->getOperand(2).getImm();
|
||||||
unsigned PredReg = MI->getOperand(3).getReg();
|
unsigned PredReg = MI->getOperand(3).getReg();
|
||||||
if (OpNum == 0) { // move -> store
|
if (OpNum == 0) { // move -> store
|
||||||
@@ -1031,6 +1022,56 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
|||||||
DstSubReg)
|
DstSubReg)
|
||||||
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
||||||
}
|
}
|
||||||
|
} else if (Opc == ARM::VMOVQ) {
|
||||||
|
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
||||||
|
unsigned Pred = MI->getOperand(2).getImm();
|
||||||
|
unsigned PredReg = MI->getOperand(3).getReg();
|
||||||
|
if (OpNum == 0) { // move -> store
|
||||||
|
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||||
|
unsigned SrcSubReg = MI->getOperand(1).getSubReg();
|
||||||
|
bool isKill = MI->getOperand(1).isKill();
|
||||||
|
bool isUndef = MI->getOperand(1).isUndef();
|
||||||
|
if (MFI.getObjectAlignment(FI) >= 16 &&
|
||||||
|
getRegisterInfo().canRealignStack(MF)) {
|
||||||
|
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VST1q))
|
||||||
|
.addFrameIndex(FI).addImm(128)
|
||||||
|
.addReg(SrcReg,
|
||||||
|
getKillRegState(isKill) | getUndefRegState(isUndef),
|
||||||
|
SrcSubReg)
|
||||||
|
.addImm(Pred).addReg(PredReg);
|
||||||
|
} else {
|
||||||
|
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTMQ))
|
||||||
|
.addReg(SrcReg,
|
||||||
|
getKillRegState(isKill) | getUndefRegState(isUndef),
|
||||||
|
SrcSubReg)
|
||||||
|
.addFrameIndex(FI).addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||||
|
.addImm(Pred).addReg(PredReg);
|
||||||
|
}
|
||||||
|
} else { // move -> load
|
||||||
|
unsigned DstReg = MI->getOperand(0).getReg();
|
||||||
|
unsigned DstSubReg = MI->getOperand(0).getSubReg();
|
||||||
|
bool isDead = MI->getOperand(0).isDead();
|
||||||
|
bool isUndef = MI->getOperand(0).isUndef();
|
||||||
|
if (MFI.getObjectAlignment(FI) >= 16 &&
|
||||||
|
getRegisterInfo().canRealignStack(MF)) {
|
||||||
|
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLD1q))
|
||||||
|
.addReg(DstReg,
|
||||||
|
RegState::Define |
|
||||||
|
getDeadRegState(isDead) |
|
||||||
|
getUndefRegState(isUndef),
|
||||||
|
DstSubReg)
|
||||||
|
.addFrameIndex(FI).addImm(128).addImm(Pred).addReg(PredReg);
|
||||||
|
} else {
|
||||||
|
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDMQ))
|
||||||
|
.addReg(DstReg,
|
||||||
|
RegState::Define |
|
||||||
|
getDeadRegState(isDead) |
|
||||||
|
getUndefRegState(isUndef),
|
||||||
|
DstSubReg)
|
||||||
|
.addFrameIndex(FI).addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
|
||||||
|
.addImm(Pred).addReg(PredReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewMI;
|
return NewMI;
|
||||||
@@ -1059,10 +1100,9 @@ ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
|
|||||||
Opc == ARM::tMOVtgpr2gpr ||
|
Opc == ARM::tMOVtgpr2gpr ||
|
||||||
Opc == ARM::tMOVgpr2tgpr) {
|
Opc == ARM::tMOVgpr2tgpr) {
|
||||||
return true;
|
return true;
|
||||||
} else if (Opc == ARM::VMOVS || Opc == ARM::VMOVD) {
|
} else if (Opc == ARM::VMOVS || Opc == ARM::VMOVD ||
|
||||||
|
Opc == ARM::VMOVDneon || Opc == ARM::VMOVQ) {
|
||||||
return true;
|
return true;
|
||||||
} else if (Opc == ARM::VMOVDneon || Opc == ARM::VMOVQ) {
|
|
||||||
return false; // FIXME
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@@ -123,6 +123,13 @@ def VLDMQ
|
|||||||
: AXDI5<(outs QPR:$dst), (ins addrmode5:$addr, pred:$p),
|
: AXDI5<(outs QPR:$dst), (ins addrmode5:$addr, pred:$p),
|
||||||
IndexModeNone, IIC_fpLoadm,
|
IndexModeNone, IIC_fpLoadm,
|
||||||
"vldm${addr:submode}${p}\t${addr:base}, ${dst:dregpair}", "", []>;
|
"vldm${addr:submode}${p}\t${addr:base}, ${dst:dregpair}", "", []>;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
def VLD1q
|
||||||
|
: NLdSt<0,0b10,0b1010,0b1100, (outs QPR:$dst), (ins addrmode6:$addr),
|
||||||
|
IIC_VLD1, "vld1", "64", "${dst:dregpair}, $addr", "", []>;
|
||||||
} // mayLoad = 1
|
} // mayLoad = 1
|
||||||
|
|
||||||
let mayStore = 1 in {
|
let mayStore = 1 in {
|
||||||
@@ -133,6 +140,13 @@ def VSTMQ
|
|||||||
: AXDI5<(outs), (ins QPR:$src, addrmode5:$addr, pred:$p),
|
: AXDI5<(outs), (ins QPR:$src, addrmode5:$addr, pred:$p),
|
||||||
IndexModeNone, IIC_fpStorem,
|
IndexModeNone, IIC_fpStorem,
|
||||||
"vstm${addr:submode}${p}\t${addr:base}, ${src:dregpair}", "", []>;
|
"vstm${addr:submode}${p}\t${addr:base}, ${src:dregpair}", "", []>;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
def VST1q
|
||||||
|
: NLdSt<0,0b00,0b1010,0b1100, (outs), (ins addrmode6:$addr, QPR:$src),
|
||||||
|
IIC_VST, "vst1", "64", "${src:dregpair}, $addr", "", []>;
|
||||||
} // mayStore = 1
|
} // mayStore = 1
|
||||||
|
|
||||||
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
|
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
|
||||||
|
Reference in New Issue
Block a user