mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Refactor setExecutionDomain to be clearer about what it's doing and more robust.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162844 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -3397,13 +3397,28 @@ ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const {
|
|||||||
return std::make_pair(ExeGeneric, 0);
|
return std::make_pair(ExeGeneric, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI,
|
||||||
|
unsigned SReg, unsigned &Lane) {
|
||||||
|
unsigned DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_0, &ARM::DPRRegClass);
|
||||||
|
Lane = 0;
|
||||||
|
|
||||||
|
if (DReg != ARM::NoRegister)
|
||||||
|
return DReg;
|
||||||
|
|
||||||
|
Lane = 1;
|
||||||
|
DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1, &ARM::DPRRegClass);
|
||||||
|
|
||||||
|
assert(DReg && "S-register with no D super-register?");
|
||||||
|
return DReg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
||||||
unsigned DstReg, SrcReg, DReg;
|
unsigned DstReg, SrcReg, DReg;
|
||||||
unsigned Lane;
|
unsigned Lane;
|
||||||
MachineInstrBuilder MIB(MI);
|
MachineInstrBuilder MIB(MI);
|
||||||
const TargetRegisterInfo *TRI = &getRegisterInfo();
|
const TargetRegisterInfo *TRI = &getRegisterInfo();
|
||||||
bool isKill;
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("cannot handle opcode!");
|
llvm_unreachable("cannot handle opcode!");
|
||||||
@@ -3414,77 +3429,70 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
|
|||||||
|
|
||||||
// Zap the predicate operands.
|
// Zap the predicate operands.
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VORRd");
|
assert(!isPredicated(MI) && "Cannot predicate a VORRd");
|
||||||
MI->RemoveOperand(3);
|
|
||||||
MI->RemoveOperand(2);
|
|
||||||
|
|
||||||
// Change to a VORRd which requires two identical use operands.
|
// Source instruction is %DDst = VMOVD %DSrc, 14, %noreg (; implicits)
|
||||||
|
DstReg = MI->getOperand(0).getReg();
|
||||||
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
|
|
||||||
|
for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
|
||||||
|
MI->RemoveOperand(i-1);
|
||||||
|
|
||||||
|
// Change to a %DDst = VORRd %DSrc, %DSrc, 14, %noreg (; implicits)
|
||||||
MI->setDesc(get(ARM::VORRd));
|
MI->setDesc(get(ARM::VORRd));
|
||||||
|
AddDefaultPred(MIB.addReg(DstReg, RegState::Define)
|
||||||
// Add the extra source operand and new predicates.
|
.addReg(SrcReg)
|
||||||
// This will go before any implicit ops.
|
.addReg(SrcReg));
|
||||||
AddDefaultPred(MachineInstrBuilder(MI).addOperand(MI->getOperand(1)));
|
|
||||||
break;
|
break;
|
||||||
case ARM::VMOVRS:
|
case ARM::VMOVRS:
|
||||||
if (Domain != ExeNEON)
|
if (Domain != ExeNEON)
|
||||||
break;
|
break;
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VGETLN");
|
assert(!isPredicated(MI) && "Cannot predicate a VGETLN");
|
||||||
|
|
||||||
|
// Source instruction is %RDst = VMOVRS %SSrc, 14, %noreg (; implicits)
|
||||||
DstReg = MI->getOperand(0).getReg();
|
DstReg = MI->getOperand(0).getReg();
|
||||||
SrcReg = MI->getOperand(1).getReg();
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
|
|
||||||
DReg = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_0, &ARM::DPRRegClass);
|
for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
|
||||||
Lane = 0;
|
MI->RemoveOperand(i-1);
|
||||||
if (DReg == ARM::NoRegister) {
|
|
||||||
DReg = TRI->getMatchingSuperReg(SrcReg, ARM::ssub_1, &ARM::DPRRegClass);
|
|
||||||
Lane = 1;
|
|
||||||
assert(DReg && "S-register with no D super-register?");
|
|
||||||
}
|
|
||||||
|
|
||||||
MI->RemoveOperand(3);
|
DReg = getCorrespondingDRegAndLane(TRI, SrcReg, Lane);
|
||||||
MI->RemoveOperand(2);
|
|
||||||
MI->RemoveOperand(1);
|
|
||||||
|
|
||||||
|
// Convert to %RDst = VGETLNi32 %DSrc, Lane, 14, %noreg (; imps)
|
||||||
|
// Note that DSrc has been widened and the other lane may be undef, which
|
||||||
|
// contaminates the entire register.
|
||||||
MI->setDesc(get(ARM::VGETLNi32));
|
MI->setDesc(get(ARM::VGETLNi32));
|
||||||
MIB.addReg(DReg);
|
AddDefaultPred(MIB.addReg(DstReg, RegState::Define)
|
||||||
MIB.addImm(Lane);
|
.addReg(DReg, RegState::Undef)
|
||||||
|
.addImm(Lane));
|
||||||
|
|
||||||
MIB->getOperand(1).setIsUndef();
|
// The old source should be an implicit use, otherwise we might think it
|
||||||
|
// was dead before here.
|
||||||
MIB.addReg(SrcReg, RegState::Implicit);
|
MIB.addReg(SrcReg, RegState::Implicit);
|
||||||
|
|
||||||
AddDefaultPred(MIB);
|
|
||||||
break;
|
break;
|
||||||
case ARM::VMOVSR:
|
case ARM::VMOVSR:
|
||||||
if (Domain != ExeNEON)
|
if (Domain != ExeNEON)
|
||||||
break;
|
break;
|
||||||
assert(!isPredicated(MI) && "Cannot predicate a VSETLN");
|
assert(!isPredicated(MI) && "Cannot predicate a VSETLN");
|
||||||
|
|
||||||
|
// Source instruction is %SDst = VMOVSR %RSrc, 14, %noreg (; implicits)
|
||||||
DstReg = MI->getOperand(0).getReg();
|
DstReg = MI->getOperand(0).getReg();
|
||||||
SrcReg = MI->getOperand(1).getReg();
|
SrcReg = MI->getOperand(1).getReg();
|
||||||
DReg = TRI->getMatchingSuperReg(DstReg, ARM::ssub_0, &ARM::DPRRegClass);
|
|
||||||
Lane = 0;
|
|
||||||
if (DReg == ARM::NoRegister) {
|
|
||||||
DReg = TRI->getMatchingSuperReg(DstReg, ARM::ssub_1, &ARM::DPRRegClass);
|
|
||||||
Lane = 1;
|
|
||||||
assert(DReg && "S-register with no D super-register?");
|
|
||||||
}
|
|
||||||
isKill = MI->getOperand(0).isKill();
|
|
||||||
|
|
||||||
MI->RemoveOperand(3);
|
for (unsigned i = MI->getDesc().getNumOperands(); i; --i)
|
||||||
MI->RemoveOperand(2);
|
MI->RemoveOperand(i-1);
|
||||||
MI->RemoveOperand(1);
|
|
||||||
MI->RemoveOperand(0);
|
|
||||||
|
|
||||||
|
DReg = getCorrespondingDRegAndLane(TRI, DstReg, Lane);
|
||||||
|
|
||||||
|
// Convert to %DDst = VSETLNi32 %DDst, %RSrc, Lane, 14, %noreg (; imps)
|
||||||
|
// Again DDst may be undefined at the beginning of this instruction.
|
||||||
MI->setDesc(get(ARM::VSETLNi32));
|
MI->setDesc(get(ARM::VSETLNi32));
|
||||||
MIB.addReg(DReg, RegState::Define);
|
AddDefaultPred(MIB.addReg(DReg, RegState::Define)
|
||||||
MIB.addReg(DReg, RegState::Undef);
|
.addReg(DReg, RegState::Undef)
|
||||||
MIB.addReg(SrcReg);
|
.addReg(SrcReg)
|
||||||
MIB.addImm(Lane);
|
.addImm(Lane));
|
||||||
|
|
||||||
if (isKill)
|
// The destination must be marked as set.
|
||||||
MIB->addRegisterKilled(DstReg, TRI, true);
|
MIB.addReg(DstReg, RegState::Define | RegState::Implicit);
|
||||||
MIB->addRegisterDefined(DstReg, TRI);
|
|
||||||
|
|
||||||
AddDefaultPred(MIB);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user