Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 758ef0a9 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Ralf Baechle
Browse files

MIPS: Fix ISA I/II FP signal context offsets



Fix a regression introduced with commit 2db9ca0a ("MIPS: Use struct
mips_abi offsets to save FP context") for MIPS I/I FP signal contexts,
by converting save/restore code to the updated internal API.  Start FGR
offsets from 0 rather than SC_FPREGS from $a0 and use $a1 rather than
the offset of SC_FPC_CSR from $a0 for the Floating Point Control/Status
Register (FCSR).

Document the new internal API and adjust assembly code formatting for
consistency.

Signed-off-by: default avatarMaciej W. Rozycki <macro@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/14476/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 6daaa326
Loading
Loading
Loading
Loading
+83 −76
Original line number Diff line number Diff line
@@ -26,95 +26,102 @@

	.set	noreorder
	.set	mips1
	/* Save floating point context */

/**
 * _save_fp_context() - save FP context from the FPU
 * @a0 - pointer to fpregs field of sigcontext
 * @a1 - pointer to fpc_csr field of sigcontext
 *
 * Save FP context, including the 32 FP data registers and the FP
 * control & status register, from the FPU to signal context.
 */
LEAF(_save_fp_context)
	.set	push
	SET_HARDFLOAT
	li	v0, 0					# assume success
	cfc1	t1, fcr31
	EX(swc1 $f0,(SC_FPREGS+0)(a0))
	EX(swc1 $f1,(SC_FPREGS+8)(a0))
	EX(swc1 $f2,(SC_FPREGS+16)(a0))
	EX(swc1 $f3,(SC_FPREGS+24)(a0))
	EX(swc1 $f4,(SC_FPREGS+32)(a0))
	EX(swc1 $f5,(SC_FPREGS+40)(a0))
	EX(swc1 $f6,(SC_FPREGS+48)(a0))
	EX(swc1 $f7,(SC_FPREGS+56)(a0))
	EX(swc1 $f8,(SC_FPREGS+64)(a0))
	EX(swc1 $f9,(SC_FPREGS+72)(a0))
	EX(swc1 $f10,(SC_FPREGS+80)(a0))
	EX(swc1 $f11,(SC_FPREGS+88)(a0))
	EX(swc1 $f12,(SC_FPREGS+96)(a0))
	EX(swc1 $f13,(SC_FPREGS+104)(a0))
	EX(swc1 $f14,(SC_FPREGS+112)(a0))
	EX(swc1 $f15,(SC_FPREGS+120)(a0))
	EX(swc1 $f16,(SC_FPREGS+128)(a0))
	EX(swc1 $f17,(SC_FPREGS+136)(a0))
	EX(swc1 $f18,(SC_FPREGS+144)(a0))
	EX(swc1 $f19,(SC_FPREGS+152)(a0))
	EX(swc1 $f20,(SC_FPREGS+160)(a0))
	EX(swc1 $f21,(SC_FPREGS+168)(a0))
	EX(swc1 $f22,(SC_FPREGS+176)(a0))
	EX(swc1 $f23,(SC_FPREGS+184)(a0))
	EX(swc1 $f24,(SC_FPREGS+192)(a0))
	EX(swc1 $f25,(SC_FPREGS+200)(a0))
	EX(swc1 $f26,(SC_FPREGS+208)(a0))
	EX(swc1 $f27,(SC_FPREGS+216)(a0))
	EX(swc1 $f28,(SC_FPREGS+224)(a0))
	EX(swc1 $f29,(SC_FPREGS+232)(a0))
	EX(swc1 $f30,(SC_FPREGS+240)(a0))
	EX(swc1 $f31,(SC_FPREGS+248)(a0))
	EX(swc1 $f0, 0(a0))
	EX(swc1 $f1, 8(a0))
	EX(swc1 $f2, 16(a0))
	EX(swc1 $f3, 24(a0))
	EX(swc1 $f4, 32(a0))
	EX(swc1 $f5, 40(a0))
	EX(swc1 $f6, 48(a0))
	EX(swc1 $f7, 56(a0))
	EX(swc1 $f8, 64(a0))
	EX(swc1 $f9, 72(a0))
	EX(swc1 $f10, 80(a0))
	EX(swc1 $f11, 88(a0))
	EX(swc1 $f12, 96(a0))
	EX(swc1 $f13, 104(a0))
	EX(swc1 $f14, 112(a0))
	EX(swc1 $f15, 120(a0))
	EX(swc1 $f16, 128(a0))
	EX(swc1 $f17, 136(a0))
	EX(swc1 $f18, 144(a0))
	EX(swc1 $f19, 152(a0))
	EX(swc1 $f20, 160(a0))
	EX(swc1 $f21, 168(a0))
	EX(swc1 $f22, 176(a0))
	EX(swc1 $f23, 184(a0))
	EX(swc1 $f24, 192(a0))
	EX(swc1 $f25, 200(a0))
	EX(swc1 $f26, 208(a0))
	EX(swc1 $f27, 216(a0))
	EX(swc1 $f28, 224(a0))
	EX(swc1 $f29, 232(a0))
	EX(swc1 $f30, 240(a0))
	EX(swc1 $f31, 248(a0))
	jr	ra
	 EX(sw	t1,(SC_FPC_CSR)(a0))
	 EX(sw	t1, (a1))
	.set	pop
	END(_save_fp_context)

/*
 * Restore FPU state:
 *  - fp gp registers
 *  - cp1 status/control register
/**
 * _restore_fp_context() - restore FP context to the FPU
 * @a0 - pointer to fpregs field of sigcontext
 * @a1 - pointer to fpc_csr field of sigcontext
 *
 * We base the decision which registers to restore from the signal stack
 * frame on the current content of c0_status, not on the content of the
 * stack frame which might have been changed by the user.
 * Restore FP context, including the 32 FP data registers and the FP
 * control & status register, from signal context to the FPU.
 */
LEAF(_restore_fp_context)
	.set	push
	SET_HARDFLOAT
	li	v0, 0					# assume success
	EX(lw t0,(SC_FPC_CSR)(a0))
	EX(lwc1 $f0,(SC_FPREGS+0)(a0))
	EX(lwc1 $f1,(SC_FPREGS+8)(a0))
	EX(lwc1 $f2,(SC_FPREGS+16)(a0))
	EX(lwc1 $f3,(SC_FPREGS+24)(a0))
	EX(lwc1 $f4,(SC_FPREGS+32)(a0))
	EX(lwc1 $f5,(SC_FPREGS+40)(a0))
	EX(lwc1 $f6,(SC_FPREGS+48)(a0))
	EX(lwc1 $f7,(SC_FPREGS+56)(a0))
	EX(lwc1 $f8,(SC_FPREGS+64)(a0))
	EX(lwc1 $f9,(SC_FPREGS+72)(a0))
	EX(lwc1 $f10,(SC_FPREGS+80)(a0))
	EX(lwc1 $f11,(SC_FPREGS+88)(a0))
	EX(lwc1 $f12,(SC_FPREGS+96)(a0))
	EX(lwc1 $f13,(SC_FPREGS+104)(a0))
	EX(lwc1 $f14,(SC_FPREGS+112)(a0))
	EX(lwc1 $f15,(SC_FPREGS+120)(a0))
	EX(lwc1 $f16,(SC_FPREGS+128)(a0))
	EX(lwc1 $f17,(SC_FPREGS+136)(a0))
	EX(lwc1 $f18,(SC_FPREGS+144)(a0))
	EX(lwc1 $f19,(SC_FPREGS+152)(a0))
	EX(lwc1 $f20,(SC_FPREGS+160)(a0))
	EX(lwc1 $f21,(SC_FPREGS+168)(a0))
	EX(lwc1 $f22,(SC_FPREGS+176)(a0))
	EX(lwc1 $f23,(SC_FPREGS+184)(a0))
	EX(lwc1 $f24,(SC_FPREGS+192)(a0))
	EX(lwc1 $f25,(SC_FPREGS+200)(a0))
	EX(lwc1 $f26,(SC_FPREGS+208)(a0))
	EX(lwc1 $f27,(SC_FPREGS+216)(a0))
	EX(lwc1 $f28,(SC_FPREGS+224)(a0))
	EX(lwc1 $f29,(SC_FPREGS+232)(a0))
	EX(lwc1 $f30,(SC_FPREGS+240)(a0))
	EX(lwc1 $f31,(SC_FPREGS+248)(a0))
	EX(lw t0, (a1))
	EX(lwc1 $f0, 0(a0))
	EX(lwc1 $f1, 8(a0))
	EX(lwc1 $f2, 16(a0))
	EX(lwc1 $f3, 24(a0))
	EX(lwc1 $f4, 32(a0))
	EX(lwc1 $f5, 40(a0))
	EX(lwc1 $f6, 48(a0))
	EX(lwc1 $f7, 56(a0))
	EX(lwc1 $f8, 64(a0))
	EX(lwc1 $f9, 72(a0))
	EX(lwc1 $f10, 80(a0))
	EX(lwc1 $f11, 88(a0))
	EX(lwc1 $f12, 96(a0))
	EX(lwc1 $f13, 104(a0))
	EX(lwc1 $f14, 112(a0))
	EX(lwc1 $f15, 120(a0))
	EX(lwc1 $f16, 128(a0))
	EX(lwc1 $f17, 136(a0))
	EX(lwc1 $f18, 144(a0))
	EX(lwc1 $f19, 152(a0))
	EX(lwc1 $f20, 160(a0))
	EX(lwc1 $f21, 168(a0))
	EX(lwc1 $f22, 176(a0))
	EX(lwc1 $f23, 184(a0))
	EX(lwc1 $f24, 192(a0))
	EX(lwc1 $f25, 200(a0))
	EX(lwc1 $f26, 208(a0))
	EX(lwc1 $f27, 216(a0))
	EX(lwc1 $f28, 224(a0))
	EX(lwc1 $f29, 232(a0))
	EX(lwc1 $f30, 240(a0))
	EX(lwc1 $f31, 248(a0))
	jr	ra
	 ctc1	t0, fcr31
	.set	pop
+48 −41
Original line number Diff line number Diff line
@@ -21,7 +21,14 @@
	.set	push
	SET_HARDFLOAT

	/* Save floating point context */
/**
 * _save_fp_context() - save FP context from the FPU
 * @a0 - pointer to fpregs field of sigcontext
 * @a1 - pointer to fpc_csr field of sigcontext
 *
 * Save FP context, including the 32 FP data registers and the FP
 * control & status register, from the FPU to signal context.
 */
	LEAF(_save_fp_context)
	mfc0	t0,CP0_STATUS
	sll	t0,t0,2
@@ -30,59 +37,59 @@

	cfc1	t1,fcr31
	/* Store the 16 double precision registers */
	sdc1	$f0,(SC_FPREGS+0)(a0)
	sdc1	$f2,(SC_FPREGS+16)(a0)
	sdc1	$f4,(SC_FPREGS+32)(a0)
	sdc1	$f6,(SC_FPREGS+48)(a0)
	sdc1	$f8,(SC_FPREGS+64)(a0)
	sdc1	$f10,(SC_FPREGS+80)(a0)
	sdc1	$f12,(SC_FPREGS+96)(a0)
	sdc1	$f14,(SC_FPREGS+112)(a0)
	sdc1	$f16,(SC_FPREGS+128)(a0)
	sdc1	$f18,(SC_FPREGS+144)(a0)
	sdc1	$f20,(SC_FPREGS+160)(a0)
	sdc1	$f22,(SC_FPREGS+176)(a0)
	sdc1	$f24,(SC_FPREGS+192)(a0)
	sdc1	$f26,(SC_FPREGS+208)(a0)
	sdc1	$f28,(SC_FPREGS+224)(a0)
	sdc1	$f30,(SC_FPREGS+240)(a0)
	sdc1	$f0,0(a0)
	sdc1	$f2,16(a0)
	sdc1	$f4,32(a0)
	sdc1	$f6,48(a0)
	sdc1	$f8,64(a0)
	sdc1	$f10,80(a0)
	sdc1	$f12,96(a0)
	sdc1	$f14,112(a0)
	sdc1	$f16,128(a0)
	sdc1	$f18,144(a0)
	sdc1	$f20,160(a0)
	sdc1	$f22,176(a0)
	sdc1	$f24,192(a0)
	sdc1	$f26,208(a0)
	sdc1	$f28,224(a0)
	sdc1	$f30,240(a0)
	jr	ra
	 sw	t0,SC_FPC_CSR(a0)
	 sw	t0,(a1)
1:	jr	ra
	 nop
	END(_save_fp_context)

/* Restore FPU state:
 *  - fp gp registers
 *  - cp1 status/control register
/**
 * _restore_fp_context() - restore FP context to the FPU
 * @a0 - pointer to fpregs field of sigcontext
 * @a1 - pointer to fpc_csr field of sigcontext
 *
 * We base the decision which registers to restore from the signal stack
 * frame on the current content of c0_status, not on the content of the
 * stack frame which might have been changed by the user.
 * Restore FP context, including the 32 FP data registers and the FP
 * control & status register, from signal context to the FPU.
 */
	LEAF(_restore_fp_context)
	mfc0	t0,CP0_STATUS
	sll	t0,t0,2

	bgez	t0,1f
	 lw	t0,SC_FPC_CSR(a0)
	 lw	t0,(a1)
	/* Restore the 16 double precision registers */
	ldc1	$f0,(SC_FPREGS+0)(a0)
	ldc1	$f2,(SC_FPREGS+16)(a0)
	ldc1	$f4,(SC_FPREGS+32)(a0)
	ldc1	$f6,(SC_FPREGS+48)(a0)
	ldc1	$f8,(SC_FPREGS+64)(a0)
	ldc1	$f10,(SC_FPREGS+80)(a0)
	ldc1	$f12,(SC_FPREGS+96)(a0)
	ldc1	$f14,(SC_FPREGS+112)(a0)
	ldc1	$f16,(SC_FPREGS+128)(a0)
	ldc1	$f18,(SC_FPREGS+144)(a0)
	ldc1	$f20,(SC_FPREGS+160)(a0)
	ldc1	$f22,(SC_FPREGS+176)(a0)
	ldc1	$f24,(SC_FPREGS+192)(a0)
	ldc1	$f26,(SC_FPREGS+208)(a0)
	ldc1	$f28,(SC_FPREGS+224)(a0)
	ldc1	$f30,(SC_FPREGS+240)(a0)
	ldc1	$f0,0(a0)
	ldc1	$f2,16(a0)
	ldc1	$f4,32(a0)
	ldc1	$f6,48(a0)
	ldc1	$f8,64(a0)
	ldc1	$f10,80(a0)
	ldc1	$f12,96(a0)
	ldc1	$f14,112(a0)
	ldc1	$f16,128(a0)
	ldc1	$f18,144(a0)
	ldc1	$f20,160(a0)
	ldc1	$f22,176(a0)
	ldc1	$f24,192(a0)
	ldc1	$f26,208(a0)
	ldc1	$f28,224(a0)
	ldc1	$f30,240(a0)
	jr	ra
	 ctc1	t0,fcr31
1:	jr	ra