Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lld][Hexagon] Support predicated-add GOT_16_X mask lookup #111896

Merged
merged 1 commit into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions lld/ELF/Arch/Hexagon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
androm3da marked this conversation as resolved.
Show resolved Hide resolved

if ((0xff000000 & insn) == 0x48000000)
return 0x061f20ff;
if ((0xff000000 & insn) == 0x49000000)
Expand All @@ -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)
Expand Down
19 changes: 15 additions & 4 deletions lld/test/ELF/hexagon-shared.s
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 <unknown>
Expand Down
Loading