summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-04-28 15:54:48 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-04-28 15:54:48 +0000
commite737b86f8cac4a8d93d639890c886815237205a7 (patch)
tree70a96ca5945e52bb89984725e9b2fc7f599c9428
parente5447574c8f58b766659ab93198916b85e52ef96 (diff)
downloadbcm5719-llvm-e737b86f8cac4a8d93d639890c886815237205a7.tar.gz
bcm5719-llvm-e737b86f8cac4a8d93d639890c886815237205a7.zip
[Hexagon] Handle double-vector registers as new-value producers
Patch by Colin LeMahieu. llvm-svn: 267897
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp30
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp13
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h2
-rw-r--r--llvm/test/MC/Hexagon/double-vector-producer.s12
4 files changed, 54 insertions, 3 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
index c8a4880465f..39b828d8a03 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -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");
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
index 909aeadc191..941cbd6dc35 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
@@ -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;
+}
}
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
index a5991a74665..58a8f68b984 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
@@ -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);
diff --git a/llvm/test/MC/Hexagon/double-vector-producer.s b/llvm/test/MC/Hexagon/double-vector-producer.s
new file mode 100644
index 00000000000..5421653b5b4
--- /dev/null
+++ b/llvm/test/MC/Hexagon/double-vector-producer.s
@@ -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
OpenPOWER on IntegriCloud