From bd885401d5a4b45fee8ae37069be0cc3beef9e3e Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Mon, 18 Aug 2025 14:58:03 +0800 Subject: [PATCH] runtime: save and restore all fcc registers in async preempt on loong64 Currently, all Op implementations on loong64 use fcc0 by default, so only fcc0 is saved in CL 475577. However, fcc1-fcc7 may also be used by users when writing assembly code, such as in CL 693878. Change-Id: Idb60d8101a0f7d602dfcbbb39bd5da9f2c475bfd Reviewed-on: https://go-review.googlesource.com/c/go/+/696875 LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase Reviewed-by: sophie zhao Reviewed-by: Meidan Li Reviewed-by: Carlos Amedee --- src/runtime/mkpreempt.go | 26 +++++++++++++++++++++++--- src/runtime/preempt_loong64.s | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go index 2bd2ef07fa..769c4ffc5c 100644 --- a/src/runtime/mkpreempt.go +++ b/src/runtime/mkpreempt.go @@ -610,10 +610,30 @@ func genLoong64(g *gen) { l.add(movf, reg, regsize) } - // save/restore FCC0 + // Add condition flag register fcc0-fcc7 + sv := "" + rs := "" + last := 7 + for i := 0; i <= last; i++ { + msb := 7 + (i * 8) + lsb := 0 + (i * 8) + + // MOVV FCCx, R4, + // BSTRINSV $msb, R4, $lsb, R5 + sv += fmt.Sprintf("%s FCC%d, R4\n", mov, i) + sv += fmt.Sprintf("BSTRINSV $%d, R4, $%d, R5\n", msb, lsb) + + // BSTRPICKV $msb, R5, $lsb, R4 + // MOVV R4, FCCx + rs += fmt.Sprintf("BSTRPICKV $%d, R5, $%d, R4\n", msb, lsb) + rs += fmt.Sprintf("%s R4, FCC%d", mov, i) + if i != last { + rs += fmt.Sprintf("\n") + } + } l.addSpecial( - mov+" FCC0, R4\n"+mov+" R4, %d(R3)", - mov+" %d(R3), R4\n"+mov+" R4, FCC0", + sv+mov+" R5, %d(R3)", + mov+" %d(R3), R5\n"+rs, regsize) // allocate frame, save PC of interrupted instruction (in LR) diff --git a/src/runtime/preempt_loong64.s b/src/runtime/preempt_loong64.s index bb9c948365..626dc4b6f6 100644 --- a/src/runtime/preempt_loong64.s +++ b/src/runtime/preempt_loong64.s @@ -65,10 +65,40 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0 MOVD F30, 456(R3) MOVD F31, 464(R3) MOVV FCC0, R4 - MOVV R4, 472(R3) + BSTRINSV $7, R4, $0, R5 + MOVV FCC1, R4 + BSTRINSV $15, R4, $8, R5 + MOVV FCC2, R4 + BSTRINSV $23, R4, $16, R5 + MOVV FCC3, R4 + BSTRINSV $31, R4, $24, R5 + MOVV FCC4, R4 + BSTRINSV $39, R4, $32, R5 + MOVV FCC5, R4 + BSTRINSV $47, R4, $40, R5 + MOVV FCC6, R4 + BSTRINSV $55, R4, $48, R5 + MOVV FCC7, R4 + BSTRINSV $63, R4, $56, R5 + MOVV R5, 472(R3) CALL ·asyncPreempt2(SB) - MOVV 472(R3), R4 + MOVV 472(R3), R5 + BSTRPICKV $7, R5, $0, R4 MOVV R4, FCC0 + BSTRPICKV $15, R5, $8, R4 + MOVV R4, FCC1 + BSTRPICKV $23, R5, $16, R4 + MOVV R4, FCC2 + BSTRPICKV $31, R5, $24, R4 + MOVV R4, FCC3 + BSTRPICKV $39, R5, $32, R4 + MOVV R4, FCC4 + BSTRPICKV $47, R5, $40, R4 + MOVV R4, FCC5 + BSTRPICKV $55, R5, $48, R4 + MOVV R4, FCC6 + BSTRPICKV $63, R5, $56, R4 + MOVV R4, FCC7 MOVD 464(R3), F31 MOVD 456(R3), F30 MOVD 448(R3), F29 -- 2.52.0