[llvm] 776d50d - [SPARC][MC] Fix encoding of backwards BPr branches
Brad Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu May 4 20:19:57 PDT 2023
Author: Brad Smith
Date: 2023-05-04T23:13:08-04:00
New Revision: 776d50d371a5da06bb156bf61a9efe38dfe4d65a
URL: https://github.com/llvm/llvm-project/commit/776d50d371a5da06bb156bf61a9efe38dfe4d65a
DIFF: https://github.com/llvm/llvm-project/commit/776d50d371a5da06bb156bf61a9efe38dfe4d65a.diff
LOG: [SPARC][MC] Fix encoding of backwards BPr branches
Make sure that the upper bits of the offset is placed in bits 20-21 of the
instruction word.
This fixes the encoding of backwards (negative offset) BPr branches.
(Previously, the upper two bits of the offset would overwrite parts of the rs1
field, causing it to branch on the wrong register, with the wrong offset)
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D144012
Added:
llvm/test/MC/Sparc/sparc64-bpr-offset.s
Modified:
llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
llvm/test/MC/Sparc/sparc64-ctrl-instructions.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index aa89488bbb62a..2c0696e8048b5 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -41,11 +41,14 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case Sparc::fixup_sparc_br19:
return (Value >> 2) & 0x7ffff;
- case Sparc::fixup_sparc_br16_2:
- return (Value >> 2) & 0xc000;
-
- case Sparc::fixup_sparc_br16_14:
- return (Value >> 2) & 0x3fff;
+ case Sparc::fixup_sparc_br16: {
+ // A.3 Branch on Integer Register with Prediction (BPr)
+ // Inst{21-20} = d16hi;
+ // Inst{13-0} = d16lo;
+ unsigned d16hi = (Value >> 16) & 0x3;
+ unsigned d16lo = (Value >> 2) & 0x3fff;
+ return (d16hi << 20) | d16lo;
+ }
case Sparc::fixup_sparc_hix22:
return (~Value >> 10) & 0x3fffff;
@@ -164,8 +167,7 @@ namespace {
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br16", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 19, 13, 0 },
{ "fixup_sparc_hi22", 10, 22, 0 },
{ "fixup_sparc_lo10", 22, 10, 0 },
@@ -211,8 +213,7 @@ namespace {
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br16", 32, 0, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 0, 13, 0 },
{ "fixup_sparc_hi22", 0, 22, 0 },
{ "fixup_sparc_lo10", 0, 10, 0 },
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index 9c50c41f6bf2e..c48beab012292 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -62,6 +62,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
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:
+ return ELF::R_SPARC_WDISP16;
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;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 701d8513e6579..3b91326589894 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -26,8 +26,7 @@ namespace llvm {
fixup_sparc_br19,
/// fixup_sparc_bpr - 16-bit fixup for bpr
- fixup_sparc_br16_2,
- fixup_sparc_br16_14,
+ fixup_sparc_br16,
/// fixup_sparc_13 - 13-bit fixup
fixup_sparc_13,
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index ee460002fc586..e69319fb9e264 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -235,10 +235,8 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
if (MO.isReg() || MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);
- Fixups.push_back(MCFixup::create(0, MO.getExpr(),
- (MCFixupKind)Sparc::fixup_sparc_br16_2));
- Fixups.push_back(MCFixup::create(0, MO.getExpr(),
- (MCFixupKind)Sparc::fixup_sparc_br16_14));
+ Fixups.push_back(
+ MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br16));
return 0;
}
diff --git a/llvm/test/MC/Sparc/sparc64-bpr-offset.s b/llvm/test/MC/Sparc/sparc64-bpr-offset.s
new file mode 100644
index 0000000000000..6c853c339c285
--- /dev/null
+++ b/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
diff erent offset encoding from 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
diff --git a/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s b/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s
index 737b95338c998..a21b17552eb15 100644
--- a/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s
+++ b/llvm/test/MC/Sparc/sparc64-ctrl-instructions.s
@@ -1150,24 +1150,18 @@
fbne,a,pn %fcc3, .BB0
- ! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
- ! CHECK: brlez %g1, .BB0 ! encoding: [0x04,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
- ! CHECK: brlz %g1, .BB0 ! encoding: [0x06,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
- ! CHECK: brnz %g1, .BB0 ! encoding: [0x0a,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
- ! CHECK: brgz %g1, .BB0 ! encoding: [0x0c,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
- ! CHECK: brgez %g1, .BB0 ! encoding: [0x0e,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz %g1, .BB0 ! encoding: [0x02'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
+ ! CHECK: brlez %g1, .BB0 ! encoding: [0x04'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
+ ! CHECK: brlz %g1, .BB0 ! encoding: [0x06'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
+ ! CHECK: brnz %g1, .BB0 ! encoding: [0x0a'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
+ ! CHECK: brgz %g1, .BB0 ! encoding: [0x0c'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
+ ! CHECK: brgez %g1, .BB0 ! encoding: [0x0e'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz %g1, .BB0
brlez %g1, .BB0
@@ -1176,29 +1170,24 @@
brgz %g1, .BB0
brgez %g1, .BB0
- ! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz %g1, .BB0 ! encoding: [0x02'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz,pt %g1, .BB0
- ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz,a %g1, .BB0
- ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22'A',0xc8'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz,a,pt %g1, .BB0
- ! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02,0b11AA0000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02'A',0xc0'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz,pn %g1, .BB0
- ! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22,0b11AA0000,0b01BBBBBB,B]
- ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2
- ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14
+ ! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22'A',0xc0'A',0x40'A',A]
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16
brz,a,pn %g1, .BB0
! CHECK: movrz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x44,0x02]
More information about the llvm-commits
mailing list