[lld] r288921 - ELF/AArch64: Refactor R_AARCH64_LDST{8, 15, 32, 64, 128}_ABS_LO12_NC Relocations

Adhemerval Zanella via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 7 09:31:49 PST 2016


Author: azanella
Date: Wed Dec  7 11:31:48 2016
New Revision: 288921

URL: http://llvm.org/viewvc/llvm-project?rev=288921&view=rev
Log:
ELF/AArch64: Refactor R_AARCH64_LDST{8,15,32,64,128}_ABS_LO12_NC Relocations

This patch refactor how to apply the R_AARCH64_LDST{8,16,32,64,128}_ABS_NC
relocations by adding a new function to correct extract the bits expected
by each relocation.  This make is explicit which are the bits range expected
and simplify the code to mask and shift the deriable values.

It also fixes the R_AARCH64_LDST128_ABS_LO12_NC mask, although in pratice
the mask/shift always returns a 16 bytes aligned value.

Checked on AArch64 and with test-suite.

Modified:
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=288921&r1=288920&r2=288921&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Dec  7 11:31:48 2016
@@ -1326,7 +1326,15 @@ static void updateAArch64Addr(uint8_t *L
   write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
 }
 
-static inline void updateAArch64Add(uint8_t *L, uint64_t Imm) {
+// Return the bits [Start, End] from Val shifted Start bits.  For instance,
+// getBits<4,8>(0xF0) returns 0xF.
+template <uint8_t Start, uint8_t End> static uint64_t getBits(uint64_t Val) {
+  uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
+  return (Val >> Start) & Mask;
+}
+
+// Update the immediate field in a ldr, str, and add instruction.
+static inline void updateAArch64LdStrAdd(uint8_t *L, uint64_t Imm) {
   or32le(L, (Imm & 0xFFF) << 10);
 }
 
@@ -1349,7 +1357,7 @@ void AArch64TargetInfo::relocateOne(uint
     write64le(Loc, Val);
     break;
   case R_AARCH64_ADD_ABS_LO12_NC:
-    updateAArch64Add(Loc, Val);
+    updateAArch64LdStrAdd(Loc, Val);
     break;
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_ADR_PREL_PG_HI21:
@@ -1377,20 +1385,20 @@ void AArch64TargetInfo::relocateOne(uint
     checkAlignment<8>(Loc, Val, Type);
     or32le(Loc, (Val & 0xFF8) << 7);
     break;
-  case R_AARCH64_LDST128_ABS_LO12_NC:
-    or32le(Loc, (Val & 0x0FF8) << 6);
+  case R_AARCH64_LDST8_ABS_LO12_NC:
+    updateAArch64LdStrAdd(Loc, getBits<0, 11>(Val));
     break;
   case R_AARCH64_LDST16_ABS_LO12_NC:
-    or32le(Loc, (Val & 0x0FFE) << 9);
-    break;
-  case R_AARCH64_LDST8_ABS_LO12_NC:
-    or32le(Loc, (Val & 0xFFF) << 10);
+    updateAArch64LdStrAdd(Loc, getBits<1, 11>(Val));
     break;
   case R_AARCH64_LDST32_ABS_LO12_NC:
-    or32le(Loc, (Val & 0xFFC) << 8);
+    updateAArch64LdStrAdd(Loc, getBits<2, 11>(Val));
     break;
   case R_AARCH64_LDST64_ABS_LO12_NC:
-    or32le(Loc, (Val & 0xFF8) << 7);
+    updateAArch64LdStrAdd(Loc, getBits<3, 11>(Val));
+    break;
+  case R_AARCH64_LDST128_ABS_LO12_NC:
+    updateAArch64LdStrAdd(Loc, getBits<4, 11>(Val));
     break;
   case R_AARCH64_MOVW_UABS_G0_NC:
     or32le(Loc, (Val & 0xFFFF) << 5);
@@ -1410,11 +1418,11 @@ void AArch64TargetInfo::relocateOne(uint
     break;
   case R_AARCH64_TLSLE_ADD_TPREL_HI12:
     checkInt<24>(Loc, Val, Type);
-    updateAArch64Add(Loc, Val >> 12);
+    updateAArch64LdStrAdd(Loc, Val >> 12);
     break;
   case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
   case R_AARCH64_TLSDESC_ADD_LO12_NC:
-    updateAArch64Add(Loc, Val);
+    updateAArch64LdStrAdd(Loc, Val);
     break;
   default:
     fatal(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));




More information about the llvm-commits mailing list