aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Arch/Hexagon.cpp15
-rw-r--r--lld/test/ELF/hexagon-shared.s6
2 files changed, 17 insertions, 4 deletions
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 730c47a..27b20ba 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -161,6 +161,13 @@ RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s,
}
}
+static bool isDuplex(uint32_t insn) {
+ // Duplex forms have a fixed mask and parse bits 15:14 are always
+ // zero. Non-duplex insns will always have at least one bit set in the
+ // parse field.
+ return (0xC000 & insn) == 0;
+}
+
static uint32_t findMaskR6(uint32_t insn) {
// There are (arguably too) many relocation masks for the DSP's
// R_HEX_6_X type. The table below is used to select the correct mask
@@ -185,10 +192,7 @@ static uint32_t findMaskR6(uint32_t insn) {
{0xd7000000, 0x006020e0}, {0xd8000000, 0x006020e0},
{0xdb000000, 0x006020e0}, {0xdf000000, 0x006020e0}};
- // Duplex forms have a fixed mask and parse bits 15:14 are always
- // zero. Non-duplex insns will always have at least one bit set in the
- // parse field.
- if ((0xC000 & insn) == 0x0)
+ if (isDuplex(insn))
return 0x03f00000;
for (InstructionMask i : r6)
@@ -224,6 +228,9 @@ static uint32_t findMaskR16(uint32_t insn) {
if ((0xff000000 & insn) == 0xb0000000)
return 0x0fe03fe0;
+ if (isDuplex(insn))
+ return 0x03f00000;
+
error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
utohexstr(insn));
return 0;
diff --git a/lld/test/ELF/hexagon-shared.s b/lld/test/ELF/hexagon-shared.s
index 6bc1bd5..d1d9254 100644
--- a/lld/test/ELF/hexagon-shared.s
+++ b/lld/test/ELF/hexagon-shared.s
@@ -38,6 +38,11 @@ jumpr r0
# R_HEX_GOT_16_X
r0 = add(r1,##bar@GOT)
+# R_HEX_GOT_16_X, duplex
+{ r0 = add(r0,##bar@GOT)
+ memw(r0) = r2 }
+
+
# foo is local so no plt will be generated
foo:
jumpr lr
@@ -78,6 +83,7 @@ pvar:
# TEXT: if (p0) jump:nt 0x102d0
# TEXT: r0 = #0 ; jump 0x102d0
# TEXT: r0 = add(r1,##-65548)
+# TEXT: r0 = add(r0,##-65548); memw(r0+#0) = r2 }
# GOT: .got:
# GOT: 00 00 00 00 00000000 <unknown>