diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp index 5d2477cc800651..8c2d3126a3cc73 100644 --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -181,11 +181,13 @@ static const InstructionMask r6[] = { {0xd7000000, 0x006020e0}, {0xd8000000, 0x006020e0}, {0xdb000000, 0x006020e0}, {0xdf000000, 0x006020e0}}; +constexpr uint32_t instParsePacketEnd = 0x0000c000; + 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; + return (instParsePacketEnd & insn) == 0; } static uint32_t findMaskR6(uint32_t insn) { @@ -216,6 +218,12 @@ static uint32_t findMaskR11(uint32_t insn) { } static uint32_t findMaskR16(uint32_t insn) { + if (isDuplex(insn)) + return 0x03f00000; + + // Clear the end-packet-parse bits: + insn = insn & ~instParsePacketEnd; + if ((0xff000000 & insn) == 0x48000000) return 0x061f20ff; if ((0xff000000 & insn) == 0x49000000) @@ -225,8 +233,14 @@ static uint32_t findMaskR16(uint32_t insn) { if ((0xff000000 & insn) == 0xb0000000) return 0x0fe03fe0; - if (isDuplex(insn)) - return 0x03f00000; + if ((0xff802000 & insn) == 0x74000000) + return 0x00001fe0; + if ((0xff802000 & insn) == 0x74002000) + return 0x00001fe0; + if ((0xff802000 & insn) == 0x74800000) + return 0x00001fe0; + if ((0xff802000 & insn) == 0x74802000) + return 0x00001fe0; for (InstructionMask i : r6) if ((0xff000000 & insn) == i.cmpMask) diff --git a/lld/test/ELF/hexagon-shared.s b/lld/test/ELF/hexagon-shared.s index 747822039e839a..01f72865847056 100644 --- a/lld/test/ELF/hexagon-shared.s +++ b/lld/test/ELF/hexagon-shared.s @@ -42,6 +42,13 @@ r0 = add(r1,##bar@GOT) { r0 = add(r0,##bar@GOT) memw(r0) = r2 } +# R_HEX_GOT_16_X, pred add +if (p0) r0 = add(r0,##bar@GOT) +if (!p0) r0 = add(r0,##bar@GOT) +{ p0 = cmp.gtu(r0, r1) + if (p0.new) r0 = add(r0,##bar@GOT) } +{ p0 = cmp.gtu(r0, r1) + if (!p0.new) r0 = add(r0,##bar@GOT) } # foo is local so no plt will be generated foo: @@ -78,12 +85,16 @@ pvar: # PLT-NEXT: r28 = memw(r14+#0) } # PLT-NEXT: jumpr r28 } -# TEXT: 8c 00 01 00 0001008c -# TEXT: { call 0x102d0 } -# TEXT: if (p0) jump:nt 0x102d0 -# TEXT: r0 = #0 ; jump 0x102d0 +# TEXT: bc 00 01 00 000100bc +# TEXT: { call 0x10300 } +# TEXT: if (p0) jump:nt 0x10300 +# TEXT: r0 = #0 ; jump 0x10300 # TEXT: r0 = add(r1,##-65548) # TEXT: r0 = add(r0,##-65548); memw(r0+#0) = r2 } +# TEXT: if (p0) r0 = add(r0,##-65548) +# TEXT: if (!p0) r0 = add(r0,##-65548) +# TEXT: if (p0.new) r0 = add(r0,##-65548) +# TEXT: if (!p0.new) r0 = add(r0,##-65548) # GOT: .got: # GOT: 00 00 00 00 00000000