18c2ecf20Sopenharmony_ci|
28c2ecf20Sopenharmony_ci|	skeleton.sa 3.2 4/26/91
38c2ecf20Sopenharmony_ci|
48c2ecf20Sopenharmony_ci|	This file contains code that is system dependent and will
58c2ecf20Sopenharmony_ci|	need to be modified to install the FPSP.
68c2ecf20Sopenharmony_ci|
78c2ecf20Sopenharmony_ci|	Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
88c2ecf20Sopenharmony_ci|	Put any target system specific handling that must be done immediately
98c2ecf20Sopenharmony_ci|	before the jump instruction.  If there no handling necessary, then
108c2ecf20Sopenharmony_ci|	the 'fpsp_xxxx' handler entry point should be placed in the exception
118c2ecf20Sopenharmony_ci|	table so that the 'jmp' can be eliminated. If the FPSP determines that the
128c2ecf20Sopenharmony_ci|	exception is one that must be reported then there will be a
138c2ecf20Sopenharmony_ci|	return from the package by a 'jmp real_xxxx'.  At that point
148c2ecf20Sopenharmony_ci|	the machine state will be identical to the state before
158c2ecf20Sopenharmony_ci|	the FPSP was entered.  In particular, whatever condition
168c2ecf20Sopenharmony_ci|	that caused the exception will still be pending when the FPSP
178c2ecf20Sopenharmony_ci|	package returns.  Thus, there will be system specific code
188c2ecf20Sopenharmony_ci|	to handle the exception.
198c2ecf20Sopenharmony_ci|
208c2ecf20Sopenharmony_ci|	If the exception was completely handled by the package, then
218c2ecf20Sopenharmony_ci|	the return will be via a 'jmp fpsp_done'.  Unless there is
228c2ecf20Sopenharmony_ci|	OS specific work to be done (such as handling a context switch or
238c2ecf20Sopenharmony_ci|	interrupt) the user program can be resumed via 'rte'.
248c2ecf20Sopenharmony_ci|
258c2ecf20Sopenharmony_ci|	In the following skeleton code, some typical 'real_xxxx' handling
268c2ecf20Sopenharmony_ci|	code is shown.  This code may need to be moved to an appropriate
278c2ecf20Sopenharmony_ci|	place in the target system, or rewritten.
288c2ecf20Sopenharmony_ci|
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
318c2ecf20Sopenharmony_ci|			All Rights Reserved
328c2ecf20Sopenharmony_ci|
338c2ecf20Sopenharmony_ci|       For details on the license for this file, please see the
348c2ecf20Sopenharmony_ci|       file, README, in this same directory.
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci|
378c2ecf20Sopenharmony_ci|	Modified for Linux-1.3.x by Jes Sorensen (jds@kom.auc.dk)
388c2ecf20Sopenharmony_ci|
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#include <linux/linkage.h>
418c2ecf20Sopenharmony_ci#include <asm/entry.h>
428c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h>
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci|SKELETON	idnt    2,1 | Motorola 040 Floating Point Software Package
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	|section 15
478c2ecf20Sopenharmony_ci|
488c2ecf20Sopenharmony_ci|	The following counters are used for standalone testing
498c2ecf20Sopenharmony_ci|
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	|section 8
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#include "fpsp.h"
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	|xref	b1238_fix
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci|
588c2ecf20Sopenharmony_ci|	Divide by Zero exception
598c2ecf20Sopenharmony_ci|
608c2ecf20Sopenharmony_ci|	All dz exceptions are 'real', hence no fpsp_dz entry point.
618c2ecf20Sopenharmony_ci|
628c2ecf20Sopenharmony_ci	.global	dz
638c2ecf20Sopenharmony_ci	.global	real_dz
648c2ecf20Sopenharmony_cidz:
658c2ecf20Sopenharmony_cireal_dz:
668c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
678c2ecf20Sopenharmony_ci	fsave		-(%sp)
688c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)
698c2ecf20Sopenharmony_ci	frestore	(%sp)+
708c2ecf20Sopenharmony_ci	unlk		%a6
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	SAVE_ALL_INT
738c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
748c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
758c2ecf20Sopenharmony_ci	bsrl	trap_c
768c2ecf20Sopenharmony_ci	addql	#4,%sp
778c2ecf20Sopenharmony_ci	bral	ret_from_exception
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci|
808c2ecf20Sopenharmony_ci|	Inexact exception
818c2ecf20Sopenharmony_ci|
828c2ecf20Sopenharmony_ci|	All inexact exceptions are real, but the 'real' handler
838c2ecf20Sopenharmony_ci|	will probably want to clear the pending exception.
848c2ecf20Sopenharmony_ci|	The provided code will clear the E3 exception (if pending),
858c2ecf20Sopenharmony_ci|	otherwise clear the E1 exception.  The frestore is not really
868c2ecf20Sopenharmony_ci|	necessary for E1 exceptions.
878c2ecf20Sopenharmony_ci|
888c2ecf20Sopenharmony_ci| Code following the 'inex' label is to handle bug #1232.  In this
898c2ecf20Sopenharmony_ci| bug, if an E1 snan, ovfl, or unfl occurred, and the process was
908c2ecf20Sopenharmony_ci| swapped out before taking the exception, the exception taken on
918c2ecf20Sopenharmony_ci| return was inex, rather than the correct exception.  The snan, ovfl,
928c2ecf20Sopenharmony_ci| and unfl exception to be taken must not have been enabled.  The
938c2ecf20Sopenharmony_ci| fix is to check for E1, and the existence of one of snan, ovfl,
948c2ecf20Sopenharmony_ci| or unfl bits set in the fpsr.  If any of these are set, branch
958c2ecf20Sopenharmony_ci| to the appropriate  handler for the exception in the fpsr.  Note
968c2ecf20Sopenharmony_ci| that this fix is only for d43b parts, and is skipped if the
978c2ecf20Sopenharmony_ci| version number is not $40.
988c2ecf20Sopenharmony_ci|
998c2ecf20Sopenharmony_ci|
1008c2ecf20Sopenharmony_ci	.global	real_inex
1018c2ecf20Sopenharmony_ci	.global	inex
1028c2ecf20Sopenharmony_ciinex:
1038c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
1048c2ecf20Sopenharmony_ci	fsave		-(%sp)
1058c2ecf20Sopenharmony_ci	cmpib		#VER_40,(%sp)		|test version number
1068c2ecf20Sopenharmony_ci	bnes		not_fmt40
1078c2ecf20Sopenharmony_ci	fmovel		%fpsr,-(%sp)
1088c2ecf20Sopenharmony_ci	btstb		#E1,E_BYTE(%a6)		|test for E1 set
1098c2ecf20Sopenharmony_ci	beqs		not_b1232
1108c2ecf20Sopenharmony_ci	btstb		#snan_bit,2(%sp) |test for snan
1118c2ecf20Sopenharmony_ci	beq		inex_ckofl
1128c2ecf20Sopenharmony_ci	addl		#4,%sp
1138c2ecf20Sopenharmony_ci	frestore	(%sp)+
1148c2ecf20Sopenharmony_ci	unlk		%a6
1158c2ecf20Sopenharmony_ci	bra		snan
1168c2ecf20Sopenharmony_ciinex_ckofl:
1178c2ecf20Sopenharmony_ci	btstb		#ovfl_bit,2(%sp) |test for ovfl
1188c2ecf20Sopenharmony_ci	beq		inex_ckufl
1198c2ecf20Sopenharmony_ci	addl		#4,%sp
1208c2ecf20Sopenharmony_ci	frestore	(%sp)+
1218c2ecf20Sopenharmony_ci	unlk		%a6
1228c2ecf20Sopenharmony_ci	bra		ovfl
1238c2ecf20Sopenharmony_ciinex_ckufl:
1248c2ecf20Sopenharmony_ci	btstb		#unfl_bit,2(%sp) |test for unfl
1258c2ecf20Sopenharmony_ci	beq		not_b1232
1268c2ecf20Sopenharmony_ci	addl		#4,%sp
1278c2ecf20Sopenharmony_ci	frestore	(%sp)+
1288c2ecf20Sopenharmony_ci	unlk		%a6
1298c2ecf20Sopenharmony_ci	bra		unfl
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci|
1328c2ecf20Sopenharmony_ci| We do not have the bug 1232 case.  Clean up the stack and call
1338c2ecf20Sopenharmony_ci| real_inex.
1348c2ecf20Sopenharmony_ci|
1358c2ecf20Sopenharmony_cinot_b1232:
1368c2ecf20Sopenharmony_ci	addl		#4,%sp
1378c2ecf20Sopenharmony_ci	frestore	(%sp)+
1388c2ecf20Sopenharmony_ci	unlk		%a6
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cireal_inex:
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
1438c2ecf20Sopenharmony_ci	fsave		-(%sp)
1448c2ecf20Sopenharmony_cinot_fmt40:
1458c2ecf20Sopenharmony_ci	bclrb		#E3,E_BYTE(%a6)		|clear and test E3 flag
1468c2ecf20Sopenharmony_ci	beqs		inex_cke1
1478c2ecf20Sopenharmony_ci|
1488c2ecf20Sopenharmony_ci| Clear dirty bit on dest resister in the frame before branching
1498c2ecf20Sopenharmony_ci| to b1238_fix.
1508c2ecf20Sopenharmony_ci|
1518c2ecf20Sopenharmony_ci	moveml		%d0/%d1,USER_DA(%a6)
1528c2ecf20Sopenharmony_ci	bfextu		CMDREG1B(%a6){#6:#3},%d0		|get dest reg no
1538c2ecf20Sopenharmony_ci	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
1548c2ecf20Sopenharmony_ci	bsrl		b1238_fix		|test for bug1238 case
1558c2ecf20Sopenharmony_ci	moveml		USER_DA(%a6),%d0/%d1
1568c2ecf20Sopenharmony_ci	bras		inex_done
1578c2ecf20Sopenharmony_ciinex_cke1:
1588c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)
1598c2ecf20Sopenharmony_ciinex_done:
1608c2ecf20Sopenharmony_ci	frestore	(%sp)+
1618c2ecf20Sopenharmony_ci	unlk		%a6
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1648c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
1658c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
1668c2ecf20Sopenharmony_ci	bsrl	trap_c
1678c2ecf20Sopenharmony_ci	addql	#4,%sp
1688c2ecf20Sopenharmony_ci	bral	ret_from_exception
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci|
1718c2ecf20Sopenharmony_ci|	Overflow exception
1728c2ecf20Sopenharmony_ci|
1738c2ecf20Sopenharmony_ci	|xref	fpsp_ovfl
1748c2ecf20Sopenharmony_ci	.global	real_ovfl
1758c2ecf20Sopenharmony_ci	.global	ovfl
1768c2ecf20Sopenharmony_ciovfl:
1778c2ecf20Sopenharmony_ci	jmp	fpsp_ovfl
1788c2ecf20Sopenharmony_cireal_ovfl:
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
1818c2ecf20Sopenharmony_ci	fsave		-(%sp)
1828c2ecf20Sopenharmony_ci	bclrb		#E3,E_BYTE(%a6)		|clear and test E3 flag
1838c2ecf20Sopenharmony_ci	bnes		ovfl_done
1848c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)
1858c2ecf20Sopenharmony_ciovfl_done:
1868c2ecf20Sopenharmony_ci	frestore	(%sp)+
1878c2ecf20Sopenharmony_ci	unlk		%a6
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1908c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
1918c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
1928c2ecf20Sopenharmony_ci	bsrl	trap_c
1938c2ecf20Sopenharmony_ci	addql	#4,%sp
1948c2ecf20Sopenharmony_ci	bral	ret_from_exception
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci|
1978c2ecf20Sopenharmony_ci|	Underflow exception
1988c2ecf20Sopenharmony_ci|
1998c2ecf20Sopenharmony_ci	|xref	fpsp_unfl
2008c2ecf20Sopenharmony_ci	.global	real_unfl
2018c2ecf20Sopenharmony_ci	.global	unfl
2028c2ecf20Sopenharmony_ciunfl:
2038c2ecf20Sopenharmony_ci	jmp	fpsp_unfl
2048c2ecf20Sopenharmony_cireal_unfl:
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
2078c2ecf20Sopenharmony_ci	fsave		-(%sp)
2088c2ecf20Sopenharmony_ci	bclrb		#E3,E_BYTE(%a6)		|clear and test E3 flag
2098c2ecf20Sopenharmony_ci	bnes		unfl_done
2108c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)
2118c2ecf20Sopenharmony_ciunfl_done:
2128c2ecf20Sopenharmony_ci	frestore	(%sp)+
2138c2ecf20Sopenharmony_ci	unlk		%a6
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2168c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
2178c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
2188c2ecf20Sopenharmony_ci	bsrl	trap_c
2198c2ecf20Sopenharmony_ci	addql	#4,%sp
2208c2ecf20Sopenharmony_ci	bral	ret_from_exception
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci|
2238c2ecf20Sopenharmony_ci|	Signalling NAN exception
2248c2ecf20Sopenharmony_ci|
2258c2ecf20Sopenharmony_ci	|xref	fpsp_snan
2268c2ecf20Sopenharmony_ci	.global	real_snan
2278c2ecf20Sopenharmony_ci	.global	snan
2288c2ecf20Sopenharmony_cisnan:
2298c2ecf20Sopenharmony_ci	jmp	fpsp_snan
2308c2ecf20Sopenharmony_cireal_snan:
2318c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
2328c2ecf20Sopenharmony_ci	fsave		-(%sp)
2338c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)	|snan is always an E1 exception
2348c2ecf20Sopenharmony_ci	frestore	(%sp)+
2358c2ecf20Sopenharmony_ci	unlk		%a6
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2388c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
2398c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
2408c2ecf20Sopenharmony_ci	bsrl	trap_c
2418c2ecf20Sopenharmony_ci	addql	#4,%sp
2428c2ecf20Sopenharmony_ci	bral	ret_from_exception
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci|
2458c2ecf20Sopenharmony_ci|	Operand Error exception
2468c2ecf20Sopenharmony_ci|
2478c2ecf20Sopenharmony_ci	|xref	fpsp_operr
2488c2ecf20Sopenharmony_ci	.global	real_operr
2498c2ecf20Sopenharmony_ci	.global	operr
2508c2ecf20Sopenharmony_cioperr:
2518c2ecf20Sopenharmony_ci	jmp	fpsp_operr
2528c2ecf20Sopenharmony_cireal_operr:
2538c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
2548c2ecf20Sopenharmony_ci	fsave		-(%sp)
2558c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)	|operr is always an E1 exception
2568c2ecf20Sopenharmony_ci	frestore	(%sp)+
2578c2ecf20Sopenharmony_ci	unlk		%a6
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2608c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
2618c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
2628c2ecf20Sopenharmony_ci	bsrl	trap_c
2638c2ecf20Sopenharmony_ci	addql	#4,%sp
2648c2ecf20Sopenharmony_ci	bral	ret_from_exception
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci|
2688c2ecf20Sopenharmony_ci|	BSUN exception
2698c2ecf20Sopenharmony_ci|
2708c2ecf20Sopenharmony_ci|	This sample handler simply clears the nan bit in the FPSR.
2718c2ecf20Sopenharmony_ci|
2728c2ecf20Sopenharmony_ci	|xref	fpsp_bsun
2738c2ecf20Sopenharmony_ci	.global	real_bsun
2748c2ecf20Sopenharmony_ci	.global	bsun
2758c2ecf20Sopenharmony_cibsun:
2768c2ecf20Sopenharmony_ci	jmp	fpsp_bsun
2778c2ecf20Sopenharmony_cireal_bsun:
2788c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
2798c2ecf20Sopenharmony_ci	fsave		-(%sp)
2808c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)	|bsun is always an E1 exception
2818c2ecf20Sopenharmony_ci	fmovel		%FPSR,-(%sp)
2828c2ecf20Sopenharmony_ci	bclrb		#nan_bit,(%sp)
2838c2ecf20Sopenharmony_ci	fmovel		(%sp)+,%FPSR
2848c2ecf20Sopenharmony_ci	frestore	(%sp)+
2858c2ecf20Sopenharmony_ci	unlk		%a6
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2888c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
2898c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
2908c2ecf20Sopenharmony_ci	bsrl	trap_c
2918c2ecf20Sopenharmony_ci	addql	#4,%sp
2928c2ecf20Sopenharmony_ci	bral	ret_from_exception
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci|
2958c2ecf20Sopenharmony_ci|	F-line exception
2968c2ecf20Sopenharmony_ci|
2978c2ecf20Sopenharmony_ci|	A 'real' F-line exception is one that the FPSP isn't supposed to
2988c2ecf20Sopenharmony_ci|	handle. E.g. an instruction with a co-processor ID that is not 1.
2998c2ecf20Sopenharmony_ci|
3008c2ecf20Sopenharmony_ci|
3018c2ecf20Sopenharmony_ci	|xref	fpsp_fline
3028c2ecf20Sopenharmony_ci	.global	real_fline
3038c2ecf20Sopenharmony_ci	.global	fline
3048c2ecf20Sopenharmony_cifline:
3058c2ecf20Sopenharmony_ci	jmp	fpsp_fline
3068c2ecf20Sopenharmony_cireal_fline:
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	SAVE_ALL_INT
3098c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
3108c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
3118c2ecf20Sopenharmony_ci	bsrl	trap_c
3128c2ecf20Sopenharmony_ci	addql	#4,%sp
3138c2ecf20Sopenharmony_ci	bral	ret_from_exception
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci|
3168c2ecf20Sopenharmony_ci|	Unsupported data type exception
3178c2ecf20Sopenharmony_ci|
3188c2ecf20Sopenharmony_ci	|xref	fpsp_unsupp
3198c2ecf20Sopenharmony_ci	.global	real_unsupp
3208c2ecf20Sopenharmony_ci	.global	unsupp
3218c2ecf20Sopenharmony_ciunsupp:
3228c2ecf20Sopenharmony_ci	jmp	fpsp_unsupp
3238c2ecf20Sopenharmony_cireal_unsupp:
3248c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
3258c2ecf20Sopenharmony_ci	fsave		-(%sp)
3268c2ecf20Sopenharmony_ci	bclrb		#E1,E_BYTE(%a6)	|unsupp is always an E1 exception
3278c2ecf20Sopenharmony_ci	frestore	(%sp)+
3288c2ecf20Sopenharmony_ci	unlk		%a6
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	SAVE_ALL_INT
3318c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
3328c2ecf20Sopenharmony_ci	movel	%sp,%sp@-		| stack frame pointer argument
3338c2ecf20Sopenharmony_ci	bsrl	trap_c
3348c2ecf20Sopenharmony_ci	addql	#4,%sp
3358c2ecf20Sopenharmony_ci	bral	ret_from_exception
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci|
3388c2ecf20Sopenharmony_ci|	Trace exception
3398c2ecf20Sopenharmony_ci|
3408c2ecf20Sopenharmony_ci	.global	real_trace
3418c2ecf20Sopenharmony_cireal_trace:
3428c2ecf20Sopenharmony_ci	|
3438c2ecf20Sopenharmony_ci	bral	trap
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci|
3468c2ecf20Sopenharmony_ci|	fpsp_fmt_error --- exit point for frame format error
3478c2ecf20Sopenharmony_ci|
3488c2ecf20Sopenharmony_ci|	The fpu stack frame does not match the frames existing
3498c2ecf20Sopenharmony_ci|	or planned at the time of this writing.  The fpsp is
3508c2ecf20Sopenharmony_ci|	unable to handle frame sizes not in the following
3518c2ecf20Sopenharmony_ci|	version:size pairs:
3528c2ecf20Sopenharmony_ci|
3538c2ecf20Sopenharmony_ci|	{4060, 4160} - busy frame
3548c2ecf20Sopenharmony_ci|	{4028, 4130} - unimp frame
3558c2ecf20Sopenharmony_ci|	{4000, 4100} - idle frame
3568c2ecf20Sopenharmony_ci|
3578c2ecf20Sopenharmony_ci|	This entry point simply holds an f-line illegal value.
3588c2ecf20Sopenharmony_ci|	Replace this with a call to your kernel panic code or
3598c2ecf20Sopenharmony_ci|	code to handle future revisions of the fpu.
3608c2ecf20Sopenharmony_ci|
3618c2ecf20Sopenharmony_ci	.global	fpsp_fmt_error
3628c2ecf20Sopenharmony_cifpsp_fmt_error:
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	.long	0xf27f0000	|f-line illegal
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci|
3678c2ecf20Sopenharmony_ci|	fpsp_done --- FPSP exit point
3688c2ecf20Sopenharmony_ci|
3698c2ecf20Sopenharmony_ci|	The exception has been handled by the package and we are ready
3708c2ecf20Sopenharmony_ci|	to return to user mode, but there may be OS specific code
3718c2ecf20Sopenharmony_ci|	to execute before we do.  If there is, do it now.
3728c2ecf20Sopenharmony_ci|
3738c2ecf20Sopenharmony_ci|
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	.global	fpsp_done
3768c2ecf20Sopenharmony_cifpsp_done:
3778c2ecf20Sopenharmony_ci	btst	#0x5,%sp@		| supervisor bit set in saved SR?
3788c2ecf20Sopenharmony_ci	beq	.Lnotkern
3798c2ecf20Sopenharmony_ci	rte
3808c2ecf20Sopenharmony_ci.Lnotkern:
3818c2ecf20Sopenharmony_ci	SAVE_ALL_INT
3828c2ecf20Sopenharmony_ci	GET_CURRENT(%d0)
3838c2ecf20Sopenharmony_ci	| deliver signals, reschedule etc..
3848c2ecf20Sopenharmony_ci	jra	ret_from_exception
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci|
3878c2ecf20Sopenharmony_ci|	mem_write --- write to user or supervisor address space
3888c2ecf20Sopenharmony_ci|
3898c2ecf20Sopenharmony_ci| Writes to memory while in supervisor mode.  copyout accomplishes
3908c2ecf20Sopenharmony_ci| this via a 'moves' instruction.  copyout is a UNIX SVR3 (and later) function.
3918c2ecf20Sopenharmony_ci| If you don't have copyout, use the local copy of the function below.
3928c2ecf20Sopenharmony_ci|
3938c2ecf20Sopenharmony_ci|	a0 - supervisor source address
3948c2ecf20Sopenharmony_ci|	a1 - user destination address
3958c2ecf20Sopenharmony_ci|	d0 - number of bytes to write (maximum count is 12)
3968c2ecf20Sopenharmony_ci|
3978c2ecf20Sopenharmony_ci| The supervisor source address is guaranteed to point into the supervisor
3988c2ecf20Sopenharmony_ci| stack.  The result is that a UNIX
3998c2ecf20Sopenharmony_ci| process is allowed to sleep as a consequence of a page fault during
4008c2ecf20Sopenharmony_ci| copyout.  The probability of a page fault is exceedingly small because
4018c2ecf20Sopenharmony_ci| the 68040 always reads the destination address and thus the page
4028c2ecf20Sopenharmony_ci| faults should have already been handled.
4038c2ecf20Sopenharmony_ci|
4048c2ecf20Sopenharmony_ci| If the EXC_SR shows that the exception was from supervisor space,
4058c2ecf20Sopenharmony_ci| then just do a dumb (and slow) memory move.  In a UNIX environment
4068c2ecf20Sopenharmony_ci| there shouldn't be any supervisor mode floating point exceptions.
4078c2ecf20Sopenharmony_ci|
4088c2ecf20Sopenharmony_ci	.global	mem_write
4098c2ecf20Sopenharmony_cimem_write:
4108c2ecf20Sopenharmony_ci	btstb	#5,EXC_SR(%a6)	|check for supervisor state
4118c2ecf20Sopenharmony_ci	beqs	user_write
4128c2ecf20Sopenharmony_cisuper_write:
4138c2ecf20Sopenharmony_ci	moveb	(%a0)+,(%a1)+
4148c2ecf20Sopenharmony_ci	subql	#1,%d0
4158c2ecf20Sopenharmony_ci	bnes	super_write
4168c2ecf20Sopenharmony_ci	rts
4178c2ecf20Sopenharmony_ciuser_write:
4188c2ecf20Sopenharmony_ci	movel	%d1,-(%sp)	|preserve d1 just in case
4198c2ecf20Sopenharmony_ci	movel	%d0,-(%sp)
4208c2ecf20Sopenharmony_ci	movel	%a1,-(%sp)
4218c2ecf20Sopenharmony_ci	movel	%a0,-(%sp)
4228c2ecf20Sopenharmony_ci	jsr		copyout
4238c2ecf20Sopenharmony_ci	addw	#12,%sp
4248c2ecf20Sopenharmony_ci	movel	(%sp)+,%d1
4258c2ecf20Sopenharmony_ci	rts
4268c2ecf20Sopenharmony_ci|
4278c2ecf20Sopenharmony_ci|	mem_read --- read from user or supervisor address space
4288c2ecf20Sopenharmony_ci|
4298c2ecf20Sopenharmony_ci| Reads from memory while in supervisor mode.  copyin accomplishes
4308c2ecf20Sopenharmony_ci| this via a 'moves' instruction.  copyin is a UNIX SVR3 (and later) function.
4318c2ecf20Sopenharmony_ci| If you don't have copyin, use the local copy of the function below.
4328c2ecf20Sopenharmony_ci|
4338c2ecf20Sopenharmony_ci| The FPSP calls mem_read to read the original F-line instruction in order
4348c2ecf20Sopenharmony_ci| to extract the data register number when the 'Dn' addressing mode is
4358c2ecf20Sopenharmony_ci| used.
4368c2ecf20Sopenharmony_ci|
4378c2ecf20Sopenharmony_ci|Input:
4388c2ecf20Sopenharmony_ci|	a0 - user source address
4398c2ecf20Sopenharmony_ci|	a1 - supervisor destination address
4408c2ecf20Sopenharmony_ci|	d0 - number of bytes to read (maximum count is 12)
4418c2ecf20Sopenharmony_ci|
4428c2ecf20Sopenharmony_ci| Like mem_write, mem_read always reads with a supervisor
4438c2ecf20Sopenharmony_ci| destination address on the supervisor stack.  Also like mem_write,
4448c2ecf20Sopenharmony_ci| the EXC_SR is checked and a simple memory copy is done if reading
4458c2ecf20Sopenharmony_ci| from supervisor space is indicated.
4468c2ecf20Sopenharmony_ci|
4478c2ecf20Sopenharmony_ci	.global	mem_read
4488c2ecf20Sopenharmony_cimem_read:
4498c2ecf20Sopenharmony_ci	btstb	#5,EXC_SR(%a6)	|check for supervisor state
4508c2ecf20Sopenharmony_ci	beqs	user_read
4518c2ecf20Sopenharmony_cisuper_read:
4528c2ecf20Sopenharmony_ci	moveb	(%a0)+,(%a1)+
4538c2ecf20Sopenharmony_ci	subql	#1,%d0
4548c2ecf20Sopenharmony_ci	bnes	super_read
4558c2ecf20Sopenharmony_ci	rts
4568c2ecf20Sopenharmony_ciuser_read:
4578c2ecf20Sopenharmony_ci	movel	%d1,-(%sp)	|preserve d1 just in case
4588c2ecf20Sopenharmony_ci	movel	%d0,-(%sp)
4598c2ecf20Sopenharmony_ci	movel	%a1,-(%sp)
4608c2ecf20Sopenharmony_ci	movel	%a0,-(%sp)
4618c2ecf20Sopenharmony_ci	jsr	copyin
4628c2ecf20Sopenharmony_ci	addw	#12,%sp
4638c2ecf20Sopenharmony_ci	movel	(%sp)+,%d1
4648c2ecf20Sopenharmony_ci	rts
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci|
4678c2ecf20Sopenharmony_ci| Use these routines if your kernel doesn't have copyout/copyin equivalents.
4688c2ecf20Sopenharmony_ci| Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
4698c2ecf20Sopenharmony_ci| and copyin overwrites SFC.
4708c2ecf20Sopenharmony_ci|
4718c2ecf20Sopenharmony_cicopyout:
4728c2ecf20Sopenharmony_ci	movel	4(%sp),%a0	| source
4738c2ecf20Sopenharmony_ci	movel	8(%sp),%a1	| destination
4748c2ecf20Sopenharmony_ci	movel	12(%sp),%d0	| count
4758c2ecf20Sopenharmony_ci	subl	#1,%d0		| dec count by 1 for dbra
4768c2ecf20Sopenharmony_ci	movel	#1,%d1
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci|	DFC is already set
4798c2ecf20Sopenharmony_ci|	movec	%d1,%DFC		| set dfc for user data space
4808c2ecf20Sopenharmony_cimoreout:
4818c2ecf20Sopenharmony_ci	moveb	(%a0)+,%d1	| fetch supervisor byte
4828c2ecf20Sopenharmony_ciout_ea:
4838c2ecf20Sopenharmony_ci	movesb	%d1,(%a1)+	| write user byte
4848c2ecf20Sopenharmony_ci	dbf	%d0,moreout
4858c2ecf20Sopenharmony_ci	rts
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_cicopyin:
4888c2ecf20Sopenharmony_ci	movel	4(%sp),%a0	| source
4898c2ecf20Sopenharmony_ci	movel	8(%sp),%a1	| destination
4908c2ecf20Sopenharmony_ci	movel	12(%sp),%d0	| count
4918c2ecf20Sopenharmony_ci	subl	#1,%d0		| dec count by 1 for dbra
4928c2ecf20Sopenharmony_ci	movel	#1,%d1
4938c2ecf20Sopenharmony_ci|	SFC is already set
4948c2ecf20Sopenharmony_ci|	movec	%d1,%SFC		| set sfc for user space
4958c2ecf20Sopenharmony_cimorein:
4968c2ecf20Sopenharmony_ciin_ea:
4978c2ecf20Sopenharmony_ci	movesb	(%a0)+,%d1	| fetch user byte
4988c2ecf20Sopenharmony_ci	moveb	%d1,(%a1)+	| write supervisor byte
4998c2ecf20Sopenharmony_ci	dbf	%d0,morein
5008c2ecf20Sopenharmony_ci	rts
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	.section .fixup,"ax"
5038c2ecf20Sopenharmony_ci	.even
5048c2ecf20Sopenharmony_ci1:
5058c2ecf20Sopenharmony_ci	jbra	fpsp040_die
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	.section __ex_table,"a"
5088c2ecf20Sopenharmony_ci	.align	4
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	.long	in_ea,1b
5118c2ecf20Sopenharmony_ci	.long	out_ea,1b
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	|end
514