mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-18 22:26:16 +00:00
[ARM] Move the implementation of the target hooks related to copy-related
instruction from ARMInstrInfo to ARMBaseInstrInfo. That way, thumb mode can also benefit from the advanced copy optimization. <rdar://problem/12702965> llvm-svn: 216274
This commit is contained in:
parent
49775e0173
commit
d358e84d9c
@ -4490,3 +4490,72 @@ bool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::getRegSequenceLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isRegSequenceLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VMOVDRR:
|
||||
// dX = VMOVDRR rY, rZ
|
||||
// is the same as:
|
||||
// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1
|
||||
// Populate the InputRegs accordingly.
|
||||
// rY
|
||||
const MachineOperand *MOReg = &MI.getOperand(1);
|
||||
InputRegs.push_back(
|
||||
RegSubRegPairAndIdx(MOReg->getReg(), MOReg->getSubReg(), ARM::ssub_0));
|
||||
// rZ
|
||||
MOReg = &MI.getOperand(2);
|
||||
InputRegs.push_back(
|
||||
RegSubRegPairAndIdx(MOReg->getReg(), MOReg->getSubReg(), ARM::ssub_1));
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::getExtractSubregLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPairAndIdx &InputReg) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isExtractSubregLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VMOVRRD:
|
||||
// rX, rY = VMOVRRD dZ
|
||||
// is the same as:
|
||||
// rX = EXTRACT_SUBREG dZ, ssub_0
|
||||
// rY = EXTRACT_SUBREG dZ, ssub_1
|
||||
const MachineOperand &MOReg = MI.getOperand(2);
|
||||
InputReg.Reg = MOReg.getReg();
|
||||
InputReg.SubReg = MOReg.getSubReg();
|
||||
InputReg.SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::getInsertSubregLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg,
|
||||
RegSubRegPairAndIdx &InsertedReg) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isInsertSubregLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VSETLNi32:
|
||||
// dX = VSETLNi32 dY, rZ, imm
|
||||
const MachineOperand &MOBaseReg = MI.getOperand(1);
|
||||
const MachineOperand &MOInsertedReg = MI.getOperand(2);
|
||||
const MachineOperand &MOIndex = MI.getOperand(3);
|
||||
BaseReg.Reg = MOBaseReg.getReg();
|
||||
BaseReg.SubReg = MOBaseReg.getSubReg();
|
||||
|
||||
InsertedReg.Reg = MOInsertedReg.getReg();
|
||||
InsertedReg.SubReg = MOInsertedReg.getSubReg();
|
||||
InsertedReg.SubIdx = MOIndex.getImm() == 0 ? ARM::ssub_0 : ARM::ssub_1;
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
@ -39,6 +39,53 @@ protected:
|
||||
unsigned LoadImmOpc, unsigned LoadOpc,
|
||||
Reloc::Model RM) const;
|
||||
|
||||
/// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
|
||||
/// the list is modeled as <Reg:SubReg, SubIdx>.
|
||||
/// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce
|
||||
/// two elements:
|
||||
/// - vreg1:sub1, sub0
|
||||
/// - vreg2<:0>, sub1
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isRegSequenceLike().
|
||||
bool getRegSequenceLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override;
|
||||
|
||||
/// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
|
||||
/// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce:
|
||||
/// - vreg1:sub1, sub0
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isExtractSubregLike().
|
||||
bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPairAndIdx &InputReg) const override;
|
||||
|
||||
/// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] BaseReg and \p [out] InsertedReg contain
|
||||
/// the equivalent inputs of INSERT_SUBREG.
|
||||
/// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
|
||||
/// - BaseReg: vreg0:sub0
|
||||
/// - InsertedReg: vreg1:sub1, sub3
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isInsertSubregLike().
|
||||
bool
|
||||
getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPair &BaseReg,
|
||||
RegSubRegPairAndIdx &InsertedReg) const override;
|
||||
|
||||
public:
|
||||
// Return whether the target has an explicit NOP encoding.
|
||||
bool hasNOP() const;
|
||||
|
@ -98,75 +98,6 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI,
|
||||
expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12, RM);
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::getRegSequenceLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isRegSequenceLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VMOVDRR:
|
||||
// dX = VMOVDRR rY, rZ
|
||||
// is the same as:
|
||||
// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1
|
||||
// Populate the InputRegs accordingly.
|
||||
// rY
|
||||
const MachineOperand *MOReg = &MI.getOperand(1);
|
||||
InputRegs.push_back(
|
||||
RegSubRegPairAndIdx(MOReg->getReg(), MOReg->getSubReg(), ARM::ssub_0));
|
||||
// rZ
|
||||
MOReg = &MI.getOperand(2);
|
||||
InputRegs.push_back(
|
||||
RegSubRegPairAndIdx(MOReg->getReg(), MOReg->getSubReg(), ARM::ssub_1));
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::getExtractSubregLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPairAndIdx &InputReg) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isExtractSubregLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VMOVRRD:
|
||||
// rX, rY = VMOVRRD dZ
|
||||
// is the same as:
|
||||
// rX = EXTRACT_SUBREG dZ, ssub_0
|
||||
// rY = EXTRACT_SUBREG dZ, ssub_1
|
||||
const MachineOperand &MOReg = MI.getOperand(2);
|
||||
InputReg.Reg = MOReg.getReg();
|
||||
InputReg.SubReg = MOReg.getSubReg();
|
||||
InputReg.SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::getInsertSubregLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg,
|
||||
RegSubRegPairAndIdx &InsertedReg) const {
|
||||
assert(DefIdx < MI.getDesc().getNumDefs() && "Invalid definition index");
|
||||
assert(MI.isInsertSubregLike() && "Invalid kind of instruction");
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case ARM::VSETLNi32:
|
||||
// dX = VSETLNi32 dY, rZ, imm
|
||||
const MachineOperand &MOBaseReg = MI.getOperand(1);
|
||||
const MachineOperand &MOInsertedReg = MI.getOperand(2);
|
||||
const MachineOperand &MOIndex = MI.getOperand(3);
|
||||
BaseReg.Reg = MOBaseReg.getReg();
|
||||
BaseReg.SubReg = MOBaseReg.getSubReg();
|
||||
|
||||
InsertedReg.Reg = MOInsertedReg.getReg();
|
||||
InsertedReg.SubReg = MOInsertedReg.getSubReg();
|
||||
InsertedReg.SubIdx = MOIndex.getImm() == 0 ? ARM::ssub_0 : ARM::ssub_1;
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Target dependent opcode missing");
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// ARMCGBR - Create Global Base Reg pass. This initializes the PIC
|
||||
/// global base register for ARM ELF.
|
||||
|
@ -38,53 +38,6 @@ public:
|
||||
///
|
||||
const ARMRegisterInfo &getRegisterInfo() const override { return RI; }
|
||||
|
||||
/// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
|
||||
/// the list is modeled as <Reg:SubReg, SubIdx>.
|
||||
/// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce
|
||||
/// two elements:
|
||||
/// - vreg1:sub1, sub0
|
||||
/// - vreg2<:0>, sub1
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isRegSequenceLike().
|
||||
bool getRegSequenceLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override;
|
||||
|
||||
/// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
|
||||
/// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce:
|
||||
/// - vreg1:sub1, sub0
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isExtractSubregLike().
|
||||
bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPairAndIdx &InputReg) const override;
|
||||
|
||||
/// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] BaseReg and \p [out] InsertedReg contain
|
||||
/// the equivalent inputs of INSERT_SUBREG.
|
||||
/// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
|
||||
/// - BaseReg: vreg0:sub0
|
||||
/// - InsertedReg: vreg1:sub1, sub3
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isInsertSubregLike().
|
||||
bool
|
||||
getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
|
||||
RegSubRegPair &BaseReg,
|
||||
RegSubRegPairAndIdx &InsertedReg) const override;
|
||||
|
||||
private:
|
||||
void expandLoadStackGuard(MachineBasicBlock::iterator MI,
|
||||
Reloc::Model RM) const override;
|
||||
|
@ -1,5 +1,7 @@
|
||||
; RUN: llc -O1 -mtriple=armv7s-apple-ios -mcpu=swift < %s -disable-adv-copy-opt=true | FileCheck -check-prefix=NOOPT --check-prefix=CHECK %s
|
||||
; RUN: llc -O1 -mtriple=armv7s-apple-ios -mcpu=swift < %s -disable-adv-copy-opt=false | FileCheck -check-prefix=OPT --check-prefix=CHECK %s
|
||||
; RUN: llc -O1 -mtriple=thumbv7s-apple-ios -mcpu=swift < %s -disable-adv-copy-opt=true | FileCheck -check-prefix=NOOPT --check-prefix=CHECK %s
|
||||
; RUN: llc -O1 -mtriple=thumbv7s-apple-ios -mcpu=swift < %s -disable-adv-copy-opt=false | FileCheck -check-prefix=OPT --check-prefix=CHECK %s
|
||||
|
||||
; CHECK-LABEL: simpleVectorDiv
|
||||
; ABI: %A => r0, r1.
|
||||
|
Loading…
x
Reference in New Issue
Block a user