[klibc] [klibc:master] mips64: Compatibility with R6 compact branches

klibc-bot for Ben Hutchings ben at decadent.org.uk
Sun Jul 23 13:27:06 PDT 2023


Commit-ID:  e25809bbea2ed2825c543cb153d9f282eac26fc5
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=e25809bbea2ed2825c543cb153d9f282eac26fc5
Author:     Ben Hutchings <ben at decadent.org.uk>
AuthorDate: Sat, 15 Jul 2023 23:57:32 +0200
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sun, 16 Jul 2023 01:02:10 +0200

[klibc] mips64: Compatibility with R6 compact branches

MIPS R6 introduced compact branch instructions, including BALC as a
replacement for JAL.  Both BALC and JAL have a 26-bit offset field
that's shifted 2 bits left.  However, in BALC this is treated as a
PC-relative signed offset (±128 MiB) rather than a segment-relative
unsigned offset (0-256 MiB).

The base address of the klibc shared library therefore needs to change
depending on whether the executable calls it with JAL or BALC.

gcc (but not Clang, currently) generates BALC instructions for
external function calls on R6 targets, which breaks shared library
builds of klibc for these targets.  Add a config symbol to control
whether compact branches are used and to change the shared library
base address accordingly.

Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 usr/klibc/README.klibc        |  6 ++++++
 usr/klibc/arch/mips64/MCONFIG | 20 +++++++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/usr/klibc/README.klibc b/usr/klibc/README.klibc
index efbb70ff..1a9e09fe 100644
--- a/usr/klibc/README.klibc
+++ b/usr/klibc/README.klibc
@@ -80,6 +80,12 @@ For i386 only:
 * CONFIG_REGPARM (bool): Optimise function calls by passing the first
   3 function parameters in registers.
 
+For mips64 only:
+
+* CONFIG_KLIBC_MIPS_USE_CB (bool): Use compact branch instructions.
+  This should be enabled when targetting MIPS R6 and must be disabled
+  for older MIPS ISAs.
+
 Building without kernel source
 ------------------------------
 
diff --git a/usr/klibc/arch/mips64/MCONFIG b/usr/klibc/arch/mips64/MCONFIG
index ae879f49..e078dad7 100644
--- a/usr/klibc/arch/mips64/MCONFIG
+++ b/usr/klibc/arch/mips64/MCONFIG
@@ -13,12 +13,22 @@ KLIBCBITSIZE  = 64
 
 # Extra linkflags when building the shared version of the library
 # This address needs to be reachable using normal inter-module
-# calls, and work on the memory models for this architecture
-# 4862 MB - normal binaries start at 4608 MB. Non-PIC jumps usually
-# use the JAL instruction which requires a destination within the same
-# 256M aligned region. Since we can't put ourselves below the normal
-# load address, use the very top of the 256M region (minus 2MB)
+# calls, and work on the memory models for this architecture.
+# Normal binaries start at 0x120000000 (4608 MiB).
+# * On R5 and earlier, non-PIC jumps usually use the JAL instruction
+#   which requires a destination within the same 256 MiB aligned
+#   region. Since we can't put ourselves below the normal load
+#   address, use the very top of the 256 MiB region (minus 2 MiB).
+# * On R6, non-PIC jumps may use either the JAL instruction or the
+#   BALC instruction which requires a destination within ±128 MiB. Put
+#   ourselves just under 128 MiB above the executable base address.
+ifneq ($(CONFIG_KLIBC_MIPS_USE_CB),y)
+KLIBCARCHREQFLAGS    += $(call cc-option,-mcompact-branches=never)
 KLIBCSHAREDFLAGS     = $(LD_IMAGE_BASE_OPT) 0x12FE00000
+else
+KLIBCARCHREQFLAGS    += -mcompact-branches=optimal
+KLIBCSHAREDFLAGS     = $(LD_IMAGE_BASE_OPT) 0x127E00000
+endif
 
 # Kernel uses vDSO for signal return since 2.6.34
 KLIBCEXECSTACK := n


More information about the klibc mailing list