forked from OSchip/llvm-project
[Hexagon] Handle double-vector registers as new-value producers
Patch by Colin LeMahieu. llvm-svn: 267897
This commit is contained in:
parent
e5447574c8
commit
e737b86f8c
|
@ -88,6 +88,19 @@ void HexagonMCCodeEmitter::encodeInstruction(MCInst const &MI, raw_ostream &OS,
|
|||
return;
|
||||
}
|
||||
|
||||
static bool RegisterMatches(unsigned Consumer, unsigned Producer,
|
||||
unsigned Producer2) {
|
||||
if (Consumer == Producer)
|
||||
return true;
|
||||
if (Consumer == Producer2)
|
||||
return true;
|
||||
// Calculate if we're a single vector consumer referencing a double producer
|
||||
if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
|
||||
if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
|
||||
return ((Consumer - Hexagon::V0) >> 1) == (Producer - Hexagon::W0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// EncodeSingleInstruction - Emit a single
|
||||
void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
||||
const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
|
||||
|
@ -125,8 +138,10 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
|||
MCOperand &MCO =
|
||||
HMB.getOperand(HexagonMCInstrInfo::getNewValueOp(MCII, HMB));
|
||||
unsigned SOffset = 0;
|
||||
unsigned VOffset = 0;
|
||||
unsigned Register = MCO.getReg();
|
||||
unsigned Register1;
|
||||
unsigned Register2;
|
||||
auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
|
||||
auto i = Instructions.begin() + Index - 1;
|
||||
for (;; --i) {
|
||||
|
@ -135,11 +150,18 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
|||
if (HexagonMCInstrInfo::isImmext(Inst))
|
||||
continue;
|
||||
++SOffset;
|
||||
if (HexagonMCInstrInfo::isVector(MCII, Inst))
|
||||
// Vector instructions don't count scalars
|
||||
++VOffset;
|
||||
Register1 =
|
||||
HexagonMCInstrInfo::hasNewValue(MCII, Inst)
|
||||
? HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg()
|
||||
: static_cast<unsigned>(Hexagon::NoRegister);
|
||||
if (Register != Register1)
|
||||
Register2 =
|
||||
HexagonMCInstrInfo::hasNewValue2(MCII, Inst)
|
||||
? HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg()
|
||||
: static_cast<unsigned>(Hexagon::NoRegister);
|
||||
if (!RegisterMatches(Register, Register1, Register2))
|
||||
// This isn't the register we're looking for
|
||||
continue;
|
||||
if (!HexagonMCInstrInfo::isPredicated(MCII, Inst))
|
||||
|
@ -153,8 +175,11 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
|||
break;
|
||||
}
|
||||
// Hexagon PRM 10.11 Construct Nt from distance
|
||||
unsigned Offset = SOffset;
|
||||
unsigned Offset =
|
||||
HexagonMCInstrInfo::isVector(MCII, HMB) ? VOffset : SOffset;
|
||||
Offset <<= 1;
|
||||
Offset |=
|
||||
HexagonMCInstrInfo::SubregisterBit(Register, Register1, Register2);
|
||||
MCO.setReg(Offset + Hexagon::R0);
|
||||
}
|
||||
|
||||
|
@ -165,7 +190,6 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
|||
((HMB.getOpcode() != DuplexIClass0) && (HMB.getOpcode() != A4_ext) &&
|
||||
(HMB.getOpcode() != A4_ext_b) && (HMB.getOpcode() != A4_ext_c) &&
|
||||
(HMB.getOpcode() != A4_ext_g))) {
|
||||
// Use a A2_nop for unimplemented instructions.
|
||||
DEBUG(dbgs() << "Unimplemented inst: "
|
||||
" `" << HexagonMCInstrInfo::getName(MCII, HMB) << "'"
|
||||
"\n");
|
||||
|
|
|
@ -788,4 +788,17 @@ void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
|
|||
MCOperand &Operand = MCI.getOperand(0);
|
||||
Operand.setImm(Operand.getImm() | outerLoopMask);
|
||||
}
|
||||
|
||||
unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
|
||||
unsigned Producer,
|
||||
unsigned Producer2) {
|
||||
// If we're a single vector consumer of a double producer, set subreg bit
|
||||
// based on if we're accessing the lower or upper register component
|
||||
if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
|
||||
if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
|
||||
return (Consumer - Hexagon::V0) & 0x1;
|
||||
if (Consumer == Producer2)
|
||||
return 0x1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,6 +290,8 @@ void setOuterLoop(MCInst &MCI);
|
|||
|
||||
// Would duplexing this instruction create a requirement to extend
|
||||
bool subInstWouldBeExtended(MCInst const &potentialDuplex);
|
||||
unsigned SubregisterBit(unsigned Consumer, unsigned Producer,
|
||||
unsigned Producer2);
|
||||
|
||||
// Attempt to find and replace compound pairs
|
||||
void tryCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# RUN: llvm-mc -arch=hexagon -mcpu=hexagonv60 -filetype=obj %s | llvm-objdump -d - | FileCheck %s
|
||||
{
|
||||
v1:0 = vshuff(v1,v0,r7)
|
||||
v2.w = vadd(v13.w,v15.w)
|
||||
v3.w = vadd(v8.w,v14.w)
|
||||
vmem(r2+#-2) = v0.new
|
||||
}
|
||||
|
||||
# CHECK: 60 61 07 1b
|
||||
# CHECK: 02 4d 4f 1c
|
||||
# CHECK: 03 48 4e 1c
|
||||
# CHECK: 26 e6 22 28
|
Loading…
Reference in New Issue