[klibc] [PATCH klibc 1/3] mips64: Compatibility with R6 compact branches

Ben Hutchings ben at decadent.org.uk
Sun Jul 16 09:12:38 PDT 2023


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 @@ and the old system call ABI are used.
 * 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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.zytor.com/archives/klibc/attachments/20230716/478fb254/attachment.sig>


More information about the klibc mailing list