mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 10:04:33 +00:00
[Hexagon] Move checking AXOK to checker
Patch by Colin LeMahieu. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301949 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
479f5fd8d4
commit
3dac85d148
@ -255,8 +255,9 @@ bool HexagonMCChecker::check(bool FullCheck) {
|
||||
bool chkSl = true;
|
||||
if (FullCheck)
|
||||
chkSl = checkSlots();
|
||||
bool chkAXOK = checkAXOK();
|
||||
bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkELB && chkS &&
|
||||
chkSh && chkSl;
|
||||
chkSh && chkSl && chkAXOK;
|
||||
|
||||
return chk;
|
||||
}
|
||||
@ -279,6 +280,81 @@ bool HexagonMCChecker::checkEndloopBranches() {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool isDuplexAGroup(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case Hexagon::SA1_addi:
|
||||
case Hexagon::SA1_addrx:
|
||||
case Hexagon::SA1_addsp:
|
||||
case Hexagon::SA1_and1:
|
||||
case Hexagon::SA1_clrf:
|
||||
case Hexagon::SA1_clrfnew:
|
||||
case Hexagon::SA1_clrt:
|
||||
case Hexagon::SA1_clrtnew:
|
||||
case Hexagon::SA1_cmpeqi:
|
||||
case Hexagon::SA1_combine0i:
|
||||
case Hexagon::SA1_combine1i:
|
||||
case Hexagon::SA1_combine2i:
|
||||
case Hexagon::SA1_combine3i:
|
||||
case Hexagon::SA1_combinerz:
|
||||
case Hexagon::SA1_combinezr:
|
||||
case Hexagon::SA1_dec:
|
||||
case Hexagon::SA1_inc:
|
||||
case Hexagon::SA1_seti:
|
||||
case Hexagon::SA1_setin1:
|
||||
case Hexagon::SA1_sxtb:
|
||||
case Hexagon::SA1_sxth:
|
||||
case Hexagon::SA1_tfr:
|
||||
case Hexagon::SA1_zxtb:
|
||||
case Hexagon::SA1_zxth:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
|
||||
unsigned Result = 0;
|
||||
unsigned Type = HexagonMCInstrInfo::getType(MCII, ID);
|
||||
if (Type == HexagonII::TypeDUPLEX) {
|
||||
unsigned subInst0Opcode = ID.getOperand(0).getInst()->getOpcode();
|
||||
unsigned subInst1Opcode = ID.getOperand(1).getInst()->getOpcode();
|
||||
Result += !isDuplexAGroup(subInst0Opcode);
|
||||
Result += !isDuplexAGroup(subInst1Opcode);
|
||||
} else
|
||||
Result +=
|
||||
Type != HexagonII::TypeALU32_2op && Type != HexagonII::TypeALU32_3op &&
|
||||
Type != HexagonII::TypeALU32_ADDI && Type != HexagonII::TypeS_2op &&
|
||||
Type != HexagonII::TypeS_3op &&
|
||||
(Type != HexagonII::TypeALU64 || HexagonMCInstrInfo::isFloat(MCII, ID));
|
||||
return Result != 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool HexagonMCChecker::checkAXOK() {
|
||||
MCInst const *HasSoloAXInst = nullptr;
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
if (HexagonMCInstrInfo::isSoloAX(MCII, I)) {
|
||||
HasSoloAXInst = &I;
|
||||
}
|
||||
}
|
||||
if (!HasSoloAXInst)
|
||||
return true;
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
if (&I != HasSoloAXInst && isNeitherAnorX(MCII, I)) {
|
||||
reportError(
|
||||
HasSoloAXInst->getLoc(),
|
||||
llvm::Twine("Instruction can only be in a packet with ALU or "
|
||||
"non-FPU XTYPE instructions"));
|
||||
reportError(I.getLoc(),
|
||||
llvm::Twine("Not an ALU or non-FPU XTYPE instruction"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexagonMCChecker::checkSlots() {
|
||||
unsigned slotsUsed = 0;
|
||||
for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
|
@ -118,6 +118,7 @@ class HexagonMCChecker {
|
||||
bool checkSolo();
|
||||
bool checkShuffle();
|
||||
bool checkSlots();
|
||||
bool checkAXOK();
|
||||
|
||||
static void compoundRegisterMap(unsigned &);
|
||||
|
||||
|
@ -205,58 +205,6 @@ static struct {
|
||||
} jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
|
||||
#define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
|
||||
|
||||
namespace {
|
||||
bool isDuplexAGroup(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case Hexagon::SA1_addi:
|
||||
case Hexagon::SA1_addrx:
|
||||
case Hexagon::SA1_addsp:
|
||||
case Hexagon::SA1_and1:
|
||||
case Hexagon::SA1_clrf:
|
||||
case Hexagon::SA1_clrfnew:
|
||||
case Hexagon::SA1_clrt:
|
||||
case Hexagon::SA1_clrtnew:
|
||||
case Hexagon::SA1_cmpeqi:
|
||||
case Hexagon::SA1_combine0i:
|
||||
case Hexagon::SA1_combine1i:
|
||||
case Hexagon::SA1_combine2i:
|
||||
case Hexagon::SA1_combine3i:
|
||||
case Hexagon::SA1_combinerz:
|
||||
case Hexagon::SA1_combinezr:
|
||||
case Hexagon::SA1_dec:
|
||||
case Hexagon::SA1_inc:
|
||||
case Hexagon::SA1_seti:
|
||||
case Hexagon::SA1_setin1:
|
||||
case Hexagon::SA1_sxtb:
|
||||
case Hexagon::SA1_sxth:
|
||||
case Hexagon::SA1_tfr:
|
||||
case Hexagon::SA1_zxtb:
|
||||
case Hexagon::SA1_zxth:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned countNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
|
||||
unsigned Result = 0;
|
||||
unsigned Type = HexagonMCInstrInfo::getType(MCII, ID);
|
||||
if (Type == HexagonII::TypeDUPLEX) {
|
||||
unsigned subInst0Opcode = ID.getOperand(0).getInst()->getOpcode();
|
||||
unsigned subInst1Opcode = ID.getOperand(1).getInst()->getOpcode();
|
||||
Result += !isDuplexAGroup(subInst0Opcode);
|
||||
Result += !isDuplexAGroup(subInst1Opcode);
|
||||
} else
|
||||
Result +=
|
||||
Type != HexagonII::TypeALU32_2op && Type != HexagonII::TypeALU32_3op &&
|
||||
Type != HexagonII::TypeALU32_ADDI && Type != HexagonII::TypeS_2op &&
|
||||
Type != HexagonII::TypeS_3op && Type != HexagonII::TypeALU64 &&
|
||||
(Type != HexagonII::TypeM || HexagonMCInstrInfo::isFloat(MCII, ID));
|
||||
return Result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/// Check that the packet is legal and enforce relative insn order.
|
||||
bool HexagonShuffler::check() {
|
||||
// Descriptive slot masks.
|
||||
@ -271,18 +219,12 @@ bool HexagonShuffler::check() {
|
||||
// Number of memory operations, loads, solo loads, stores, solo stores, single
|
||||
// stores.
|
||||
unsigned memory = 0, loads = 0, load0 = 0, stores = 0, store0 = 0, store1 = 0;
|
||||
// Number of HVX loads, HVX stores.
|
||||
unsigned CVIloads = 0, CVIstores = 0;
|
||||
// Number of duplex insns
|
||||
unsigned duplex = 0;
|
||||
// Number of insns restricting other insns in the packet to A and X types,
|
||||
// which is neither A or X types.
|
||||
unsigned onlyAX = 0, neitherAnorX = 0;
|
||||
// Number of insns restricting other insns in slot #1 to A type.
|
||||
unsigned onlyAin1 = 0;
|
||||
// Number of insns restricting any insn in slot #1, except A2_nop.
|
||||
unsigned onlyNo1 = 0;
|
||||
unsigned xtypeFloat = 0;
|
||||
unsigned pSlot3Cnt = 0;
|
||||
unsigned nvstores = 0;
|
||||
unsigned memops = 0;
|
||||
@ -295,11 +237,8 @@ bool HexagonShuffler::check() {
|
||||
for (iterator ISJ = begin(); ISJ != end(); ++ISJ) {
|
||||
MCInst const &ID = ISJ->getDesc();
|
||||
|
||||
if (HexagonMCInstrInfo::isSoloAX(MCII, ID))
|
||||
++onlyAX;
|
||||
else if (HexagonMCInstrInfo::isSoloAin1(MCII, ID))
|
||||
if (HexagonMCInstrInfo::isSoloAin1(MCII, ID))
|
||||
++onlyAin1;
|
||||
neitherAnorX += countNeitherAnorX(MCII, ID);
|
||||
if (HexagonMCInstrInfo::prefersSlot3(MCII, ID)) {
|
||||
++pSlot3Cnt;
|
||||
slot3ISJ = ISJ;
|
||||
@ -312,8 +251,6 @@ bool HexagonShuffler::check() {
|
||||
case HexagonII::TypeS_2op:
|
||||
case HexagonII::TypeS_3op:
|
||||
case HexagonII::TypeALU64:
|
||||
if (HexagonMCInstrInfo::isFloat(MCII, ID))
|
||||
++xtypeFloat;
|
||||
break;
|
||||
case HexagonII::TypeJ:
|
||||
++jumps;
|
||||
@ -323,7 +260,6 @@ bool HexagonShuffler::check() {
|
||||
++onlyNo1;
|
||||
case HexagonII::TypeCVI_VM_LD:
|
||||
case HexagonII::TypeCVI_VM_TMP_LD:
|
||||
++CVIloads;
|
||||
case HexagonII::TypeLD:
|
||||
++loads;
|
||||
++memory;
|
||||
@ -339,7 +275,6 @@ bool HexagonShuffler::check() {
|
||||
++onlyNo1;
|
||||
case HexagonII::TypeCVI_VM_ST:
|
||||
case HexagonII::TypeCVI_VM_NEW_ST:
|
||||
++CVIstores;
|
||||
case HexagonII::TypeST:
|
||||
++stores;
|
||||
++memory;
|
||||
@ -408,8 +343,7 @@ bool HexagonShuffler::check() {
|
||||
|
||||
// Check if the packet is legal.
|
||||
if ((load0 > 1 || store0 > 1) ||
|
||||
(duplex > 1 || (duplex && memory)) ||
|
||||
(onlyAX && neitherAnorX > 1) || (onlyAX && xtypeFloat)) {
|
||||
(duplex > 1 || (duplex && memory))) {
|
||||
reportError(llvm::Twine("invalid instruction packet"));
|
||||
return false;
|
||||
}
|
||||
|
4
test/MC/Hexagon/PacketRules/restrict_ax.s
Normal file
4
test/MC/Hexagon/PacketRules/restrict_ax.s
Normal file
@ -0,0 +1,4 @@
|
||||
{ r0=memw_locked(r0)
|
||||
r1=-mpyi(r0,#0) }
|
||||
# RUN: not llvm-mc -arch=hexagon -filetype=asm %s 2>%t; FileCheck %s --check-prefix=CHECK00 <%t
|
||||
# CHECK00: 1:3: error: Instruction can only be in a packet with ALU or non-FPU XTYPE instructions
|
9
test/MC/Hexagon/solo-axok.s
Normal file
9
test/MC/Hexagon/solo-axok.s
Normal file
@ -0,0 +1,9 @@
|
||||
# RUN: not llvm-mc -arch=hexagon -filetype=asm -mcpu=hexagonv55 %s 2>%t; FileCheck %s < %t
|
||||
#
|
||||
{
|
||||
sp=asrh(r6)
|
||||
l2fetch(fp,r23:22)
|
||||
p2=r7
|
||||
p1=dfclass(r31:30,#6)
|
||||
}
|
||||
# CHECK: rror: Instruction can only
|
Loading…
Reference in New Issue
Block a user