Skip to contentSkip to conversation

mips: cps: Assemble jr.hb with an R2 ISA level

PATCH Applied Rosen Penev 3 participants 3 messages May 7 – May 26 MIPS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mips: cps: Assemble jr.hb with an R2 ISA level

A MIPS allmodconfig built with LLVM can select CPU_MIPS32_R1 together with MIPS_MT_SMP. In that configuration clang invokes the integrated assembler with -march=mips32, and the MIPS MT path in cps-vec.S fails to assemble two jr.hb instructions:

arch/mips/kernel/cps-vec.S:376:2: error: instruction requires a CPU feature not currently enabled

arch/mips/kernel/cps-vec.S:490:4: error: instruction requires a CPU feature not currently enabled

The earlier jr.hb in the same file is already assembled inside a .set MIPS_ISA_LEVEL_RAW scope. The two failing sites are reached after popping back to the file's base ISA level, so LLVM correctly rejects them for an R1 target.

Wrap those jr.hb instructions in the same ISA-level push/pop used by the working site. This keeps the MT code unchanged while making the required R2 hazard-branch encoding explicit to the assembler.

Assisted-by Codex:GPT-5.5
---
 arch/mips/kernel/cps-vec.S | 6 ++++++
 1 file changed, 6 insertions(+)
arch/mips/kernel/cps-vec.S +6 -0
index 2ae7034a3d5c..70413c816eb0 100644
@@ -373,8 +373,11 @@ LEAF(mips_cps_boot_vpes)
 	.set	pop
 
 	PTR_LA	t1, 1f
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
 	jr.hb	t1
 	 nop
+	.set	pop
 1:	mfc0	t1, CP0_MVPCONTROL
 	ori	t1, t1, MVPCONTROL_VPC
 	mtc0	t1, CP0_MVPCONTROL
@@ -487,8 +490,11 @@ LEAF(mips_cps_boot_vpes)
 	li	t0, TCHALT_H
 	mtc0	t0, CP0_TCHALT
 	PTR_LA	t0, 1f
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
 1:	jr.hb	t0
 	 nop
+	.set	pop
 
 2:
 
Signature · 1 line
2.54.0
Reviewed-by on v1 1/1
#1 lore raw
Quoted 18 lines · Rosen Penev
arch/mips/kernel/cps-vec.S +3 -0
index 2ae7034a3d5c..70413c816eb0 100644
@@ -373,8 +373,11 @@ LEAF(mips_cps_boot_vpes)
 	.set	pop
 
 	PTR_LA	t1, 1f
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
 	jr.hb	t1
 	 nop
+	.set	pop
 1:	mfc0	t1, CP0_MVPCONTROL
 	ori	t1, t1, MVPCONTROL_VPC
 	mtc0	t1, CP0_MVPCONTROL
@@ -487,8 +490,11 @@ LEAF(mips_cps_boot_vpes)
 	li	t0, TCHALT_H

arch/mips/kernel/cps-vec.S LEAF(mips_cps_boot_vpes) · line 500

Quoted 10 lines
arch/mips/kernel/cps-vec.S +3 -0
 	mtc0	t0, CP0_TCHALT
 	PTR_LA	t0, 1f
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
 1:	jr.hb	t0
 	 nop
+	.set	pop
 
 2:
 

This seems exceedingly pedantic to me at the cost of cluttering code with
these .set push/pop blocks. Why not simply wrap the whole code block down to the end of the CONFIG_MIPS_MT_SMP conditional instead, analogously to how mips_cps_core_init() has been arranged? The presence of MT implies R2 after all.

Ah, I can see we have MIPS_ISA_LEVEL_RAW always hardcoded to a 64-bit one
and commit 8dbc1864b74f ("MIPS: CPS: Fix MIPS_ISA_LEVEL_RAW fallout") reporting the MOVE macro getting expanded to a 64-bit DADDU instruction on 64-bit ISAs, which is obviously not incorrect (you get what you asked for), though also problematic in this use case.

This is actually no longer relevant however, as this was changed back in
2025 with binutils commit 40fc1451c63d ("[MIPS] Map 'move' to 'or'.") targetting version 2.26, while our requirement nowadays is 2.30, according to Documentation/process/changes.rst. It is a fairly recent requirement though, from Linux 6.16 only, and the previous one was 2.25, so backports would be affected and it might be too early to rely on for a bug fix.

Still my guts' feeling is we should define MIPS_ISA_LEVEL_RAW and the
other such macros to a 32-bit or 64-bit ISA according to the machine word size of the CPU/ISA chosen for the whole kernel build. This would enable the cleanup I suggested at the top with no reservation and remove the risk of GAS choosing to produce 64-bit instructions where a 32-bit CPU/ISA has been chosen in the configuration.

You are welcome to do that, however as it stands your patch is not
incorrect and fixes a real problem, so:

Maciej

maintainer Applied
#2 lore raw
In reply to Rosen Penev
Quoted 20 lines · Rosen Penev

A MIPS allmodconfig built with LLVM can select CPU_MIPS32_R1 together with MIPS_MT_SMP. In that configuration clang invokes the integrated assembler with -march=mips32, and the MIPS MT path in cps-vec.S fails to assemble two jr.hb instructions:

arch/mips/kernel/cps-vec.S:376:2: error: instruction requires a CPU feature not currently enabled

arch/mips/kernel/cps-vec.S:490:4: error: instruction requires a CPU feature not currently enabled

The earlier jr.hb in the same file is already assembled inside a .set MIPS_ISA_LEVEL_RAW scope. The two failing sites are reached after popping back to the file's base ISA level, so LLVM correctly rejects them for an R1 target.

Wrap those jr.hb instructions in the same ISA-level push/pop used by the working site. This keeps the MT code unchanged while making the required R2 hazard-branch encoding explicit to the assembler.

Quoted 5 lines
Assisted-by Codex:GPT-5.5
---
 arch/mips/kernel/cps-vec.S | 6 ++++++
 1 file changed, 6 insertions(+)

applied to mips-next

Thomas.

Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]