summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp182
1 files changed, 167 insertions, 15 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index eb643d0aeb2..b82a0157e81 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -1242,6 +1242,7 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
MBB.erase(MI);
return true;
}
+
case Hexagon::PS_tailcall_i:
MI.setDesc(get(Hexagon::J2_jump));
return true;
@@ -1267,6 +1268,82 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
case Hexagon::PS_jmpretfnew:
MI.setDesc(get(Hexagon::J2_jumprfnew));
return true;
+
+ case Hexagon::V6_vgathermh_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
+ case Hexagon::V6_vgathermw_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
+ case Hexagon::V6_vgathermhw_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
+ case Hexagon::V6_vgathermhq_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .add(MI.getOperand(4));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
+ case Hexagon::V6_vgathermwq_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .add(MI.getOperand(4));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
+ case Hexagon::V6_vgathermhwq_pseudo:
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))
+ .add(MI.getOperand(1))
+ .add(MI.getOperand(2))
+ .add(MI.getOperand(3))
+ .add(MI.getOperand(4));
+ BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
+ .add(MI.getOperand(0))
+ .addImm(0)
+ .addReg(Hexagon::VTMP);
+ MBB.erase(MI);
+ return true;
+
}
return false;
@@ -2051,6 +2128,8 @@ bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,
// TODO: Add all the compound branches here. Can we do this in Relation model?
case Hexagon::J4_cmpeqi_tp0_jump_nt:
case Hexagon::J4_cmpeqi_tp1_jump_nt:
+ case Hexagon::J4_cmpeqn1_tp0_jump_nt:
+ case Hexagon::J4_cmpeqn1_tp1_jump_nt:
return isInt<11>(offset);
}
}
@@ -2817,10 +2896,8 @@ bool HexagonInstrInfo::producesStall(const MachineInstr &MI,
MachineBasicBlock::const_instr_iterator MII = BII;
MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
- if (!(*MII).isBundle()) {
- const MachineInstr &J = *MII;
- return producesStall(J, MI);
- }
+ if (!MII->isBundle())
+ return producesStall(*MII, MI);
for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
const MachineInstr &J = *MII;
@@ -2906,6 +2983,9 @@ unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI,
/// Return the position of the base and offset operands for this instruction.
bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,
unsigned &BasePos, unsigned &OffsetPos) const {
+ if (!isAddrModeWithOffset(MI) && !isPostIncrement(MI))
+ return false;
+
// Deal with memops first.
if (isMemOp(MI)) {
BasePos = 0;
@@ -3097,15 +3177,24 @@ unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,
assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);
if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
(GB.getOpcode() != Hexagon::J2_jumptnew))
- return -1;
+ return -1u;
unsigned DestReg = GA.getOperand(0).getReg();
if (!GB.readsRegister(DestReg))
- return -1;
- if (DestReg == Hexagon::P0)
- return Hexagon::J4_cmpeqi_tp0_jump_nt;
- if (DestReg == Hexagon::P1)
- return Hexagon::J4_cmpeqi_tp1_jump_nt;
- return -1;
+ return -1u;
+ if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)
+ return -1u;
+ // The value compared against must be either u5 or -1.
+ const MachineOperand &CmpOp = GA.getOperand(2);
+ if (!CmpOp.isImm())
+ return -1u;
+ int V = CmpOp.getImm();
+ if (V == -1)
+ return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt
+ : Hexagon::J4_cmpeqn1_tp1_jump_nt;
+ if (!isUInt<5>(V))
+ return -1u;
+ return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt
+ : Hexagon::J4_cmpeqi_tp1_jump_nt;
}
int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
@@ -3514,6 +3603,7 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
return HexagonII::HSIG_L2;
case Hexagon::EH_RETURN_JMPR:
case Hexagon::PS_jmpret:
+ case Hexagon::SL2_jumpr31:
// jumpr r31
// Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0
DstReg = MI.getOperand(0).getReg();
@@ -3526,6 +3616,9 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
case Hexagon::PS_jmpretfnewpt:
case Hexagon::PS_jmprettnew:
case Hexagon::PS_jmpretfnew:
+ case Hexagon::SL2_jumpr31_t:
+ case Hexagon::SL2_jumpr31_f:
+ case Hexagon::SL2_jumpr31_tnew:
DstReg = MI.getOperand(1).getReg();
SrcReg = MI.getOperand(0).getReg();
// [if ([!]p0[.new])] jumpr r31
@@ -3619,8 +3712,8 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
return HexagonII::HSIG_S2;
break;
case Hexagon::S2_allocframe:
- if (MI.getOperand(0).isImm() &&
- isShiftedUInt<5,3>(MI.getOperand(0).getImm()))
+ if (MI.getOperand(2).isImm() &&
+ isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
return HexagonII::HSIG_S1;
break;
//
@@ -3825,8 +3918,14 @@ int HexagonInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
}
}
- return TargetInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
- UseMI, UseIdx);
+ int Latency = TargetInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
+ UseMI, UseIdx);
+ if (!Latency)
+ // We should never have 0 cycle latency between two instructions unless
+ // they can be packetized together. However, this decision can't be made
+ // here.
+ Latency = 1;
+ return Latency;
}
// inverts the predication logic.
@@ -3865,6 +3964,35 @@ int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {
return ~(-1U << bits);
}
+
+bool HexagonInstrInfo::isAddrModeWithOffset(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ case Hexagon::L2_loadrbgp:
+ case Hexagon::L2_loadrdgp:
+ case Hexagon::L2_loadrhgp:
+ case Hexagon::L2_loadrigp:
+ case Hexagon::L2_loadrubgp:
+ case Hexagon::L2_loadruhgp:
+ case Hexagon::S2_storerbgp:
+ case Hexagon::S2_storerbnewgp:
+ case Hexagon::S2_storerhgp:
+ case Hexagon::S2_storerhnewgp:
+ case Hexagon::S2_storerigp:
+ case Hexagon::S2_storerinewgp:
+ case Hexagon::S2_storerdgp:
+ case Hexagon::S2_storerfgp:
+ return true;
+ }
+ const uint64_t F = MI.getDesc().TSFlags;
+ unsigned addrMode =
+ ((F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask);
+ // Disallow any base+offset instruction. The assembler does not yet reorder
+ // based up any zero offset instruction.
+ return (addrMode == HexagonII::BaseRegOffset ||
+ addrMode == HexagonII::BaseImmOffset ||
+ addrMode == HexagonII::BaseLongOffset);
+}
+
unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {
using namespace HexagonII;
@@ -4094,6 +4222,22 @@ bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
}
+void HexagonInstrInfo::
+setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const {
+ assert(MIB->isBundle());
+ MachineOperand &Operand = MIB->getOperand(0);
+ if (Operand.isImm())
+ Operand.setImm(Operand.getImm() | memShufDisabledMask);
+ else
+ MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));
+}
+
+bool HexagonInstrInfo::getBundleNoShuf(const MachineInstr &MIB) const {
+ assert(MIB.isBundle());
+ const MachineOperand &Operand = MIB.getOperand(0);
+ return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);
+}
+
// Addressing mode relations.
short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {
return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
@@ -4103,10 +4247,18 @@ short HexagonInstrInfo::changeAddrMode_io_abs(short Opc) const {
return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
}
+short HexagonInstrInfo::changeAddrMode_io_pi(short Opc) const {
+ return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;
+}
+
short HexagonInstrInfo::changeAddrMode_io_rr(short Opc) const {
return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
}
+short HexagonInstrInfo::changeAddrMode_pi_io(short Opc) const {
+ return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;
+}
+
short HexagonInstrInfo::changeAddrMode_rr_io(short Opc) const {
return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
}
OpenPOWER on IntegriCloud