[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] [PATCH] FreeMiNT for ColdFire: FPU (2)



On 26/02/2013 23:02, Vincent Rivière wrote:
FireTOS fixes will follow tomorrow.

Here is the new patch.

Now I can compute 2 POV-Ray images simultaneously without any trouble on the FireBee, with both EmuTOS and FireTOS :-)

Please commit!

fpu2.patch
Added ColdFire FPU support in context switch for FireTOS. Contributed by Vincent Riviere.

--
Vincent Rivière
--- freemint-1.18.orig/sys/arch/context.S	2013-02-27 23:17:00.234375000 +0100
+++ freemint-1.18/sys/arch/context.S	2013-02-28 00:28:30.906250000 +0100
@@ -108,12 +108,9 @@
 	addq.l	#2,a1			// assume 2-byte filler after the exception frame
 build_stack_fixed:
 
-	// ColdFire FPU
-	fsave	C_FSTATE(a0)		// save internal state frame (including fpcr and fpsr)
-	fmovem.d fp0-fp7,C_FREGS(a0)	// save data registers
-	fmove.l	fpiar,C_FCTRL+8(a0)	// and control registers
+	pea	short1(pc)		// return address
+	bra	save_coldfire_fpu
 
-	bra.s	short1
 build_68k:
 #endif
 #ifdef M68000
@@ -136,17 +133,18 @@
 	tst.w	d1			// test longframe (AKP)
 	beq.s	short1			// short
 #endif
+
+// save the FPU state
+#ifdef	__mcoldfire__
+	pea	nofpu(pc)		// return address
+	bra	save_coldfire_fpu
+#else
 	tst.w	_fpu			// is there a true FPU in the system
 	beq.s	nofpu
 
 	fsave	C_FSTATE(a0)		// save internal state frame
 #ifndef M68000
-#ifdef	__mcoldfire__
-	moveq	#60,d1
-	cmp.w	_mcpu+2,d1		// on 68060 frame format is different
-#else
 	cmp.w	#60,_mcpu+2		// on 68060 frame format is different
-#endif
 	bne.s	no60
 	tst.b	C_FSTATE+2(a0)		// if NULL frame then the FPU is not in use
 	beq.s	nofpu			// skip programmer's model save
@@ -155,15 +153,10 @@
 #endif
 	tst.b	C_FSTATE(a0)		// if NULL frame then the FPU is not in use
 	beq.s	nofpu			// skip programmer's model save
-#ifdef	__mcoldfire__
-save:	fmovem.d fp0-fp7,C_FREGS(a0)		// save data registers
-	fmove.l	fpcr,C_FCTRL(a0)		// and control registers
-	fmove.l	fpsr,C_FCTRL+4(a0)
-	fmove.l	fpiar,C_FCTRL+8(a0)
-#else
 save:	fmovem.x fp0-fp7,C_FREGS(a0)		// save data registers
 	fmovem.l fpcr/fpsr/fpiar,C_FCTRL(a0)	// and control registers
-#endif
+#endif /* __mcoldfire__ */
+
 nofpu:
 	lea	C_SFMT(a0),a2
 #ifdef	__mcoldfire__
@@ -240,31 +233,18 @@
 noprot2:
 #endif
 
-#ifdef __mcoldfire__
-	tst.w	_coldfire_68k_emulation
-	bne.s	savefpu_68k
-
-	// ColdFire FPU
-	fsave	C_FSTATE(a0)		// save internal state frame (including fpcr and fpsr)
-	fmovem.d fp0-fp7,C_FREGS(a0)	// save data registers
-	fmove.l	fpiar,C_FCTRL+8(a0)	// and control registers
-
-	bra.s	nofpu2
-savefpu_68k:
-#endif
-
+// save the FPU state
+#ifdef	__mcoldfire__
+	pea	nofpu2(pc)		// return address
+	bra	save_coldfire_fpu
+#else
 // if running with a true coprocessor we need to save the FPU state
 
 	tst.w	_fpu			// is there a true FPU in the system
 	beq.s	nofpu2
 	fsave	C_FSTATE(a0)		// save internal state frame
 #ifndef M68000
-#ifdef	__mcoldfire__
-	moveq	#60,d1
-	cmp.w	_mcpu+2,d1		// on 68060 frame format is different
-#else
 	cmp.w	#60,_mcpu+2		// on 68060 frame format is different
-#endif
 	bne.s	no60_2
 	tst.b	C_FSTATE+2(a0)		// if NULL frame then the FPU is not in use
 	beq.s	nofpu2			// skip programmer's model save
@@ -273,15 +253,10 @@
 #endif
 	tst.b	C_FSTATE(a0)			// if NULL frame then the FPU is not in use
 	beq.s	nofpu2				// skip programmer's model save
-#ifdef	__mcoldfire__
-save2:	fmovem.d fp0-fp7,C_FREGS(a0)		// save data registers
-	fmove.l	fpcr,C_FCTRL(a0)		// and control registers
-	fmove.l	fpsr,C_FCTRL+4(a0)
-	fmove.l	fpiar,C_FCTRL+8(a0)
-#else
 save2:	fmovem.x fp0-fp7,C_FREGS(a0)		// save data registers
 	fmovem.l fpcr/fpsr/fpiar,C_FCTRL(a0)	// and control registers
-#endif
+#endif /* __mcoldfire__ */
+
 nofpu2:
 // note: I am somewhat unsure of this assumption, viz that save_context
 // can never be called in a situation where a co-processor
@@ -360,10 +335,7 @@
 	tst.w	_coldfire_68k_emulation
 	bne.s	restore_68k
 
-	// ColdFire FPU
-	fmove.l	C_FCTRL+8(a0),fpiar	// restore control registers
-	fmovem.d C_FREGS(a0),fp0-fp7	// and data registers
-	frestore C_FSTATE(a0)		// finally the internal state (including fpcr and fpsr)
+	bsr	restore_coldfire_fpu
 
 	move.l	C_PC(a0),-(sp)		// push the PC
 	move.w	C_SR(a0),-(sp)		// push the status register
@@ -424,16 +396,15 @@
 rcovernc:
 	move.w	d0,-(sp)		// frame format identifier
 
+// restore the FPU state
+#ifdef __mcoldfire__
+	bsr	restore_coldfire_fpu
+#else
 // if running with a true coprocessor we need to restore the FPU state
 	tst.w	_fpu			// is there a true FPU in the system
 	beq.s	short3
 #ifndef M68000
-#ifdef	__mcoldfire__
-	moveq	#60,d1
-	cmp.w	_mcpu+2,d1		// on 68060 frame format is different
-#else
 	cmp.w	#60,_mcpu+2		// on 68060 frame format is different
-#endif
 	bne.s	no60_3
 	tst.b	C_FSTATE+2(a0)
 	beq.s	short4
@@ -442,17 +413,12 @@
 #endif
 	tst.b	C_FSTATE(a0)			// if NULL frame then the FPU is not in use
 	beq.s	short4				// skip programmer's model restore
-#ifdef	__mcoldfire__
-save3:	fmove.l	C_FCTRL(a0),fpcr		// restore control registers
-	fmove.l	C_FCTRL+4(a0),fpsr
-	fmove.l	C_FCTRL+8(a0),fpiar
-	fmovem.d C_FREGS(a0),fp0-fp7		// and data registers
-#else
 save3:	fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar	// restore control registers
 	fmovem.x C_FREGS(a0),fp0-fp7		// and data registers
-#endif
 short4:
 	frestore C_FSTATE(a0)			// finally the internal state
+#endif /* __mcoldfire__ */
+
 short3:
 	move.l	C_PC(a0),-(sp)		// push the PC
 	move.w	C_SR(a0),-(sp)		// push the status register
@@ -515,10 +481,7 @@
 	tst.w	_coldfire_68k_emulation
 	bne.s	change_68k
 
-	// ColdFire FPU
-	fmove.l	C_FCTRL+8(a0),fpiar	// restore control registers
-	fmovem.d C_FREGS(a0),fp0-fp7	// and data registers
-	frestore C_FSTATE(a0)		// finally the internal state (including fpcr and fpsr)
+	bsr	restore_coldfire_fpu
 
 	move.l	C_PC(a0),-(sp)		// push the PC
 	move.w	C_SR(a0),-(sp)		// push the status register
@@ -579,18 +542,17 @@
 rcover2nc:
 	move.w	d0,-(sp)		// frame format identifier
 
+// restore the FPU state
+#ifdef __mcoldfire__
+	bsr	restore_coldfire_fpu
+#else
 // if running with a true coprocessor we need to restore the FPU state
 
 	tst.w	_fpu			// is there a true FPU in the system
 	beq.s	short6
 
 #ifndef M68000
-#ifdef	__mcoldfire__
-	moveq	#60,d1
-	cmp.w	_mcpu+2,d1		// on 68060 frame format is different
-#else
 	cmp.w	#60,_mcpu+2		// on 68060 frame format is different
-#endif
 	bne.s	no60_4
 	tst.b	C_FSTATE+2(a0)
 	beq.s	short5
@@ -599,17 +561,12 @@
 #endif
 	tst.b	C_FSTATE(a0)		// if NULL frame then the FPU is not in use
 	beq.s	short5			// skip programmer's model restore
-#ifdef	__mcoldfire__
-save5:	fmove.l	C_FCTRL(a0),fpcr		// restore control registers
-	fmove.l	C_FCTRL+4(a0),fpsr
-	fmove.l	C_FCTRL+8(a0),fpiar
-	fmovem.d C_FREGS(a0),fp0-fp7		// and data registers
-#else
 save5:	fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar	// restore control registers
 	fmovem.x C_FREGS(a0),fp0-fp7		// and data registers
-#endif
 short5:
 	frestore C_FSTATE(a0)			// finally the internal state
+#endif /* __mcoldfire__ */
+
 short6:
 	move.l	C_PC(a0),-(sp)		// push the PC
 	move.w	C_SR(a0),-(sp)		// push status register
@@ -620,3 +577,23 @@
 	jmp	_new_trace
 notrace2:
 	rte				// jump back to old context
+
+#ifdef	__mcoldfire__
+save_coldfire_fpu:
+	fsave	C_FSTATE(a0)		// save internal state frame (including fpcr and fpsr)
+	tst.b	C_FSTATE(a0)		// if NULL frame then the FPU is not in use
+	beq.s	save_coldfire_fpu_end	// skip programmer's model restore
+	fmovem.d fp0-fp7,C_FREGS(a0)	// save data registers
+	fmove.l	fpiar,C_FCTRL+8(a0)	// and control registers
+save_coldfire_fpu_end:
+	rts
+
+restore_coldfire_fpu:
+	tst.b	C_FSTATE(a0)		// if NULL frame then the FPU is not in use
+	beq.s	restore_coldfire_fpu_internal	// skip programmer's model restore
+	fmove.l	C_FCTRL+8(a0),fpiar	// restore control registers
+	fmovem.d C_FREGS(a0),fp0-fp7	// and data registers
+restore_coldfire_fpu_internal:
+	frestore C_FSTATE(a0)		// finally the internal state (including fpcr and fpsr)
+	rts
+#endif