diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-04-28 15:54:48 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-04-28 15:54:48 +0000 |
commit | e737b86f8cac4a8d93d639890c886815237205a7 (patch) | |
tree | 70a96ca5945e52bb89984725e9b2fc7f599c9428 | |
parent | e5447574c8f58b766659ab93198916b85e52ef96 (diff) | |
download | bcm5719-llvm-e737b86f8cac4a8d93d639890c886815237205a7.tar.gz bcm5719-llvm-e737b86f8cac4a8d93d639890c886815237205a7.zip |
[Hexagon] Handle double-vector registers as new-value producers
Patch by Colin LeMahieu.
llvm-svn: 267897
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 |