Home | History | Annotate | Line # | Download | only in fpsp
netbsd.sa revision 1.1
      1 *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      2 *	M68000 Hi-Performance Microprocessor Division
      3 *	M68040 Software Package 
      4 *
      5 *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      6 *	All rights reserved.
      7 *
      8 *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
      9 *	To the maximum extent permitted by applicable law,
     10 *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     11 *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     12 *	PARTICULAR PURPOSE and any warranty against infringement with
     13 *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     14 *	and any accompanying written materials. 
     15 *
     16 *	To the maximum extent permitted by applicable law,
     17 *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     18 *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     19 *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     20 *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     21 *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     22 *	and support of the SOFTWARE.  
     23 *
     24 *	You are hereby granted a copyright license to use, modify, and
     25 *	distribute the SOFTWARE so long as this entire notice is retained
     26 *	without alteration in any modified and/or redistributed versions,
     27 *	and that such modified versions are clearly identified as such.
     28 *	No licenses are granted by implication, estoppel or otherwise
     29 *	under any patents or trademarks of Motorola, Inc.
     30 
     31 *
     32 *	skeleton.sa 3.2 4/26/91
     33 *
     34 *	This file contains code that is system dependent and will
     35 *	need to be modified to install the FPSP.
     36 *
     37 *	Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
     38 *	Put any target system specific handling that must be done immediately
     39 *	before the jump instruction.  If there no handling necessary, then
     40 *	the 'fpsp_xxxx' handler entry point should be placed in the exception
     41 *	table so that the 'jmp' can be eliminated. If the FPSP determines that the
     42 *	exception is one that must be reported then there will be a
     43 *	return from the package by a 'jmp real_xxxx'.  At that point
     44 *	the machine state will be identical to the state before
     45 *	the FPSP was entered.  In particular, whatever condition
     46 *	that caused the exception will still be pending when the FPSP
     47 *	package returns.  Thus, there will be system specific code
     48 *	to handle the exception.
     49 *
     50 *	If the exception was completely handled by the package, then
     51 *	the return will be via a 'jmp fpsp_done'.  Unless there is 
     52 *	OS specific work to be done (such as handling a context switch or
     53 *	interrupt) the user program can be resumed via 'rte'.
     54 *
     55 *	In the following skeleton code, some typical 'real_xxxx' handling
     56 *	code is shown.  This code may need to be moved to an appropriate
     57 *	place in the target system, or rewritten.
     58 *	
     59 
     60 SKELETON	IDNT    2,1 Motorola 040 Floating Point Software Package
     61 
     62 	section 15
     63 *
     64 *	The following counters are used for standalone testing
     65 *
     66 
     67 	section 8
     68 
     69 	include	fpsp.h
     70 
     71 	xref	b1238_fix
     72 	xref	_mmutype
     73 
     74 *
     75 *	Divide by Zero exception
     76 *
     77 *	All dz exceptions are 'real', hence no fpsp_dz entry point.
     78 *
     79 	xdef	dz
     80 	xdef	real_dz
     81 dz:
     82 	cmp.l		#-2,_mmutype
     83 	bne.l		_fpfault
     84 real_dz:
     85 	link		a6,#-LOCAL_SIZE
     86 	fsave		-(sp)
     87 	bclr.b		#E1,E_BYTE(a6)
     88 	frestore	(sp)+
     89 	unlk		a6
     90 	jmp		_fpfault
     91 
     92 *
     93 *	Inexact exception
     94 *
     95 *	All inexact exceptions are real, but the 'real' handler
     96 *	will probably want to clear the pending exception.
     97 *	The provided code will clear the E3 exception (if pending), 
     98 *	otherwise clear the E1 exception.  The frestore is not really
     99 *	necessary for E1 exceptions.
    100 *
    101 * Code following the 'inex' label is to handle bug #1232.  In this
    102 * bug, if an E1 snan, ovfl, or unfl occured, and the process was
    103 * swapped out before taking the exception, the exception taken on
    104 * return was inex, rather than the correct exception.  The snan, ovfl,
    105 * and unfl exception to be taken must not have been enabled.  The
    106 * fix is to check for E1, and the existence of one of snan, ovfl,
    107 * or unfl bits set in the fpsr.  If any of these are set, branch
    108 * to the appropriate  handler for the exception in the fpsr.  Note
    109 * that this fix is only for d43b parts, and is skipped if the
    110 * version number is not $40.
    111 * 
    112 *
    113 	xdef	real_inex
    114 	xdef	inex
    115 inex:
    116 	cmp.l		#-2,_mmutype
    117 	bne.l		_fpfault
    118 	link		a6,#-LOCAL_SIZE
    119 	fsave		-(sp)
    120 	cmpi.b		#VER_40,(sp)		;test version number
    121 	bne.b		not_fmt40
    122 	fmove.l		fpsr,-(sp)
    123 	btst.b		#E1,E_BYTE(a6)		;test for E1 set
    124 	beq.b		not_b1232
    125 	btst.b		#snan_bit,2(sp) ;test for snan
    126 	beq		inex_ckofl
    127 	addq.l		#4,sp
    128 	frestore	(sp)+
    129 	unlk		a6
    130 	bra		snan
    131 inex_ckofl:
    132 	btst.b		#ovfl_bit,2(sp) ;test for ovfl
    133 	beq		inex_ckufl 
    134 	addq.l		#4,sp
    135 	frestore	(sp)+
    136 	unlk		a6
    137 	bra		ovfl
    138 inex_ckufl:
    139 	btst.b		#unfl_bit,2(sp) ;test for unfl
    140 	beq		not_b1232
    141 	addq.l		#4,sp
    142 	frestore	(sp)+
    143 	unlk		a6
    144 	bra		unfl
    145 
    146 *
    147 * We do not have the bug 1232 case.  Clean up the stack and call
    148 * real_inex.
    149 *
    150 not_b1232:
    151 	addq.l		#4,sp
    152 	frestore	(sp)+
    153 	unlk		a6
    154 
    155 real_inex:
    156 	link		a6,#-LOCAL_SIZE
    157 	fsave		-(sp)
    158 not_fmt40:
    159 	bclr.b		#E3,E_BYTE(a6)		;clear and test E3 flag
    160 	beq.b		inex_cke1
    161 *
    162 * Clear dirty bit on dest resister in the frame before branching
    163 * to b1238_fix.
    164 *
    165 	movem.l		d0/d1,USER_DA(a6)
    166 	bfextu		CMDREG1B(a6){6:3},d0		;get dest reg no
    167 	bclr.b		d0,FPR_DIRTY_BITS(a6)	;clr dest dirty bit
    168 	bsr.l		b1238_fix		;test for bug1238 case
    169 	movem.l		USER_DA(a6),d0/d1
    170 	bra.b		inex_done
    171 inex_cke1:
    172 	bclr.b		#E1,E_BYTE(a6)
    173 inex_done:
    174 	frestore	(sp)+
    175 	unlk		a6
    176 	jmp		_fpfault
    177 	
    178 *
    179 *	Overflow exception
    180 *
    181 	xref	fpsp_ovfl
    182 	xdef	real_ovfl
    183 	xdef	ovfl
    184 ovfl:
    185 	cmp.l		#-2,_mmutype
    186 	beq.l		fpsp_ovfl
    187 	jmp		_fpfault
    188 real_ovfl:
    189 	link		a6,#-LOCAL_SIZE
    190 	fsave		-(sp)
    191 	bclr.b		#E3,E_BYTE(a6)		;clear and test E3 flag
    192 	bne.b		ovfl_done
    193 	bclr.b		#E1,E_BYTE(a6)
    194 ovfl_done:
    195 	frestore	(sp)+
    196 	unlk		a6
    197 	jmp		_fpfault
    198 	
    199 *
    200 *	Underflow exception
    201 *
    202 	xref	fpsp_unfl
    203 	xdef	real_unfl
    204 	xdef	unfl
    205 unfl:
    206 	cmp.l		#-2,_mmutype
    207 	beq.l		fpsp_unfl
    208 	jmp		_fpfault
    209 real_unfl:
    210 	link		a6,#-LOCAL_SIZE
    211 	fsave		-(sp)
    212 	bclr.b		#E3,E_BYTE(a6)		;clear and test E3 flag
    213 	bne.b		unfl_done
    214 	bclr.b		#E1,E_BYTE(a6)
    215 unfl_done:
    216 	frestore	(sp)+
    217 	unlk		a6
    218 	jmp		_fpfault
    219 	
    220 *
    221 *	Signalling NAN exception
    222 *
    223 	xref	fpsp_snan
    224 	xdef	real_snan
    225 	xdef	snan
    226 snan:
    227 	cmp.l		#-2,_mmutype
    228 	beq.l		fpsp_snan
    229 	jmp		_fpfault
    230 real_snan:
    231 	link		a6,#-LOCAL_SIZE
    232 	fsave		-(sp)
    233 	bclr.b		#E1,E_BYTE(a6)	;snan is always an E1 exception
    234 	frestore	(sp)+
    235 	unlk		a6
    236 	jmp		_fpfault
    237 	
    238 *
    239 *	Operand Error exception
    240 *
    241 	xref	fpsp_operr
    242 	xdef	real_operr
    243 	xdef	operr
    244 operr:
    245 	cmp.l		#-2,_mmutype
    246 	beq.l		fpsp_operr
    247 	jmp		_fpfault
    248 real_operr:
    249 	link		a6,#-LOCAL_SIZE
    250 	fsave		-(sp)
    251 	bclr.b		#E1,E_BYTE(a6)	;operr is always an E1 exception
    252 	frestore	(sp)+
    253 	unlk		a6
    254 	jmp		_fpfault
    255 	
    256 *
    257 *	BSUN exception
    258 *
    259 *	This sample handler simply clears the nan bit in the FPSR.
    260 *
    261 	xref	fpsp_bsun
    262 	xdef	real_bsun
    263 	xdef	bsun
    264 bsun:
    265 	cmp.l		#-2,_mmutype
    266 	beq.l		fpsp_bsun
    267 	jmp		_fpfault
    268 real_bsun:
    269 	link		a6,#-LOCAL_SIZE
    270 	fsave		-(sp)
    271 	bclr.b		#E1,E_BYTE(a6)	;bsun is always an E1 exception
    272 	fmove.l		FPSR,-(sp)
    273 	bclr.b		#nan_bit,(sp)
    274 	fmove.l		(sp)+,FPSR
    275 	frestore	(sp)+
    276 	unlk		a6
    277 	jmp		_fpfault
    278 
    279 *
    280 *	F-line exception
    281 *
    282 *	A 'real' F-line exception is one that the FPSP isn't supposed to 
    283 *	handle. E.g. an instruction with a co-processor ID that is not 1.
    284 *
    285 *
    286 	xref	fpsp_fline
    287 	xdef	real_fline
    288 	xdef	fline
    289 fline:
    290 	cmp.l		#-2,_mmutype
    291 	beq.l		fpsp_fline
    292 	jmp		_fpfault
    293 real_fline:
    294 	jmp		_fpfault
    295 
    296 *
    297 *	Unsupported data type exception
    298 *
    299 	xref	fpsp_unsupp
    300 	xdef	real_unsupp
    301 	xdef	unsupp
    302 unsupp:
    303 	cmp.l		#-2,_mmutype
    304 	beq.l		fpsp_unsupp
    305 	jmp		_fpfault
    306 real_unsupp:
    307 	link		a6,#-LOCAL_SIZE
    308 	fsave		-(sp)
    309 	bclr.b		#E1,E_BYTE(a6)	;unsupp is always an E1 exception
    310 	frestore	(sp)+
    311 	unlk		a6
    312 	jmp		_fpfault
    313 
    314 *
    315 *	Trace exception
    316 *
    317 	xdef	real_trace
    318 real_trace:
    319 	rte
    320 
    321 *
    322 *	fpsp_fmt_error --- exit point for frame format error
    323 *
    324 *	The fpu stack frame does not match the frames existing
    325 *	or planned at the time of this writing.  The fpsp is
    326 *	unable to handle frame sizes not in the following
    327 *	version:size pairs:
    328 *
    329 *	{4060, 4160} - busy frame
    330 *	{4028, 4130} - unimp frame
    331 *	{4000, 4100} - idle frame
    332 *
    333 *	This entry point simply holds an f-line illegal value.  
    334 *	Replace this with a call to your kernel panic code or
    335 *	code to handle future revisions of the fpu.
    336 *
    337 	xdef	fpsp_fmt_error
    338 fpsp_fmt_error:
    339 	pea		1f
    340 	jsr		_panic
    341 	dc.l		$f27f0000	;f-line illegal
    342 1:
    343 	.asciz		"bad floating point stack frame"
    344 	.even
    345 
    346 *
    347 *	fpsp_done --- FPSP exit point
    348 *
    349 *	The exception has been handled by the package and we are ready
    350 *	to return to user mode, but there may be OS specific code
    351 *	to execute before we do.  If there is, do it now.
    352 *
    353 *
    354 	xref	rei
    355 	xdef	fpsp_done
    356 fpsp_done:
    357 	jmp		rei
    358 
    359 *
    360 *	mem_write --- write to user or supervisor address space
    361 *
    362 * Writes to memory while in supervisor mode.  copyout accomplishes
    363 * this via a 'moves' instruction.  copyout is a UNIX SVR3 (and later) function.
    364 * If you don't have copyout, use the local copy of the function below.
    365 *
    366 *	a0 - supervisor source address
    367 *	a1 - user destination address
    368 *	d0 - number of bytes to write (maximum count is 12)
    369 *
    370 * The supervisor source address is guaranteed to point into the supervisor
    371 * stack.  The result is that a UNIX
    372 * process is allowed to sleep as a consequence of a page fault during
    373 * copyout.  The probability of a page fault is exceedingly small because
    374 * the 68040 always reads the destination address and thus the page
    375 * faults should have already been handled.
    376 *
    377 * If the EXC_SR shows that the exception was from supervisor space,
    378 * then just do a dumb (and slow) memory move.  In a UNIX environment
    379 * there shouldn't be any supervisor mode floating point exceptions.
    380 *
    381 	xdef	mem_write
    382 mem_write:
    383 	btst.b	#5,EXC_SR(a6)	;check for supervisor state
    384 	beq.b	user_write
    385 super_write:
    386 	move.b	(a0)+,(a1)+
    387 	subq.l	#1,d0
    388 	bne.b	super_write
    389 	rts
    390 user_write:
    391 	move.l	d1,-(sp)	;preserve d1 just in case
    392 	move.l	d0,-(sp)
    393 	move.l	a1,-(sp)
    394 	move.l	a0,-(sp)
    395 	jsr	_copyout
    396 	add.l	#12,sp
    397 	move.l	(sp)+,d1
    398 	rts
    399 
    400 *
    401 *	mem_read --- read from user or supervisor address space
    402 *
    403 * Reads from memory while in supervisor mode.  copyin accomplishes
    404 * this via a 'moves' instruction.  copyin is a UNIX SVR3 (and later) function.
    405 * If you don't have copyin, use the local copy of the function below.
    406 *
    407 * The FPSP calls mem_read to read the original F-line instruction in order
    408 * to extract the data register number when the 'Dn' addressing mode is
    409 * used.
    410 *
    411 *Input:
    412 *	a0 - user source address
    413 *	a1 - supervisor destination address
    414 *	d0 - number of bytes to read (maximum count is 12)
    415 *
    416 * Like mem_write, mem_read always reads with a supervisor 
    417 * destination address on the supervisor stack.  Also like mem_write,
    418 * the EXC_SR is checked and a simple memory copy is done if reading
    419 * from supervisor space is indicated.
    420 *
    421 	xdef	mem_read
    422 mem_read:
    423 	btst.b	#5,EXC_SR(a6)	;check for supervisor state
    424 	beq.b	user_read
    425 super_read:
    426 	move.b	(a0)+,(a1)+
    427 	subq.l	#1,d0
    428 	bne.b	super_read
    429 	rts
    430 user_read:
    431 	move.l	d1,-(sp)	;preserve d1 just in case
    432 	move.l	d0,-(sp)
    433 	move.l	a1,-(sp)
    434 	move.l	a0,-(sp)
    435 	jsr	_copyin
    436 	add.l	#12,sp
    437 	move.l	(sp)+,d1
    438 	rts
    439 
    440 	end
    441