summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp21
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp109
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h2
-rw-r--r--llvm/test/MC/Hexagon/duplex-registers.s10
4 files changed, 136 insertions, 6 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
index ee96330d8cd..c8a4880465f 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -768,13 +768,22 @@ unsigned
HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const {
- if (MO.isReg())
- return MCT.getRegisterInfo()->getEncodingValue(MO.getReg());
- if (MO.isImm())
- return static_cast<unsigned>(MO.getImm());
+ assert(!MO.isImm());
+ if (MO.isReg()) {
+ unsigned Reg = MO.getReg();
+ if (HexagonMCInstrInfo::isSubInstruction(MI))
+ return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg);
+ switch(MI.getOpcode()){
+ case Hexagon::A2_tfrrcr:
+ case Hexagon::A2_tfrcrr:
+ if(Reg == Hexagon::M0)
+ Reg = Hexagon::C6;
+ if(Reg == Hexagon::M1)
+ Reg = Hexagon::C7;
+ }
+ return MCT.getRegisterInfo()->getEncodingValue(Reg);
+ }
- // MO must be an ME.
- assert(MO.isExpr());
return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
}
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
index 769c76ea1fa..909aeadc191 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
@@ -191,6 +191,55 @@ MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
return (MCII.get(MCI.getOpcode()));
}
+unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
+ using namespace Hexagon;
+ switch (Reg) {
+ default:
+ llvm_unreachable("unknown duplex register");
+ // Rs Rss
+ case R0:
+ case D0:
+ return 0;
+ case R1:
+ case D1:
+ return 1;
+ case R2:
+ case D2:
+ return 2;
+ case R3:
+ case D3:
+ return 3;
+ case R4:
+ case D8:
+ return 4;
+ case R5:
+ case D9:
+ return 5;
+ case R6:
+ case D10:
+ return 6;
+ case R7:
+ case D11:
+ return 7;
+ case R16:
+ return 8;
+ case R17:
+ return 9;
+ case R18:
+ return 10;
+ case R19:
+ return 11;
+ case R20:
+ return 12;
+ case R21:
+ return 13;
+ case R22:
+ return 14;
+ case R23:
+ return 15;
+ }
+}
+
MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {
const auto &HExpr = cast<HexagonMCExpr>(Expr);
assert(HExpr.getExpr());
@@ -549,6 +598,66 @@ bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) {
return (Flags & memStoreReorderEnabledMask) != 0;
}
+bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {
+ switch (MCI.getOpcode()) {
+ default:
+ return false;
+ case Hexagon::V4_SA1_addi:
+ case Hexagon::V4_SA1_addrx:
+ case Hexagon::V4_SA1_addsp:
+ case Hexagon::V4_SA1_and1:
+ case Hexagon::V4_SA1_clrf:
+ case Hexagon::V4_SA1_clrfnew:
+ case Hexagon::V4_SA1_clrt:
+ case Hexagon::V4_SA1_clrtnew:
+ case Hexagon::V4_SA1_cmpeqi:
+ case Hexagon::V4_SA1_combine0i:
+ case Hexagon::V4_SA1_combine1i:
+ case Hexagon::V4_SA1_combine2i:
+ case Hexagon::V4_SA1_combine3i:
+ case Hexagon::V4_SA1_combinerz:
+ case Hexagon::V4_SA1_combinezr:
+ case Hexagon::V4_SA1_dec:
+ case Hexagon::V4_SA1_inc:
+ case Hexagon::V4_SA1_seti:
+ case Hexagon::V4_SA1_setin1:
+ case Hexagon::V4_SA1_sxtb:
+ case Hexagon::V4_SA1_sxth:
+ case Hexagon::V4_SA1_tfr:
+ case Hexagon::V4_SA1_zxtb:
+ case Hexagon::V4_SA1_zxth:
+ case Hexagon::V4_SL1_loadri_io:
+ case Hexagon::V4_SL1_loadrub_io:
+ case Hexagon::V4_SL2_deallocframe:
+ case Hexagon::V4_SL2_jumpr31:
+ case Hexagon::V4_SL2_jumpr31_f:
+ case Hexagon::V4_SL2_jumpr31_fnew:
+ case Hexagon::V4_SL2_jumpr31_t:
+ case Hexagon::V4_SL2_jumpr31_tnew:
+ case Hexagon::V4_SL2_loadrb_io:
+ case Hexagon::V4_SL2_loadrd_sp:
+ case Hexagon::V4_SL2_loadrh_io:
+ case Hexagon::V4_SL2_loadri_sp:
+ case Hexagon::V4_SL2_loadruh_io:
+ case Hexagon::V4_SL2_return:
+ case Hexagon::V4_SL2_return_f:
+ case Hexagon::V4_SL2_return_fnew:
+ case Hexagon::V4_SL2_return_t:
+ case Hexagon::V4_SL2_return_tnew:
+ case Hexagon::V4_SS1_storeb_io:
+ case Hexagon::V4_SS1_storew_io:
+ case Hexagon::V4_SS2_allocframe:
+ case Hexagon::V4_SS2_storebi0:
+ case Hexagon::V4_SS2_storebi1:
+ case Hexagon::V4_SS2_stored_sp:
+ case Hexagon::V4_SS2_storeh_io:
+ case Hexagon::V4_SS2_storew_sp:
+ case Hexagon::V4_SS2_storewi0:
+ case Hexagon::V4_SS2_storewi1:
+ return true;
+ }
+}
+
bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
index 2a1d11c3c74..a5991a74665 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
@@ -107,6 +107,7 @@ unsigned getDuplexCandidateGroup(MCInst const &MI);
// Return a list of all possible instruction duplex combinations
SmallVector<DuplexCandidate, 8> getDuplexPossibilties(MCInstrInfo const &MCII,
MCInst const &MCB);
+unsigned getDuplexRegisterNumbering(unsigned Reg);
MCExpr const &getExpr(MCExpr const &Expr);
@@ -262,6 +263,7 @@ bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI);
/// Return whether the insn can be packaged only with an A-type insn in slot #1.
bool isSoloAin1(MCInstrInfo const &MCII, MCInst const &MCI);
+bool isSubInstruction(MCInst const &MCI);
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI);
bool mustExtend(MCExpr const &Expr);
bool mustNotExtend(MCExpr const &Expr);
diff --git a/llvm/test/MC/Hexagon/duplex-registers.s b/llvm/test/MC/Hexagon/duplex-registers.s
new file mode 100644
index 00000000000..f0cde7f9628
--- /dev/null
+++ b/llvm/test/MC/Hexagon/duplex-registers.s
@@ -0,0 +1,10 @@
+#RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d - | FileCheck %s
+
+.text
+{
+ r16 = memuh(r17 + #0)
+ r18 = memuh(r19 + #0)
+}
+
+# CHECK: 289808ba
+# CHECK: r16 = memuh(r17 + #0);{{ *}}r18 = memuh(r19 + #0)
OpenPOWER on IntegriCloud