Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) |	x_unfl.sa 3.4 7/1/91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) |	fpsp_unfl --- FPSP handler for underflow exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) | Trap disabled results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) |	For 881/2 compatibility, sw must denormalize the intermediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) | result, then store the result.  Denormalization is accomplished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) | by taking the intermediate result (which is always normalized) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) | shifting the mantissa right while incrementing the exponent until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) | it is equal to the denormalized exponent for the destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) | format.  After denormalization, the result is rounded to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) | destination format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) | Trap enabled results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) |	All trap disabled code applies.	In addition the exceptional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) | operand needs to made available to the user with a bias of $6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) | added to the exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) |		Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) |			All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) |       For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) |       file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) X_UNFL:	|idnt    2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	|section	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	|xref	denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	|xref	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	|xref	store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	|xref	g_rndpr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	|xref	g_opcls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	|xref	g_dfmtou
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	|xref	real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	|xref	real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	|xref	fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	|xref	b1238_fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	.global	fpsp_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) fpsp_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	link		%a6,#-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	fsave		-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	moveml		%d0-%d1/%a0-%a1,USER_DA(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	fmovemx	%fp0-%fp3,USER_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	fmoveml	%fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	bsrl		unf_res	|denormalize, round & store interm op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) | If underflow exceptions are not enabled, check for inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) | exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	btstb		#unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	beqs		ck_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	btstb		#E3,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	beqs		no_e3_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) | Clear dirty bit on dest resister in the frame before branching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) | to b1238_fix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	bsrl		b1238_fix		|test for bug1238 case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	orl		#sx_mask,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) no_e3_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	fmovemx	USER_FP0(%a6),%fp0-%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	frestore	(%a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	bral		real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) | It is possible to have either inex2 or inex1 exceptions with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) | unfl.  If the inex enable bit is set in the FPCR, and either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) | inex2 or inex1 occurred, we must clean up and branch to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) | real inex handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) ck_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	moveb		FPCR_ENABLE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	andb		FPSR_EXCEPT(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	andib		#0x3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	beqs		unfl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) | Inexact enabled and reported, and we must take an inexact exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) take_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	btstb		#E3,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	beqs		no_e3_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) | Clear dirty bit on dest resister in the frame before branching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) | to b1238_fix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	bsrl		b1238_fix		|test for bug1238 case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	orl		#sx_mask,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) no_e3_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	moveb		#INEX_VEC,EXC_VEC+1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	moveml         USER_DA(%a6),%d0-%d1/%a0-%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	fmovemx        USER_FP0(%a6),%fp0-%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	fmoveml        USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	frestore        (%a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	unlk            %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	bral		real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unfl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	bclrb		#E3,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	beqs		e1_set		|if set then branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) | Clear dirty bit on dest resister in the frame before branching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) | to b1238_fix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	bfextu		CMDREG3B(%a6){#6:#3},%d0		|get dest reg no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	bsrl		b1238_fix		|test for bug1238 case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	orl		#sx_mask,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	fmovemx	USER_FP0(%a6),%fp0-%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	frestore	(%a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	bral		fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) e1_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	fmovemx	USER_FP0(%a6),%fp0-%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	bral		fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) |	unf_res --- underflow result calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unf_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	bsrl		g_rndpr		|returns RND_PREC in d0 0=ext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) |					;1=sgl, 2=dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) |					;we need the RND_PREC in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) |					;upper word for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	movew		#0,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	movew		%d0,-(%a7)	|copy RND_PREC to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) | If the exception bit set is E3, the exceptional operand from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) | fpu is in WBTEMP; else it is in FPTEMP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	btstb		#E3,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	beqs		unf_E1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unf_E3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	lea		WBTEMP(%a6),%a0	|a0 now points to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) | Test for fsgldiv and fsglmul.  If the inst was one of these, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) | force the precision to extended for the denorm routine.  Use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) | the user's precision for the round routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	movew		CMDREG3B(%a6),%d1	|check for fsgldiv or fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	andiw		#0x7f,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	cmpiw		#0x30,%d1		|check for sgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	beqs		unf_sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	cmpiw		#0x33,%d1		|check for sglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	bnes		unf_cont	|if not, use fpcr prec in round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unf_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	clrl		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	movew		#0x1,(%a7)	|override g_rndpr precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) |					;force single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	bras		unf_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unf_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	lea		FPTEMP(%a6),%a0	|a0 now points to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unf_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	bclrb		#sign_bit,LOCAL_EX(%a0)	|clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	sne		LOCAL_SGN(%a0)		|store sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	bsrl		denorm		|returns denorm, a0 points to it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) | WARNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) |				;d0 has guard,round sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) |				;make sure that it is not corrupted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) |				;before it reaches the round subroutine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) |				;also ensure that a0 isn't corrupted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) | Set up d1 for round subroutine d1 contains the PREC/MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) | information respectively on upper/lower register halves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	bfextu		FPCR_MODE(%a6){#2:#2},%d1	|get mode from FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) |						;mode in lower d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	addl		(%a7)+,%d1		|merge PREC/MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) | WARNING: a0 and d0 are assumed to be intact between the denorm and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) | round subroutines. All code between these two subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) | must not corrupt a0 and d0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) | Perform Round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) |	Input:		a0 points to input operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) |			d0{31:29} has guard, round, sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) |			d1{01:00} has rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) |			d1{17:16} has rounding precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) |	Output:		a0 points to rounded operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	bsrl		round		|returns rounded denorm at (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) | Differentiate between store to memory vs. store to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unf_store:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	bsrl		g_opcls		|returns opclass in d0{2:0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	cmpib		#0x3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	bnes		not_opc011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) | At this point, a store to memory is pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) opc011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	bsrl		g_dfmtou
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	tstb		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	beqs		ext_opc011	|If extended, do not subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) |				;If destination format is sgl/dbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	tstb		LOCAL_HI(%a0)	|If rounded result is normal,don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) |					;subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	bmis		ext_opc011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	subqw		#1,LOCAL_EX(%a0)	|account for denorm bias vs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) |				;normalized bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) |				;          normalized   denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) |				;single       $7f           $7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) |				;double       $3ff          $3fe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ext_opc011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	bsrl		store		|stores to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	bras		unf_done	|finish up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) | At this point, a store to a float register is pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) not_opc011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	bsrl		store	|stores to float register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) |				;a0 is not corrupted on a store to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) |				;float register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) | Set the condition codes according to result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	tstl		LOCAL_HI(%a0)	|check upper mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	bnes		ck_sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	tstl		LOCAL_LO(%a0)	|check lower mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	bnes		ck_sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	bsetb		#z_bit,FPSR_CC(%a6) |set condition codes if zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ck_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	btstb		#sign_bit,LOCAL_EX(%a0)	|check the sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	beqs		unf_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	bsetb		#neg_bit,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) | Finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	btstb		#inex2_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	beqs		no_aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	bsetb		#aunfl_bit,FPSR_AEXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) no_aunfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	|end