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) |	res_func.sa 3.9 7/29/91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) | Normalizes denormalized numbers if necessary and updates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) | stack frame.  The function is then restored back into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) | machine and the 040 completes the operation.  This routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) | is only used by the unsupported data type/format handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) | (Exception vector 55).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) | For packed move out (fmove.p fpm,<ea>) the operation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) | completed here; data is packed and moved to user memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) | The stack is restored to the 040 only in the case of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) | reportable exception in the conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) |		Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) |			All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) |       For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) |       file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) RES_FUNC:    |idnt    2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 	|section	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) sp_bnds:	.short	0x3f81,0x407e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 		.short	0x3f6a,0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) dp_bnds:	.short	0x3c01,0x43fe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 		.short	0x3bcd,0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	|xref	mem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	|xref	bindec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	|xref	get_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	|xref	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	|xref	denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	|xref	dest_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	|xref	dest_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	|xref	dest_sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	|xref	unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	|xref	nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	|xref	dnrm_lp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	|xref	ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	|xref	reg_dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	|xref	t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	|xref	t_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	.global	res_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	.global	p_move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) res_func:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	clrb	DNRM_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	clrb	RES_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	clrb	CU_ONLY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	tstb	DY_MO_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	beqs	monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) dyadic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	btstb	#7,DTAG(%a6)	|if dop = norm=000, zero=001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) |				;inf=010 or nan=011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	beqs	monadic		|then branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) |				;else denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) | HANDLE DESTINATION DENORM HERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) |				;set dtag to norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) |				;write the tag & fpte15 to the fstack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	leal	FPTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	bsr	nrm_set		|normalize number (exp will go negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	bclrb	#sign_bit,LOCAL_EX(%a0) |get rid of false sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	bfclr	LOCAL_SGN(%a0){#0:#8}	|change back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	beqs	dpos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) dpos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	bfclr	DTAG(%a6){#0:#4}	|set tag to normalized, FPTE15 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	bsetb	#4,DTAG(%a6)	|set FPTE15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	orb	#0x0f,DNRM_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) monadic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	leal	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	btstb	#direction_bit,CMDREG1B(%a6)	|check direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	bne	opclass3			|it is a mv out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) | At this point, only opclass 0 and 2 possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	btstb	#7,STAG(%a6)	|if sop = norm=000, zero=001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) |				;inf=010 or nan=011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	bne	mon_dnrm	|else denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	tstb	DY_MO_FLG(%a6)	|all cases of dyadic instructions would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	bne	normal		|require normalization of denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) | At this point:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) |	monadic instructions:	fabs  = $18  fneg   = $1a  ftst   = $3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) |				fmove = $00  fsmove = $40  fdmove = $44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) |				fsqrt = $05* fssqrt = $41  fdsqrt = $45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) |				(*fsqrt reencoded to $05)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	movew	CMDREG1B(%a6),%d0	|get command register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	andil	#0x7f,%d0			|strip to only command word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) | At this point, fabs, fneg, fsmove, fdmove, ftst, fsqrt, fssqrt, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) | fdsqrt are possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) | For cases fabs, fneg, fsmove, and fdmove goto spos (do not normalize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) | For cases fsqrt, fssqrt, and fdsqrt goto nrm_src (do normalize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	btstl	#0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	bne	normal			|weed out fsqrt instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) | cu_norm handles fmove in instructions with normalized inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) | The routine round is used to correctly round the input for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) | destination precision and mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) cu_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	st	CU_ONLY(%a6)		|set cu-only inst flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	andib	#0x3b,%d0		|isolate bits to select inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	tstb	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	beql	cu_nmove	|if zero, it is an fmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	cmpib	#0x18,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	beql	cu_nabs		|if $18, it is fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	cmpib	#0x1a,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	beql	cu_nneg		|if $1a, it is fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) | Inst is ftst.  Check the source operand and set the cc's accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) | No write is done, so simply rts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) cu_ntst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	movew	LOCAL_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	bclrl	#15,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	beqs	cu_ntpo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	orl	#neg_mask,USER_FPSR(%a6) |set N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) cu_ntpo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	cmpiw	#0x7fff,%d0	|test for inf/nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	bnes	cu_ntcz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	tstl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	bnes	cu_ntn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	bnes	cu_ntn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	orl	#inf_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) cu_ntn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	orl	#nan_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) |						;snan handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) cu_ntcz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	tstl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	bnel	cu_ntsx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	bnel	cu_ntsx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) cu_ntsx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) | Inst is fabs.  Execute the absolute value function on the input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) | Branch to the fmove code.  If the operand is NaN, do nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) cu_nabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	moveb	STAG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	btstl	#5,%d0			|test for NaN or zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	bne	wr_etemp		|if either, simply write it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	bclrb	#7,LOCAL_EX(%a0)		|do abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	bras	cu_nmove		|fmove code will finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) | Inst is fneg.  Execute the negate value function on the input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) | Fall though to the fmove code.  If the operand is NaN, do nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) cu_nneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	moveb	STAG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	btstl	#5,%d0			|test for NaN or zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	bne	wr_etemp		|if either, simply write it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	bchgb	#7,LOCAL_EX(%a0)		|do neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) | Inst is fmove.  This code also handles all result writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) | If bit 2 is set, round is forced to double.  If it is clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) | and bit 6 is set, round is forced to single.  If both are clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) | the round precision is found in the fpcr.  If the rounding precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) | is double or single, round the result before the write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) cu_nmove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	moveb	STAG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	andib	#0xe0,%d0			|isolate stag bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	bne	wr_etemp		|if not norm, simply write it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	btstb	#2,CMDREG1B+1(%a6)	|check for rd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	bne	cu_nmrd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	btstb	#6,CMDREG1B+1(%a6)	|check for rs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	bne	cu_nmrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) | The move or operation is not with forced precision.  Test for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) | nan or inf as the input; if so, simply write it to FPn.  Use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) | FPCR_MODE byte to get rounding on norms and zeros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) cu_nmnr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	bfextu	FPCR_MODE(%a6){#0:#2},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	tstb	%d0			|check for extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	beq	cu_wrexn		|if so, just write result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	cmpib	#1,%d0			|check for single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	beq	cu_nmrs			|fall through to double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) | The move is fdmove or round precision is double.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) cu_nmrd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	movel	#2,%d0			|set up the size for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	movew	LOCAL_EX(%a0),%d1		|compare exponent to double threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	andw	#0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	cmpw	#0x3c01,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	bls	cu_nunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1	|get rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	orl	#0x00020000,%d1		|or in rprec (double)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	clrl	%d0			|clear g,r,s for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	bclrb	#sign_bit,LOCAL_EX(%a0)	|convert to internal format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	bsrl	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	bfclr	LOCAL_SGN(%a0){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	beqs	cu_nmrdc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) cu_nmrdc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	movew	LOCAL_EX(%a0),%d1		|check for overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	andw	#0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	cmpw	#0x43ff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	bge	cu_novfl		|take care of overflow case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	bra	cu_wrexn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) | The move is fsmove or round precision is single.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) cu_nmrs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	movel	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	movew	LOCAL_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	andw	#0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	cmpw	#0x3f81,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	bls	cu_nunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	orl	#0x00010000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	clrl	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	bsrl	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	bfclr	LOCAL_SGN(%a0){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	beqs	cu_nmrsc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) cu_nmrsc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	movew	LOCAL_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	andw	#0x7FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	cmpw	#0x407f,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	blt	cu_wrexn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) | The operand is above precision boundaries.  Use t_ovfl to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) | generate the correct value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) cu_novfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	bsr	t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	bra	cu_wrexn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) | The operand is below precision boundaries.  Use denorm to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) | generate the correct value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) cu_nunfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	bsr	denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	bfclr	LOCAL_SGN(%a0){#0:#8}	|change back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	beqs	cu_nucont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) cu_nucont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	btstb	#2,CMDREG1B+1(%a6)	|check for rd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	bne	inst_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	btstb	#6,CMDREG1B+1(%a6)	|check for rs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	bne	inst_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	moveb	FPCR_MODE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	lsrb	#6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	bra	inst_sd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) inst_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	orl	#0x00020000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	bra	inst_sd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) inst_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	orl	#0x00010000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) inst_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	bsrl	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	bfclr	LOCAL_SGN(%a0){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	beqs	cu_nuflp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) cu_nuflp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	btstb	#inex2_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	beqs	cu_nuninx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	orl	#aunfl_mask,USER_FPSR(%a6) |if the round was inex, set AUNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) cu_nuninx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	tstl	LOCAL_HI(%a0)		|test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	bnes	cu_nunzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	bnes	cu_nunzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) | The mantissa is zero from the denorm loop.  Check sign and rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) | to see if rounding should have occurred which would leave the lsb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	andil	#0x30,%d0		|isolate rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	cmpil	#0x20,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	blts	cu_nzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	bnes	cu_nrp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) cu_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	tstw	LOCAL_EX(%a0)	|if positive, set lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	bges	cu_nzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	btstb	#7,FPCR_MODE(%a6) |check for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	beqs	cu_nincs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	bras	cu_nincd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) cu_nrp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	tstw	LOCAL_EX(%a0)	|if positive, set lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	blts	cu_nzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	btstb	#7,FPCR_MODE(%a6) |check for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	beqs	cu_nincs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) cu_nincd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	orl	#0x800,LOCAL_LO(%a0) |inc for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	bra	cu_nunzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) cu_nincs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	orl	#0x100,LOCAL_HI(%a0) |inc for single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	bra	cu_nunzro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) cu_nzro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	moveb	STAG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	andib	#0xe0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	cmpib	#0x40,%d0		|check if input was tagged zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	beqs	cu_numv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) cu_nunzro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	orl	#unfl_mask,USER_FPSR(%a6) |set unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) cu_numv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	movel	(%a0),ETEMP(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	movel	4(%a0),ETEMP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	movel	8(%a0),ETEMP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) | Write the result to memory, setting the fpsr cc bits.  NaN and Inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) | bypass cu_wrexn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) cu_wrexn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	tstw	LOCAL_EX(%a0)		|test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	beqs	cu_wrzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	cmpw	#0x8000,LOCAL_EX(%a0)	|test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	bnes	cu_wreon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) cu_wrzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	orl	#z_mask,USER_FPSR(%a6)	|set Z bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) cu_wreon:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	tstw	LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	bpl	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) | HANDLE SOURCE DENORM HERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) |				;clear denorm stag to norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) |				;write the new tag & ete15 to the fstack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) mon_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) | At this point, check for the cases in which normalizing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) | denorm produces incorrect results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	tstb	DY_MO_FLG(%a6)	|all cases of dyadic instructions would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	bnes	nrm_src		|require normalization of denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) | At this point:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) |	monadic instructions:	fabs  = $18  fneg   = $1a  ftst   = $3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) |				fmove = $00  fsmove = $40  fdmove = $44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) |				fsqrt = $05* fssqrt = $41  fdsqrt = $45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) |				(*fsqrt reencoded to $05)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	movew	CMDREG1B(%a6),%d0	|get command register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	andil	#0x7f,%d0			|strip to only command word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) | At this point, fabs, fneg, fsmove, fdmove, ftst, fsqrt, fssqrt, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) | fdsqrt are possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) | For cases fabs, fneg, fsmove, and fdmove goto spos (do not normalize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) | For cases fsqrt, fssqrt, and fdsqrt goto nrm_src (do normalize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	btstl	#0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	bnes	nrm_src		|weed out fsqrt instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	st	CU_ONLY(%a6)	|set cu-only inst flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	bra	cu_dnrm		|fmove, fabs, fneg, ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) |				;cases go to cu_dnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) nrm_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	bsr	nrm_set		|normalize number (exponent will go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) |				; negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	bclrb	#sign_bit,LOCAL_EX(%a0) |get rid of false sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	bfclr	LOCAL_SGN(%a0){#0:#8}	|change back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	beqs	spos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	bsetb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) spos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	bfclr	STAG(%a6){#0:#4}	|set tag to normalized, FPTE15 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	bsetb	#4,STAG(%a6)	|set ETE15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	orb	#0xf0,DNRM_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	tstb	DNRM_FLG(%a6)	|check if any of the ops were denorms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	bne	ck_wrap		|if so, check if it is a potential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) |				;wrap-around case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) fix_stk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	moveb	#0xfe,CU_SAVEPC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	st	RES_FLG(%a6)	|indicate that a restore is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) | cu_dnrm handles all cu-only instructions (fmove, fabs, fneg, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) | ftst) completely in software without an frestore to the 040.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) cu_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	st	CU_ONLY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	andib	#0x3b,%d0		|isolate bits to select inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	tstb	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	beql	cu_dmove	|if zero, it is an fmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	cmpib	#0x18,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	beql	cu_dabs		|if $18, it is fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	cmpib	#0x1a,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	beql	cu_dneg		|if $1a, it is fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) | Inst is ftst.  Check the source operand and set the cc's accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) | No write is done, so simply rts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) cu_dtst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	movew	LOCAL_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	bclrl	#15,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	beqs	cu_dtpo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	orl	#neg_mask,USER_FPSR(%a6) |set N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) cu_dtpo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	cmpiw	#0x7fff,%d0	|test for inf/nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	bnes	cu_dtcz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	tstl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	bnes	cu_dtn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	bnes	cu_dtn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	orl	#inf_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) cu_dtn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	orl	#nan_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) |						;snan handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) cu_dtcz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	tstl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	bnel	cu_dtsx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	bnel	cu_dtsx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) cu_dtsx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) | Inst is fabs.  Execute the absolute value function on the input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) | Branch to the fmove code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) cu_dabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	bclrb	#7,LOCAL_EX(%a0)		|do abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	bras	cu_dmove		|fmove code will finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) | Inst is fneg.  Execute the negate value function on the input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) | Fall though to the fmove code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) cu_dneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	bchgb	#7,LOCAL_EX(%a0)		|do neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) | Inst is fmove.  This code also handles all result writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) | If bit 2 is set, round is forced to double.  If it is clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) | and bit 6 is set, round is forced to single.  If both are clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) | the round precision is found in the fpcr.  If the rounding precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) | is double or single, the result is zero, and the mode is checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) | to determine if the lsb of the result should be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) cu_dmove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	btstb	#2,CMDREG1B+1(%a6)	|check for rd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	bne	cu_dmrd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	btstb	#6,CMDREG1B+1(%a6)	|check for rs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	bne	cu_dmrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) | The move or operation is not with forced precision.  Use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) | FPCR_MODE byte to get rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) cu_dmnr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	bfextu	FPCR_MODE(%a6){#0:#2},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	tstb	%d0			|check for extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	beq	cu_wrexd		|if so, just write result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	cmpib	#1,%d0			|check for single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	beq	cu_dmrs			|fall through to double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) | The move is fdmove or round precision is double.  Result is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) | Check rmode for rp or rm and set lsb accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) cu_dmrd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1	|get rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	tstw	LOCAL_EX(%a0)		|check sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	blts	cu_dmdn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	cmpib	#3,%d1			|check for rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	bne	cu_dpd			|load double pos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	bra	cu_dpdr			|load double pos zero w/lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) cu_dmdn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	cmpib	#2,%d1			|check for rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	bne	cu_dnd			|load double neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	bra	cu_dndr			|load double neg zero w/lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) | The move is fsmove or round precision is single.  Result is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) | Check for rp or rm and set lsb accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) cu_dmrs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1	|get rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	tstw	LOCAL_EX(%a0)		|check sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	blts	cu_dmsn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	cmpib	#3,%d1			|check for rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	bne	cu_spd			|load single pos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	bra	cu_spdr			|load single pos zero w/lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) cu_dmsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	cmpib	#2,%d1			|check for rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	bne	cu_snd			|load single neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	bra	cu_sndr			|load single neg zero w/lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) | The precision is extended, so the result in etemp is correct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) | Simply set unfl (not inex2 or aunfl) and write the result to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) | the correct fp register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) cu_wrexd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	orl	#unfl_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	tstw	LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	beq	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) | These routines write +/- zero in double format.  The routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) | cu_dpdr and cu_dndr set the double lsb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) cu_dpd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	movel	#0x3c010000,LOCAL_EX(%a0)	|force pos double zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) cu_dpdr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	movel	#0x3c010000,LOCAL_EX(%a0)	|force pos double zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	movel	#0x800,LOCAL_LO(%a0)	|with lsb set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) cu_dnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	movel	#0xbc010000,LOCAL_EX(%a0)	|force pos double zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) cu_dndr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	movel	#0xbc010000,LOCAL_EX(%a0)	|force pos double zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	movel	#0x800,LOCAL_LO(%a0)	|with lsb set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) | These routines write +/- zero in single format.  The routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) | cu_dpdr and cu_dndr set the single lsb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) cu_spd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	movel	#0x3f810000,LOCAL_EX(%a0)	|force pos single zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) cu_spdr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	movel	#0x3f810000,LOCAL_EX(%a0)	|force pos single zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	movel	#0x100,LOCAL_HI(%a0)	|with lsb set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) cu_snd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	movel	#0xbf810000,LOCAL_EX(%a0)	|force pos single zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	orl	#z_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) cu_sndr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	movel	#0xbf810000,LOCAL_EX(%a0)	|force pos single zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	movel	#0x100,LOCAL_HI(%a0)	|with lsb set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	bra	wr_etemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) | This code checks for 16-bit overflow conditions on dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) | operations which are not restorable into the floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) | unit and must be completed in software.  Basically, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) | condition exists with a very large norm and a denorm.  One
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) | of the operands must be denormalized to enter this code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) | Flags used:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) |	DY_MO_FLG contains 0 for monadic op, $ff for dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) |	DNRM_FLG contains $00 for neither op denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) |	                  $0f for the destination op denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) |	                  $f0 for the source op denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) |	                  $ff for both ops denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) | The wrap-around condition occurs for add, sub, div, and cmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) | when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) |	abs(dest_exp - src_exp) >= $8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) | and for mul when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) |	(dest_exp + src_exp) < $0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) | we must process the operation here if this case is true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) | The rts following the frcfpn routine is the exit from res_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) | for this condition.  The restore flag (RES_FLG) is left clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) | No frestore is done unless an exception is to be reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) | For fadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) |	if(sign_of(dest) != sign_of(src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) |		replace exponent of src with $3fff (keep sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) |		use fpu to perform dest+new_src (user's rmode and X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) |		clr sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) |	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) |		set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) |	call round with user's precision and mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) |	move result to fpn and wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) | For fsub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) |	if(sign_of(dest) == sign_of(src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) |		replace exponent of src with $3fff (keep sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) |		use fpu to perform dest+new_src (user's rmode and X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) |		clr sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) |	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) |		set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) |	call round with user's precision and mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) |	move result to fpn and wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) | For fdiv/fsgldiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) |	if(both operands are denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) |		restore_to_fpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) |	if(dest is norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) |		force_ovf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) |	else(dest is denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) |		force_unf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) | For fcmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) |	if(dest is norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) |		N = sign_of(dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) |	else(dest is denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) |		N = sign_of(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) | For fmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) |	if(both operands are denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) |		force_unf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) |	if((dest_exp + src_exp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) |		force_unf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) |	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) |		restore_to_fpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) | local equates:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	.set	addcode,0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	.set	subcode,0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	.set	mulcode,0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	.set	divcode,0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	.set	cmpcode,0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) ck_wrap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	| tstb	DY_MO_FLG(%a6)	;check for fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	beq	fix_stk		|if zero, it is fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	andiw	#0x3b,%d0		|strip to command bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	cmpiw	#addcode,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	beq	wrap_add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	cmpiw	#subcode,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	beq	wrap_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	cmpiw	#mulcode,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	beq	wrap_mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	cmpiw	#cmpcode,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	beq	wrap_cmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) | Inst is fdiv.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) wrap_div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	beq	fix_stk		 |restore to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) | One of the ops is denormalized.  Test for wrap condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) | and force the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	bnes	div_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) div_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	bsrl	ckinf_ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	subl	%d1,%d0			|subtract dest from src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	cmpl	#0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	clrb	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	movew	ETEMP_EX(%a6),%d0		|find the sign of the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	movew	FPTEMP_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	eorw	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	beq	force_unf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	st	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	bra	force_unf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) ckinf_ns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	moveb	STAG(%a6),%d0		|check source tag for inf or nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	bra	ck_in_com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) ckinf_nd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	moveb	DTAG(%a6),%d0		|check destination tag for inf or nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) ck_in_com:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	andib	#0x60,%d0			|isolate tag bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	cmpb	#0x40,%d0			|is it inf?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	beq	nan_or_inf		|not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	cmpb	#0x60,%d0			|is it nan?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	beq	nan_or_inf		|yes, not wrap case?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	cmpb	#0x20,%d0			|is it a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	beq	nan_or_inf		|yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	clrl	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	rts				|then ; it is either a zero of norm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) |					;check wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) nan_or_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	moveql	#-1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) div_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	bsrl	ckinf_nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	subl	%d1,%d0			|subtract src from dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	clrb	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	movew	ETEMP_EX(%a6),%d0		|find the sign of the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	movew	FPTEMP_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	eorw	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	beqs	force_ovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	st	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) | This code handles the case of the instruction resulting in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) | an overflow condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) force_ovf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	orl	#ovfl_inx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	leal	WBTEMP(%a6),%a0		|point a0 to memory location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	btstl	#6,%d0			|test for forced precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	beqs	frcovf_fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	btstl	#2,%d0			|check for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	bnes	frcovf_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	movel	#0x1,%d0			|inst is forced single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	bras	frcovf_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) frcovf_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	movel	#0x2,%d0			|inst is forced double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	bras	frcovf_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) frcovf_fpcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|inst not forced - use fpcr prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) frcovf_rnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) | The 881/882 does not set inex2 for the following case, so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) | line is commented out to be compatible with 881/882
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) |	tst.b	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) |	beq.b	frcovf_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) |	or.l	#inex2_mask,USER_FPSR(%a6) ;if prec is s or d, set inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) |frcovf_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	bsrl	ovf_res			|get correct result based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) |					;round precision/mode.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) |					;sets FPSR_CC correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) |					;returns in external format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	bfclr	WBTEMP_SGN(%a6){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	beq	frcfpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	bra	frcfpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) | Inst is fadd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) wrap_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	beq	fix_stk		 |restore to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) | One of the ops is denormalized.  Test for wrap condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) | and complete the instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	bnes	add_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) add_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	bsrl	ckinf_ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	subl	%d1,%d0			|subtract dest from src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	bra	add_wrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) add_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	bsrl	ckinf_nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	subl	%d1,%d0			|subtract src from dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) | Check the signs of the operands.  If they are unlike, the fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) | can be used to add the norm and 1.0 with the sign of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) | denorm and it will correctly generate the result in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) | precision.  We can then call round with no sticky and the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) | will be correct for the user's rounding mode and precision.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) | the signs are the same, we call round with the sticky bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) | and the result will be correct for the user's rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) | precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) add_wrap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	movew	ETEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	movew	FPTEMP_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	eorw	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	beq	add_same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) | The signs are unlike.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	cmpb	#0x0f,DNRM_FLG(%a6) |is dest the denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	bnes	add_u_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	movew	FPTEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	orw	#0x3fff,%d0	|force the exponent to +/- 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	movew	%d0,FPTEMP_EX(%a6) |in the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	fmovel	%d0,%fpcr		|set up users rmode and X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	fmovex	ETEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	faddx	FPTEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	fmovel	%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	fmovex	%fp0,WBTEMP(%a6)	|write result to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	clrl	%d0		|force sticky to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	bclrb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	sne	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	beq	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) add_u_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	movew	ETEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	orw	#0x3fff,%d0	|force the exponent to +/- 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	movew	%d0,ETEMP_EX(%a6) |in the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	fmovel	%d0,%fpcr		|set up users rmode and X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	fmovex	ETEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	faddx	FPTEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	fmovel	%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	fmovex	%fp0,WBTEMP(%a6)	|write result to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	clrl	%d0		|force sticky to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	bclrb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	sne	WBTEMP_SGN(%a6)	|use internal format for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	beq	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) | Signs are alike:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) add_same:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	cmpb	#0x0f,DNRM_FLG(%a6) |is dest the denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	bnes	add_s_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) add_s_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	leal	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	movel	#0x20000000,%d0	|set sticky for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	bclrb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	sne	ETEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	bfclr	ETEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	beqs	add_s_dclr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	bsetb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) add_s_dclr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	leal	WBTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	movel	ETEMP(%a6),(%a0)	|write result to wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	movel	ETEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	movel	ETEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	tstw	ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	bgt	add_ckovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	bra	add_ckovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) add_s_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	leal	FPTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	movel	#0x20000000,%d0	|set sticky for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	bclrb	#sign_bit,FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	sne	FPTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	bfclr	FPTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	beqs	add_s_sclr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	bsetb	#sign_bit,FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) add_s_sclr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	leal	WBTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	movel	FPTEMP(%a6),(%a0)	|write result to wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	movel	FPTEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	movel	FPTEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	tstw	FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	bgt	add_ckovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) add_ckovf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	movew	WBTEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	andiw	#0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	cmpiw	#0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	bne	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) | The result has overflowed to $7fff exponent.  Set I, ovfl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) | and aovfl, and clr the mantissa (incorrectly set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) | round routine.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	orl	#inf_mask+ovfl_inx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	clrl	4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) | Inst is fsub.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) wrap_sub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	beq	fix_stk		 |restore to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) | One of the ops is denormalized.  Test for wrap condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) | and complete the instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	bnes	sub_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) sub_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	bsrl	ckinf_ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	subl	%d1,%d0			|subtract src from dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	bra	sub_wrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) sub_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	bsrl	ckinf_nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	subl	%d1,%d0			|subtract dest from src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) | Check the signs of the operands.  If they are alike, the fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) | can be used to subtract from the norm 1.0 with the sign of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) | denorm and it will correctly generate the result in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) | precision.  We can then call round with no sticky and the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) | will be correct for the user's rounding mode and precision.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) | the signs are unlike, we call round with the sticky bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) | and the result will be correct for the user's rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) | precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) sub_wrap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	movew	ETEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	movew	FPTEMP_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	eorw	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	bne	sub_diff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) | The signs are alike.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	cmpb	#0x0f,DNRM_FLG(%a6) |is dest the denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	bnes	sub_u_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	movew	FPTEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	orw	#0x3fff,%d0	|force the exponent to +/- 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	movew	%d0,FPTEMP_EX(%a6) |in the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	fmovel	%d0,%fpcr		|set up users rmode and X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	fmovex	FPTEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	fsubx	ETEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	fmovel	%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	fmovex	%fp0,WBTEMP(%a6)	|write result to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	clrl	%d0		|force sticky to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	bclrb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	sne	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	beq	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) sub_u_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	movew	ETEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	orw	#0x3fff,%d0	|force the exponent to +/- 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	movew	%d0,ETEMP_EX(%a6) |in the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	fmovel	%d0,%fpcr		|set up users rmode and X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	fmovex	FPTEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	fsubx	ETEMP(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	fmovel	%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	fmovex	%fp0,WBTEMP(%a6)	|write result to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	clrl	%d0		|force sticky to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	bclrb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	sne	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	beq	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) | Signs are unlike:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) sub_diff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	cmpb	#0x0f,DNRM_FLG(%a6) |is dest the denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	bnes	sub_s_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) sub_s_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	leal	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	movel	#0x20000000,%d0	|set sticky for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) | Since the dest is the denorm, the sign is the opposite of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) | norm sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	eoriw	#0x8000,ETEMP_EX(%a6)	|flip sign on result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	tstw	ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	bgts	sub_s_dwr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) sub_s_dwr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	bclrb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	sne	ETEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	bfclr	ETEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	beqs	sub_s_dclr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	bsetb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) sub_s_dclr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	leal	WBTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	movel	ETEMP(%a6),(%a0)	|write result to wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	movel	ETEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	movel	ETEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	bra	sub_ckovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) sub_s_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	leal	FPTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	movel	USER_FPCR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	andil	#0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	lsrl	#4,%d0		|put rmode in lower 2 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	movel	USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	andil	#0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	lsrl	#6,%d1		|put precision in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	orl	%d0,%d1		|set up for round call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	movel	#0x20000000,%d0	|set sticky for round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	bclrb	#sign_bit,FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	sne	FPTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	bsrl	round		|round result to users rmode & prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	bfclr	FPTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	beqs	sub_s_sclr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	bsetb	#sign_bit,FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) sub_s_sclr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	leal	WBTEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	movel	FPTEMP(%a6),(%a0)	|write result to wbtemp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	movel	FPTEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	movel	FPTEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	tstw	FPTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	bgt	sub_ckovf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) sub_ckovf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	movew	WBTEMP_EX(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	andiw	#0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	cmpiw	#0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	bne	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) | The result has overflowed to $7fff exponent.  Set I, ovfl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) | and aovfl, and clr the mantissa (incorrectly set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) | round routine.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	orl	#inf_mask+ovfl_inx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	clrl	4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	bra	frcfpnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) | Inst is fcmp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) wrap_cmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	beq	fix_stk		 |restore to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) | One of the ops is denormalized.  Test for wrap condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) | and complete the instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	bnes	cmp_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) cmp_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	bsrl	ckinf_ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	subl	%d1,%d0			|subtract dest from src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	tstw	ETEMP_EX(%a6)		|set N to ~sign_of(src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	bge	cmp_setn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) cmp_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	bsrl	ckinf_nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	subl	%d1,%d0			|subtract src from dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	cmpl	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	blt	fix_stk			|if less, not wrap case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	tstw	FPTEMP_EX(%a6)		|set N to sign_of(dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	blt	cmp_setn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) cmp_setn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) | Inst is fmul.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) wrap_mul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	beq	force_unf	|force an underflow (really!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) | One of the ops is denormalized.  Test for wrap condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) | and complete the instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	bnes	mul_srcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) mul_destd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	bsrl	ckinf_ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	addl	%d1,%d0			|subtract dest from src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	bgt	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	bra	force_unf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mul_srcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	bsrl	ckinf_nd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	bne	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	addl	%d1,%d0			|subtract src from dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	bgt	fix_stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) | This code handles the case of the instruction resulting in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) | an underflow condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) force_unf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	orl	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	clrb	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	movew	ETEMP_EX(%a6),%d0		|find the sign of the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	movew	FPTEMP_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	eorw	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	andiw	#0x8000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	beqs	frcunfcont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	st	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) frcunfcont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	lea	WBTEMP(%a6),%a0		|point a0 to memory location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	btstl	#6,%d0			|test for forced precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	beqs	frcunf_fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	btstl	#2,%d0			|check for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	bnes	frcunf_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	movel	#0x1,%d0			|inst is forced single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	bras	frcunf_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) frcunf_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	movel	#0x2,%d0			|inst is forced double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	bras	frcunf_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) frcunf_fpcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|inst not forced - use fpcr prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) frcunf_rnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	bsrl	unf_sub			|get correct result based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) |					;round precision/mode.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) |					;sets FPSR_CC correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	beqs	frcfpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	bra	frcfpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) | Write the result to the user's fpn.  All results must be HUGE to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) | written; otherwise the results would have overflowed or underflowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) | If the rounding precision is single or double, the ovf_res routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) | is needed to correctly supply the max value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) frcfpnr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	btstl	#6,%d0			|test for forced precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	beqs	frcfpn_fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	btstl	#2,%d0			|check for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	bnes	frcfpn_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	movel	#0x1,%d0			|inst is forced single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	bras	frcfpn_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) frcfpn_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	movel	#0x2,%d0			|inst is forced double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	bras	frcfpn_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) frcfpn_fpcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|inst not forced - use fpcr prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	tstb	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	beqs	frcfpn			|if extended, write what you got
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) frcfpn_rnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	bclrb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	sne	WBTEMP_SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	bsrl	ovf_res			|get correct result based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) |					;round precision/mode.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) |					;sets FPSR_CC correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	beqs	frcfpn_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) frcfpn_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	orl	#ovfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) | Perform the write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) frcfpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	bfextu	CMDREG1B(%a6){#6:#3},%d0	|extract fp destination register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	cmpib	#3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	bles	frc0123			|check if dest is fp0-fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	movel	#7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	subl	%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	clrl	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	bsetl	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	fmovemx WBTEMP(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) frc0123:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	cmpib	#0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	beqs	frc0_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	cmpib	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	beqs	frc1_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	cmpib	#2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	beqs	frc2_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) frc3_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	movel	WBTEMP_EX(%a6),USER_FP3(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	movel	WBTEMP_HI(%a6),USER_FP3+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	movel	WBTEMP_LO(%a6),USER_FP3+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) frc2_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	movel	WBTEMP_EX(%a6),USER_FP2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	movel	WBTEMP_HI(%a6),USER_FP2+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	movel	WBTEMP_LO(%a6),USER_FP2+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) frc1_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	movel	WBTEMP_EX(%a6),USER_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	movel	WBTEMP_HI(%a6),USER_FP1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	movel	WBTEMP_LO(%a6),USER_FP1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) frc0_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	movel	WBTEMP_EX(%a6),USER_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	movel	WBTEMP_HI(%a6),USER_FP0+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	movel	WBTEMP_LO(%a6),USER_FP0+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) | Write etemp to fpn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) | A check is made on enabled and signalled snan exceptions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) | and the destination is not overwritten if this condition exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) | This code is designed to make fmoveins of unsupported data types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) | faster.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) wr_etemp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	btstb	#snan_bit,FPSR_EXCEPT(%a6)	|if snan is set, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	beqs	fmoveinc		|enabled, force restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	btstb	#snan_bit,FPCR_ENABLE(%a6) |and don't overwrite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	beqs	fmoveinc		|the dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) |						;snan handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	tstb	ETEMP(%a6)		|check for negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	blts	snan_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) snan_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	orl	#neg_bit,USER_FPSR(%a6)	|snan is negative; set N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) fmoveinc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	moveb	STAG(%a6),%d0		|check if stag is inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	andib	#0xe0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	cmpib	#0x40,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	bnes	fminc_cnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	orl	#inf_mask,USER_FPSR(%a6) |if inf, nothing yet has set I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	tstw	LOCAL_EX(%a0)		|check sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	bges	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	bra	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) fminc_cnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	cmpib	#0x60,%d0			|check if stag is NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	bnes	fminc_czero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	orl	#nan_mask,USER_FPSR(%a6) |if nan, nothing yet has set NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) |						;snan handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	tstw	LOCAL_EX(%a0)		|check sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	bges	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	bra	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) fminc_czero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	cmpib	#0x20,%d0			|check if zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	bnes	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	orl	#z_mask,USER_FPSR(%a6)	|if zero, set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	tstw	LOCAL_EX(%a0)		|check sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	bges	fminc_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	orl	#neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) fminc_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	bfextu	CMDREG1B(%a6){#6:#3},%d0	|extract fp destination register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	cmpib	#3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	bles	fp0123			|check if dest is fp0-fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	movel	#7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	subl	%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	clrl	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	bsetl	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	fmovemx ETEMP(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) fp0123:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	cmpib	#0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	beqs	fp0_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	cmpib	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	beqs	fp1_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	cmpib	#2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	beqs	fp2_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) fp3_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	movel	ETEMP_EX(%a6),USER_FP3(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	movel	ETEMP_HI(%a6),USER_FP3+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	movel	ETEMP_LO(%a6),USER_FP3+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) fp2_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	movel	ETEMP_EX(%a6),USER_FP2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	movel	ETEMP_HI(%a6),USER_FP2+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	movel	ETEMP_LO(%a6),USER_FP2+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) fp1_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	movel	ETEMP_EX(%a6),USER_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	movel	ETEMP_HI(%a6),USER_FP1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	movel	ETEMP_LO(%a6),USER_FP1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) fp0_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	movel	ETEMP_EX(%a6),USER_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	movel	ETEMP_HI(%a6),USER_FP0+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	movel	ETEMP_LO(%a6),USER_FP0+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) opclass3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	st	CU_ONLY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	movew	CMDREG1B(%a6),%d0	|check if packed moveout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	andiw	#0x0c00,%d0	|isolate last 2 bits of size field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	cmpiw	#0x0c00,%d0	|if size is 011 or 111, it is packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	beq	pack_out	|else it is norm or denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	bra	mv_out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) |	MOVE OUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) mv_tbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	.long	li
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	.long	sgp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	.long	xp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	.long	mvout_end	|should never be taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	.long	wi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	.long	dp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	.long	bi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	.long	mvout_end	|should never be taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) mv_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	bfextu	CMDREG1B(%a6){#3:#3},%d1	|put source specifier in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	leal	mv_tbl,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	movel	%a0@(%d1:l:4),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	jmp	(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) | This exit is for move-out to memory.  The aunfl bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) | set if the result is inex and unfl is signalled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) mvout_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	btstb	#inex2_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	beqs	no_aufl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	btstb	#unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	beqs	no_aufl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	bsetb	#aunfl_bit,FPSR_AEXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) no_aufl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	fmovel	#0,%FPSR			|clear any cc bits from res_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) | Return ETEMP to extended format from internal extended format so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) | that gen_except will have a correctly signed value for ovfl/unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) | handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	bfclr	ETEMP_SGN(%a6){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	beqs	mvout_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	bsetb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) mvout_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) | This exit is for move-out to int register.  The aunfl bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) | not set in any case for this move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) mvouti_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	clrw	NMNEXC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	bclrb	#E1,E_BYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	fmovel	#0,%FPSR			|clear any cc bits from res_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) | Return ETEMP to extended format from internal extended format so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) | that gen_except will have a correctly signed value for ovfl/unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) | handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	bfclr	ETEMP_SGN(%a6){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	beqs	mvouti_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	bsetb	#sign_bit,ETEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) mvouti_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) | li is used to handle a long integer source specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) li:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	moveql	#4,%d0		|set byte count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	bne	int_dnrm	|if so, branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	fmovemx ETEMP(%a6),%fp0-%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	fcmpd	#0x41dfffffffc00000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) | 41dfffffffc00000 in dbl prec = 401d0000fffffffe00000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	fbge	lo_plrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	fcmpd	#0xc1e0000000000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) | c1e0000000000000 in dbl prec = c01e00008000000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	fble	lo_nlrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) | at this point, the answer is between the largest pos and neg values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	movel	USER_FPCR(%a6),%d1	|use user's rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	andil	#0x30,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	fmovel	%d1,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	fmovel	%fp0,L_SCR1(%a6)	|let the 040 perform conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	fmovel %fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	bra	int_wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) lo_plrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	movel	#0x7fffffff,L_SCR1(%a6)	|answer is largest positive int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	fcmpd	#0x41dfffffffe00000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) | 41dfffffffe00000 in dbl prec = 401d0000ffffffff00000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	fbge	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) lo_nlrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	movel	#0x80000000,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	fcmpd	#0xc1e0000000100000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) | c1e0000000100000 in dbl prec = c01e00008000000080000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	fblt	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) | wi is used to handle a word integer source specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) wi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	moveql	#2,%d0		|set byte count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	bne	int_dnrm	|branch if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	fmovemx ETEMP(%a6),%fp0-%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	fcmps	#0x46fffe00,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) | 46fffe00 in sgl prec = 400d0000fffe000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	fbge	wo_plrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	fcmps	#0xc7000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) | c7000000 in sgl prec = c00e00008000000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	fble	wo_nlrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) | at this point, the answer is between the largest pos and neg values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	movel	USER_FPCR(%a6),%d1	|use user's rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	andil	#0x30,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	fmovel	%d1,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	fmovew	%fp0,L_SCR1(%a6)	|let the 040 perform conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	fmovel %fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	bra	int_wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) wo_plrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	movew	#0x7fff,L_SCR1(%a6)	|answer is largest positive int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	fcmps	#0x46ffff00,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) | 46ffff00 in sgl prec = 400d0000ffff000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	fbge	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) wo_nlrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	movew	#0x8000,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	fcmps	#0xc7000080,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) | c7000080 in sgl prec = c00e00008000800000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	fblt	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) | bi is used to handle a byte integer source specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) bi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	moveql	#1,%d0		|set byte count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	bne	int_dnrm	|branch if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	fmovemx ETEMP(%a6),%fp0-%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	fcmps	#0x42fe0000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) | 42fe0000 in sgl prec = 40050000fe00000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	fbge	by_plrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	fcmps	#0xc3000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) | c3000000 in sgl prec = c00600008000000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	fble	by_nlrg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) | at this point, the answer is between the largest pos and neg values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	movel	USER_FPCR(%a6),%d1	|use user's rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	andil	#0x30,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	fmovel	%d1,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	fmoveb	%fp0,L_SCR1(%a6)	|let the 040 perform conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	fmovel %fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	bra	int_wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) by_plrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	moveb	#0x7f,L_SCR1(%a6)		|answer is largest positive int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	fcmps	#0x42ff0000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) | 42ff0000 in sgl prec = 40050000ff00000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	fbge	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) by_nlrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	moveb	#0x80,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	fbeq	int_wrt			|exact answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	fcmps	#0xc3008000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) | c3008000 in sgl prec = c00600008080000000000000 in ext prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	fblt	int_operr		|set operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	bra	int_inx			|set inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) | Common integer routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) | int_drnrm---account for possible nonzero result for round up with positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) | operand and round down for negative answer.  In the first case (result = 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) | byte-width (store in d0) of result must be honored.  In the second case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) | -1 in L_SCR1(a6) will cover all contingencies (FMOVE.B/W/L out).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) int_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	movel	#0,L_SCR1(%a6)	| initialize result to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1	| d1 is the rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	cmpb	#2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	bmis	int_inx		| if RN or RZ, done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	bnes	int_rp		| if RP, continue below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	tstw	ETEMP(%a6)	| RM: store -1 in L_SCR1 if src is negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	bpls	int_inx		| otherwise result is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	movel	#-1,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	bras	int_inx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) int_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	tstw	ETEMP(%a6)	| RP: store +1 of proper width in L_SCR1 if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) |				; source is greater than 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	bmis	int_inx		| otherwise, result is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	lea	L_SCR1(%a6),%a1	| a1 is address of L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	addal	%d0,%a1		| offset by destination width -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	subal	#1,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	bsetb	#0,(%a1)		| set low bit at a1 address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) int_inx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	oril	#inx2a_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	bras	int_wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) int_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	fmovemx %fp0-%fp0,FPTEMP(%a6)	|FPTEMP must contain the extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) |				;precision source that needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) |				;converted to integer this is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) |				;if the operr exception is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) |				;set operr/aiop (no inex2 on int ovfl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	oril	#opaop_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) |				;fall through to perform int_wrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) int_wrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	movel	EXC_EA(%a6),%a1	|load destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	tstl	%a1		|check to see if it is a dest register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	beqs	wrt_dn		|write data register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	lea	L_SCR1(%a6),%a0	|point to supervisor source address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	bsrl	mem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	bra	mvouti_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) wrt_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	movel	%d0,-(%sp)	|d0 currently contains the size to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	bsrl	get_fline	|get_fline returns Dn in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	andiw	#0x7,%d0		|isolate register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	movel	(%sp)+,%d1	|get size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	cmpil	#4,%d1		|most frequent case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	beqs	sz_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	cmpil	#2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	bnes	sz_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	orl	#8,%d0		|add 'word' size to register#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	bras	sz_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) sz_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	orl	#0x10,%d0		|add 'long' size to register#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) sz_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	movel	%d0,%d1		|reg_dest expects size:reg in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	bsrl	reg_dest	|load proper data register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	bra	mvouti_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) xp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	lea	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	bne	xdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	clrl	%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	bras	do_fp		|do normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) sgp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	lea	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	bne	sp_catas	|branch if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	movew	LOCAL_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	lea	sp_bnds,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	cmpw	(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	blt	sp_under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	cmpw	2(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	bgt	sp_over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	movel	#1,%d0		|set destination format to single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	bras	do_fp		|do normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) dp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	lea	ETEMP(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	bclrb	#sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	sne	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	btstb	#7,STAG(%a6)	|check for extended denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	bne	dp_catas	|branch if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	movew	LOCAL_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	lea	dp_bnds,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	cmpw	(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	blt	dp_under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	cmpw	2(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	bgt	dp_over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	movel	#2,%d0		|set destination format to double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) |				;fall through to do_fp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) do_fp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1	|rnd mode in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	swap	%d0			|rnd prec in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	addl	%d0,%d1			|d1 has PREC/MODE info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	clrl	%d0			|clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	bsrl	round			|round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	movel	%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	movel	EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	bfextu	CMDREG1B(%a6){#3:#3},%d1	|extract destination format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) |					;at this point only the dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) |					;formats sgl, dbl, ext are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) |					;possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	cmpb	#2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	bgts	ddbl			|double=5, extended=2, single=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	bnes	dsgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) |					;fall through to dext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) dext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	bsrl	dest_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) dsgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	bsrl	dest_sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) ddbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	bsrl	dest_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) | Handle possible denorm or catastrophic underflow cases here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) xdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	bsr	set_xop		|initialize WBTEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	bsetb	#wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	movel	%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	bsrl	dest_ext	|store to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) sp_under:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	bsetb	#etemp15_bit,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	cmpw	4(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	blts	sp_catas	|catastrophic underflow case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	movel	#1,%d0		|load in round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	movel	#sgl_thresh,%d1	|load in single denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	bsrl	dpspdnrm	|expects d1 to have the proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) |				;denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	bsrl	dest_sgl	|stores value to destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	bra	mvout_end	|exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) dp_under:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	bsetb	#etemp15_bit,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	cmpw	4(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	blts	dp_catas	|catastrophic underflow case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	movel	#dbl_thresh,%d1	|load in double precision threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	movel	#2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	bsrl	dpspdnrm	|expects d1 to have proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) |				;denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) |				;expects d0 to have round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	bsrl	dest_dbl	|store value to destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	bra	mvout_end	|exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) | Handle catastrophic underflow cases here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) sp_catas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) | Temp fix for z bit set in unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	movel	USER_FPSR(%a6),-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	movel	#1,%d0		|set round precision to sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	bsrl	unf_sub		|a0 points to result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	movel	(%a7)+,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	movel	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	subw	%d0,LOCAL_EX(%a0) |account for difference between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) |				;denorm/norm bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	movel	%a0,%a1		|a1 has the operand input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	bsrl	dest_sgl	|store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	oril	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) dp_catas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) | Temp fix for z bit set in unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	movel	USER_FPSR(%a6),-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	movel	#2,%d0		|set round precision to dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	bsrl	unf_sub		|a0 points to result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	movel	(%a7)+,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	movel	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	subw	%d0,LOCAL_EX(%a0) |account for difference between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) |				;denorm/norm bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	movel	%a0,%a1		|a1 has the operand input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	bsrl	dest_dbl	|store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	oril	#unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) | Handle catastrophic overflow cases here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) sp_over:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) | Temp fix for z bit set in unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	movel	USER_FPSR(%a6),-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	movel	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	leal	FP_SCR1(%a6),%a0	|use FP_SCR1 for creating result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	movel	ETEMP_EX(%a6),(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	movel	ETEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	movel	ETEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	bsrl	ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	movel	(%a7)+,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	movel	%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	movel	EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	bsrl	dest_sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	orl	#ovfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) dp_over:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) | Temp fix for z bit set in ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	movel	USER_FPSR(%a6),-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	movel	#2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	leal	FP_SCR1(%a6),%a0	|use FP_SCR1 for creating result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	movel	ETEMP_EX(%a6),(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	movel	ETEMP_HI(%a6),4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	movel	ETEMP_LO(%a6),8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	bsrl	ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	movel	(%a7)+,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	movel	%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	movel	EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	bsrl	dest_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	orl	#ovfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	bra	mvout_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) |	DPSPDNRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) | This subroutine takes an extended normalized number and denormalizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) | it to the given round precision. This subroutine also decrements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) | the input operand's exponent by 1 to account for the fact that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) | dest_sgl or dest_dbl expects a normalized number's bias.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) | Input: a0  points to a normalized number in internal extended format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) |	 d0  is the round precision (=1 for sgl; =2 for dbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) |	 d1  is the single precision or double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) |	     denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) | Output: (In the format for dest_sgl or dest_dbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) |	 a0   points to the destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) |	 a1   points to the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) | Exceptions: Reports inexact 2 exception by setting USER_FPSR bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) dpspdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	movel	%d0,-(%a7)	|save round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	clrl	%d0		|clear initial g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	bsrl	dnrm_lp		|careful with d0, it's needed by round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	bfextu	FPCR_MODE(%a6){#2:#2},%d1 |get rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	swap	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	movew	2(%a7),%d1	|set rounding precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	swap	%d1		|at this point d1 has PREC/MODE info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	bsrl	round		|round result, sets the inex bit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) |				;USER_FPSR if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	movew	#1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	subw	%d0,LOCAL_EX(%a0) |account for difference in denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) |				;vs norm bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	movel	%a0,%a1		|a1 has the operand input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	addw	#4,%a7		|pop stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) | SET_XOP initialized WBTEMP with the value pointed to by a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) | input: a0 points to input operand in the internal extended format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) set_xop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	movel	LOCAL_EX(%a0),WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	movel	LOCAL_HI(%a0),WBTEMP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	movel	LOCAL_LO(%a0),WBTEMP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	bfclr	WBTEMP_SGN(%a6){#0:#8}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	beqs	sxop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	bsetb	#sign_bit,WBTEMP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) sxop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	bfclr	STAG(%a6){#5:#4}	|clear wbtm66,wbtm1,wbtm0,sbit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) |	P_MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) p_movet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	.long	p_move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	.long	p_movez
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	.long	p_movei
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	.long	p_moven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	.long	p_move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) p_regd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	.long	p_dyd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	.long	p_dyd1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	.long	p_dyd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	.long	p_dyd3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	.long	p_dyd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	.long	p_dyd5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	.long	p_dyd6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	.long	p_dyd7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) pack_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	leal	p_movet,%a0	|load jmp table address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	movew	STAG(%a6),%d0	|get source tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	bfextu	%d0{#16:#3},%d0	|isolate source bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	movel	(%a0,%d0.w*4),%a0	|load a0 with routine label for tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	jmp	(%a0)		|go to the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) p_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	movel	#0x0c,%d0	|get byte count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	movel	EXC_EA(%a6),%a1	|get the destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	bsr	mem_write	|write the user's destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	moveb	#0,CU_SAVEPC(%a6) |set the cu save pc to all 0's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) | Also note that the dtag must be set to norm here - this is because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) | the 040 uses the dtag to execute the correct microcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)         bfclr    DTAG(%a6){#0:#3}  |set dtag to norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) | Notes on handling of special case (zero, inf, and nan) inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) |	1. Operr is not signalled if the k-factor is greater than 18.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) |	2. Per the manual, status bits are not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) p_move:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	movew	CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	btstl	#kfact_bit,%d0	|test for dynamic k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	beqs	statick		|if clear, k-factor is static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) dynamick:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	bfextu	%d0{#25:#3},%d0	|isolate register for dynamic k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	lea	p_regd,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	movel	%a0@(%d0:l:4),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	jmp	(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) statick:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	andiw	#0x007f,%d0	|get k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	bfexts	%d0{#25:#7},%d0	|sign extend d0 for bindec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	bsrl	bindec		|perform the convert; data at a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	leal	FP_SCR1(%a6),%a0	|load a0 with result address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	bral	p_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) p_movez:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	clrw	2(%a0)		|clear lower word of exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	clrl	4(%a0)		|load second lword of ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	clrl	8(%a0)		|load third lword of ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	bra	p_write		|go write results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) p_movei:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	fmovel	#0,%FPSR		|clear aiop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	clrw	2(%a0)		|clear lower word of exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	bra	p_write		|go write the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) p_moven:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	clrw	2(%a0)		|clear lower word of exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	bra	p_write		|go write the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) | Routines to read the dynamic k-factor from Dn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) p_dyd0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	movel	USER_D0(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) p_dyd1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	movel	USER_D1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) p_dyd2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	movel	%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) p_dyd3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	movel	%d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) p_dyd4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	movel	%d4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) p_dyd5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	movel	%d5,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	bras	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) p_dyd6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	movel	%d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	bra	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) p_dyd7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	movel	%d7,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	bra	statick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	|end