[PATCH] D144012: [SPARC][MC] Fix encoding of backwards BPr branches

Koakuma via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 4 02:14:22 PST 2023


koakuma updated this revision to Diff 502362.
koakuma added a comment.

- Fix calculation for `fixup_sparc_br16_2`.
- Make sure to properly shift fixup values as described in the fixup tables.
- Only emit one R_SPARC_WDISP16 relocation per one fixup_sparc_br16_14/2 pair.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144012/new/

https://reviews.llvm.org/D144012

Files:
  llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
  llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
  llvm/test/MC/Sparc/sparc64-bpr-offset.s


Index: llvm/test/MC/Sparc/sparc64-bpr-offset.s
===================================================================
--- /dev/null
+++ llvm/test/MC/Sparc/sparc64-bpr-offset.s
@@ -0,0 +1,31 @@
+! RUN: llvm-mc -arch=sparcv9 -filetype=obj %s | llvm-objdump -d - | FileCheck %s --check-prefix=BIN
+
+        !! SPARCv9/SPARC64 BPr branches have different offset encoding for the others,
+        !! make sure that our offset bits don't trample on other fields.
+        !! This is particularly important with backwards branches.
+
+        ! BIN:  0: 02 c8 40 01  	brz %g1, 1
+        ! BIN:  4: 04 c8 40 01  	brlez %g1, 1
+        ! BIN:  8: 06 c8 40 01  	brlz %g1, 1
+        ! BIN:  c: 0a c8 40 01  	brnz %g1, 1
+        ! BIN: 10: 0c c8 40 01  	brgz %g1, 1
+        ! BIN: 14: 0e c8 40 01  	brgez %g1, 1
+        brz   %g1, .+4
+        brlez %g1, .+4
+        brlz  %g1, .+4
+        brnz  %g1, .+4
+        brgz  %g1, .+4
+        brgez %g1, .+4
+
+        ! BIN: 18: 02 f8 7f ff  	brz %g1, 65535
+        ! BIN: 1c: 04 f8 7f ff  	brlez %g1, 65535
+        ! BIN: 20: 06 f8 7f ff  	brlz %g1, 65535
+        ! BIN: 24: 0a f8 7f ff  	brnz %g1, 65535
+        ! BIN: 28: 0c f8 7f ff  	brgz %g1, 65535
+        ! BIN: 2c: 0e f8 7f ff  	brgez %g1, 65535
+        brz   %g1, .-4
+        brlez %g1, .-4
+        brlz  %g1, .-4
+        brnz  %g1, .-4
+        brgz  %g1, .-4
+        brgez %g1, .-4
Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
===================================================================
--- llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -10,6 +10,7 @@
 #include "MCTargetDesc/SparcMCExpr.h"
 #include "MCTargetDesc/SparcMCTargetDesc.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectWriter.h"
@@ -62,6 +63,14 @@
     case Sparc::fixup_sparc_call30:  return ELF::R_SPARC_WDISP30;
     case Sparc::fixup_sparc_br22:    return ELF::R_SPARC_WDISP22;
     case Sparc::fixup_sparc_br19:    return ELF::R_SPARC_WDISP19;
+    case Sparc::fixup_sparc_br16_14:
+      return ELF::R_SPARC_WDISP16;
+    case Sparc::fixup_sparc_br16_2:
+      // fixup_sparc_br16_14/fixup_sparc_br16_2 are always
+      // emitted in pairs, but since there's no ELF relocation for
+      // split bits, emit the real relocation in the _14 part
+      // and here, in the _2 part, emit an R_SPARC_NONE instead.
+      return ELF::R_SPARC_NONE;
     case Sparc::fixup_sparc_pc22:    return ELF::R_SPARC_PC22;
     case Sparc::fixup_sparc_pc10:    return ELF::R_SPARC_PC10;
     case Sparc::fixup_sparc_wplt30:  return ELF::R_SPARC_WPLT30;
Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
===================================================================
--- llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -42,7 +42,7 @@
     return (Value >> 2) & 0x7ffff;
 
   case Sparc::fixup_sparc_br16_2:
-    return (Value >> 2) & 0xc000;
+    return (Value >> 16) & 0x3;
 
   case Sparc::fixup_sparc_br16_14:
     return (Value >> 2) & 0x3fff;
@@ -345,9 +345,16 @@
 
       if (Fixup.getKind() >= FirstLiteralRelocationKind)
         return;
+      MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
       Value = adjustFixupValue(Fixup.getKind(), Value);
       if (!Value) return;           // Doesn't change encoding.
 
+      // Shift the value into position.
+      if (Endian == support::little)
+        Value <<= Info.TargetOffset;
+      else
+        Value <<= 32 - Info.TargetOffset - Info.TargetSize;
+
       unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
       unsigned Offset = Fixup.getOffset();
       // For each byte of the fragment that the fixup touches, mask in the bits


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144012.502362.patch
Type: text/x-patch
Size: 3898 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230304/2ed86fd4/attachment.bin>


More information about the llvm-commits mailing list