[lld] r339332 - Add R_HEX_6_X relocation support

Sid Manning via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 9 05:00:11 PDT 2018


Author: sidneym
Date: Thu Aug  9 05:00:10 2018
New Revision: 339332

URL: http://llvm.org/viewvc/llvm-project?rev=339332&view=rev
Log:
Add R_HEX_6_X relocation support

This is a larger patch.  This relocation has irregular immediate
masks that require a lookup to find the correct mask.

Differential Revision: https://reviews.llvm.org/D50450

Modified:
    lld/trunk/ELF/Arch/Hexagon.cpp
    lld/trunk/test/ELF/hexagon.s

Modified: lld/trunk/ELF/Arch/Hexagon.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Hexagon.cpp?rev=339332&r1=339331&r2=339332&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Hexagon.cpp (original)
+++ lld/trunk/ELF/Arch/Hexagon.cpp Thu Aug  9 05:00:10 2018
@@ -58,18 +58,62 @@ RelExpr Hexagon::getRelExpr(RelType Type
   case R_HEX_B22_PCREL:
   case R_HEX_B22_PCREL_X:
   case R_HEX_B32_PCREL_X:
+  case R_HEX_6_PCREL_X:
     return R_PC;
   default:
     return R_ABS;
   }
 }
 
+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
+  // for the given instruction.
+  struct InstructionMask {
+    uint32_t CmpMask;
+    uint32_t RelocMask;
+  };
+
+  static const InstructionMask R6[] = {
+      {0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
+      {0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
+      {0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
+      {0x42000000, 0x000020f8}, {0x43000000, 0x000007e0},
+      {0x44000000, 0x000020f8}, {0x45000000, 0x000007e0},
+      {0x46000000, 0x000020f8}, {0x47000000, 0x000007e0},
+      {0x6a000000, 0x00001f80}, {0x7c000000, 0x001f2000},
+      {0x9a000000, 0x00000f60}, {0x9b000000, 0x00000f60},
+      {0x9c000000, 0x00000f60}, {0x9d000000, 0x00000f60},
+      {0x9f000000, 0x001f0100}, {0xab000000, 0x0000003f},
+      {0xad000000, 0x0000003f}, {0xaf000000, 0x00030078},
+      {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)
+    return 0x03f00000;
+
+  for (InstructionMask I : R6)
+    if ((0xff000000 & Insn) == I.CmpMask)
+      return I.RelocMask;
+
+  error("unrecognized instruction for R_HEX_6 relocation: 0x" +
+        utohexstr(Insn));
+  return 0;
+}
+
 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
 
 void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
   switch (Type) {
   case R_HEX_NONE:
     break;
+  case R_HEX_6_PCREL_X:
+  case R_HEX_6_X:
+    or32le(Loc, applyMask(findMaskR6(read32le(Loc)), Val));
+    break;
   case R_HEX_12_X:
     or32le(Loc, applyMask(0x000007e0, Val));
     break;

Modified: lld/trunk/test/ELF/hexagon.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/hexagon.s?rev=339332&r1=339331&r2=339332&view=diff
==============================================================================
--- lld/trunk/test/ELF/hexagon.s (original)
+++ lld/trunk/test/ELF/hexagon.s Thu Aug  9 05:00:10 2018
@@ -29,3 +29,125 @@ call #_start
 call ##_start
 # CHECK: immext(#4294967232)
 # CHECK: call 0x11000
+
+# R_HEX_6_X tests:
+# One test for each mask in the lookup table.
+
+#0x38000000
+if (!P0) memw(r0+#8)=##_start
+# CHECK: 38c0c100   	if (!p0) memw(r0+#8) = ##69632 }
+
+#0x39000000
+{ p0 = p1
+  if (!P0.new) memw(r0+#0)=##_start }
+# CHECK: 39c0c000   	if (!p0.new) memw(r0+#0) = ##69632 }
+
+#0x3e000000
+memw(r0+##_start)+=r1
+# CHECK: 3e40c001   	memw(r0+##69632) += r1 }
+
+#0x3f000000
+memw(r0+##_start)+=#4
+# CHECK: 3f40c004   	memw(r0+##69632) += #4 }
+
+#0x40000000
+{ r0 = r1
+  if (p0) memb(r0+##_start)=r0.new }
+# CHECK: 40a0c200   	if (p0) memb(r0+##69632) = r0.new }
+
+#0x41000000
+if (p0) r0=memb(r1+##_start)
+# CHECK: 4101c000   	if (p0) r0 = memb(r1+##69632) }
+
+#0x42000000
+{ r0 = r1
+  p0 = p1
+  if (p0.new) memb(r0+##_start)=r0.new }
+# CHECK: 42a0c200   	if (p0.new) memb(r0+##69632) = r0.new }
+
+#0x43000000
+{ p0 = p1
+ if (P0.new) r0=memb(r0+##_start) }
+# CHECK: 4300c000   	if (p0.new) r0 = memb(r0+##69632) }
+
+#0x44000000
+if (!p0) memb(r0+##_start)=r1
+# CHECK: 4400c100   	if (!p0) memb(r0+##69632) = r1 }
+
+#0x45000000
+if (!p0) r0=memb(r1+##_start)
+# CHECK: 4501c000   	if (!p0) r0 = memb(r1+##69632) }
+
+#0x46000000
+{ p0 = p1
+  if (!p0.new) memb(r0+##_start)=r1 }
+# CHECK: 4600c100   	if (!p0.new) memb(r0+##69632) = r1 }
+
+#0x47000000
+{ p0 = p1
+  if (!p0.new) r0=memb(r1+##_start) }
+# CHECK: 4701c000   	if (!p0.new) r0 = memb(r1+##69632) }
+
+#0x6a000000 -- Note 4294967132 == -0xa4 the distance between
+#              here and _start, so this will change if
+#              tests are added between here and _start
+r0=add(pc,##_start at pcrel)
+# CHECK: 6a49ce00  	r0 = add(pc,##4294967132) }
+
+#0x7c000000
+r1:0=combine(#8,##_start)
+# CHECK: 7c80c100   	r1:0 = combine(#8,##69632) }
+
+#0x9a000000
+r1:0=memb_fifo(r2=##_start)
+# CHECK: 9a82d000   	r1:0 = memb_fifo(r2=##69632) }
+
+#0x9b000000
+r0=memb(r1=##_start)
+# CHECK: 9b01d000   	r0 = memb(r1=##69632) }
+
+#0x9c000000
+r1:0=memb_fifo(r2<<#2+##_start)
+# CHECK: 9c82f000   	r1:0 = memb_fifo(r2<<#2+##69632) }
+
+#0x9d000000
+r0=memb(r1<<#2+##_start)
+# CHECK: 9d01f000   	r0 = memb(r1<<#2+##69632) }
+
+#0x9f000000
+if (!p0) r0=memb(##_start)
+# CHECK: 9f00e880   	if (!p0) r0 = memb(##69632) }
+
+#0xab000000
+memb(r0=##_start)=r1
+# CHECK: ab00c180   	memb(r0=##69632) = r1 }
+
+#0xad000000
+memb(r0<<#2+##_start)=r1
+# CHECK: ad00e180   	memb(r0<<#2+##69632) = r1 }
+
+#0xaf000000
+if (!p0) memb(##_start)=r1
+# CHECK: af00c184   	if (!p0) memb(##69632) = r1 }
+
+#0xd7000000
+r0=add(##_start,mpyi(r1,r2))
+# CHECK: d701c200   	r0 = add(##69632,mpyi(r1,r2)) }
+
+#0xd8000000
+R0=add(##_start,mpyi(r0,#2))
+# CHECK: d800c002   	r0 = add(##69632,mpyi(r0,#2)) }
+
+#0xdb000000
+r0=add(r1,add(r2,##_start))
+# CHECK: db01c002   	r0 = add(r1,add(r2,##69632)) }
+
+#0xdf000000
+r0=add(r1,mpyi(r2,##_start))
+# CHECK: df82c001   	r0 = add(r1,mpyi(r2,##69632)) }
+
+# Duplex form of R_HEX_6_X
+# R_HEX_32_6_X
+# R_HEX_6_X
+{ r0 = ##_start; r2 = r16 }
+# CHECK: 28003082   	r0 = ##69632; 	r2 = r16 }




More information about the llvm-commits mailing list