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) |	round.sa 3.4 7/29/91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) |	handle rounding and normalization tasks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) |		Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) |			All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) |       For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) |       file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) |ROUND	idnt    2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	|section	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) |	round --- round result according to precision/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) |	a0 points to the input operand in the internal extended format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) |	d1(high word) contains rounding precision:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) |		ext = $0000xxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) |		sgl = $0001xxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) |		dbl = $0002xxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) |	d1(low word) contains rounding mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) |		RN  = $xxxx0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) |		RZ  = $xxxx0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) |		RM  = $xxxx0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) |		RP  = $xxxx0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) |	d0{31:29} contains the g,r,s bits (extended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) |	On return the value pointed to by a0 is correctly rounded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) |	a0 is preserved and the g-r-s bits in d0 are cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) |	The result is not typed - the tag field is invalid.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) |	result is still in the internal extended format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) |	The INEX bit of USER_FPSR will be set if the rounded result was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) |	inexact (i.e. if any of the g-r-s bits were set).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	.global	round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) | If g=r=s=0 then result is exact and round is done, else set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) | the inex flag in status reg and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	bsrs	ext_grs			|this subroutine looks at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) |					:rounding precision and sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) |					;the appropriate g-r-s bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	tstl	%d0			|if grs are zero, go force
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	bne	rnd_cont		|lower bits to zero for size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	swap	%d1			|set up d1.w for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	bra	truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) rnd_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) | Use rounding mode as an index into a jump table for these modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	orl	#inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	lea	mode_tab,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	movel	(%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	jmp	(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) | Jump table indexed by rounding mode in d1.w.  All following assumes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) | grs != 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) mode_tab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	.long	rnd_near
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	.long	rnd_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	.long	rnd_mnus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	.long	rnd_plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) |	ROUND PLUS INFINITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) |	If sign of fp number = 0 (positive), then add 1 to l.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) rnd_plus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	swap	%d1			|set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	tstb	LOCAL_SGN(%a0)		|check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	bmi	truncate		|if positive then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	movel	#0xffffffff,%d0		|force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	lea	add_to_l,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	movel	(%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	jmp	(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) |	ROUND MINUS INFINITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) |	If sign of fp number = 1 (negative), then add 1 to l.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) rnd_mnus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	swap	%d1			|set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	tstb	LOCAL_SGN(%a0)		|check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	bpl	truncate		|if negative then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	movel	#0xffffffff,%d0		|force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	lea	add_to_l,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	movel	(%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	jmp	(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) |	ROUND ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) |	Always truncate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) rnd_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	swap	%d1			|set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	bra	truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) |	ROUND NEAREST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) |	If (g=1), then add 1 to l and if (r=s=0), then clear l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) |	Note that this will round to even in case of a tie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rnd_near:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	swap	%d1			|set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	asll	#1,%d0			|shift g-bit to c-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	bcc	truncate		|if (g=1) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	lea	add_to_l,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	movel	(%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	jmp	(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) |	ext_grs --- extract guard, round and sticky bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) | Input:	d1 =		PREC:ROUND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) | Output:	d0{31:29}=	guard, round, sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) | The ext_grs extract the guard/round/sticky bits according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) | selected rounding precision. It is called by the round subroutine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) | only.  All registers except d0 are kept intact. d0 becomes an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) | updated guard,round,sticky in d0{31:29}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) | Notes: the ext_grs uses the round PREC, and therefore has to swap d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) |	 prior to usage, and needs to restore d1 to original.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ext_grs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	swap	%d1			|have d1.w point to round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	cmpiw	#0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	bnes	sgl_or_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	bras	end_ext_grs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) sgl_or_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	moveml	%d2/%d3,-(%a7)		|make some temp registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	cmpiw	#1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	bnes	grs_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) grs_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	bfextu	LOCAL_HI(%a0){#24:#2},%d3	|sgl prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	movel	#30,%d2			|of the sgl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	lsll	%d2,%d3			|shift g-r bits to MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	movel	LOCAL_HI(%a0),%d2		|get word 2 for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	andil	#0x0000003f,%d2		|s bit is the or of all other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	bnes	st_stky			|bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	tstl	LOCAL_LO(%a0)		|test lower mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	bnes	st_stky			|if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	tstl	%d0			|test original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	bnes	st_stky			|if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	bras	end_sd			|if words 3 and 4 are clr, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) grs_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	bfextu	LOCAL_LO(%a0){#21:#2},%d3	|dbl-prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	movel	#30,%d2			|of the dbl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	lsll	%d2,%d3			|shift g-r bits to the MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	movel	LOCAL_LO(%a0),%d2		|get lower mantissa  for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	andil	#0x000001ff,%d2		|s bit is the or-ing of all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	bnes	st_stky			|other bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	tstl	%d0			|test word original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	bnes	st_stky			|if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	bras	end_sd			|if clear, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) st_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	bset	#rnd_stky_bit,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) end_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	movel	%d3,%d0			|return grs to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	moveml	(%a7)+,%d2/%d3		|restore scratch registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) end_ext_grs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	swap	%d1			|restore d1 to original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) |*******************  Local Equates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	.set	ad_1_sgl,0x00000100	|  constant to add 1 to l-bit in sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	.set	ad_1_dbl,0x00000800	|  constant to add 1 to l-bit in dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) |Jump table for adding 1 to the l-bit indexed by rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) add_to_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.long	add_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.long	add_sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	.long	add_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	.long	add_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) |	ADD SINGLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) add_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	addl	#ad_1_sgl,LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	bccs	scc_clr			|no mantissa overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	roxrw  LOCAL_HI(%a0)		|shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	roxrw  LOCAL_HI+2(%a0)		|shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	addw	#0x1,LOCAL_EX(%a0)	|and incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) scc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	tstl	%d0			|test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	bnes	sgl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	andiw  #0xfe00,LOCAL_HI+2(%a0)	|clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sgl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	andil	#0xffffff00,LOCAL_HI(%a0) |truncate bits beyond sgl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	clrl	LOCAL_LO(%a0)		|clear d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) |	ADD EXTENDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) add_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	addql  #1,LOCAL_LO(%a0)		|add 1 to l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	bccs	xcc_clr			|test for carry out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	addql  #1,LOCAL_HI(%a0)		|propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	bccs	xcc_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	roxrw  LOCAL_HI(%a0)		|mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	roxrw  LOCAL_HI+2(%a0)		|mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	roxrw	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	roxrw	LOCAL_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	addw	#0x1,LOCAL_EX(%a0)	|and inc exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) xcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	tstl	%d0			|test rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	bnes	add_ext_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	andib	#0xfe,LOCAL_LO+3(%a0)	|clear the l bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) add_ext_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) |	ADD DOUBLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) add_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	addl	#ad_1_dbl,LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	bccs	dcc_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	addql	#1,LOCAL_HI(%a0)		|propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	bccs	dcc_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	roxrw	LOCAL_HI(%a0)		|mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	roxrw	LOCAL_HI+2(%a0)		|mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	roxrw	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	roxrw	LOCAL_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	addw	#0x1,LOCAL_EX(%a0)	|incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	tstl	%d0			|test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	bnes	dbl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	andiw	#0xf000,LOCAL_LO+2(%a0)	|clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dbl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	andil	#0xfffff800,LOCAL_LO(%a0) |truncate bits beyond dbl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) | Truncate all other bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) trunct:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	.long	end_rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	.long	sgl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	.long	dbl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	.long	dbl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) truncate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	lea	trunct,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	movel	(%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	jmp	(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) end_rnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) |	NORMALIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) | These routines (nrm_zero & nrm_set) normalize the unnorm.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) | is done by shifting the mantissa left while decrementing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) | exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) | NRM_SET shifts and decrements until there is a 1 set in the integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) | bit of the mantissa (msb in d1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) | NRM_ZERO shifts and decrements until there is a 1 set in the integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) | bit of the mantissa (msb in d1) unless this would mean the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) | would go less than 0.  In that case the number becomes a denorm - the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) | exponent (d0) is set to 0 and the mantissa (d1 & d2) is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) | normalized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) | Note that both routines have been optimized (for the worst case) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) | therefore do not have the easy to follow decrement/shift loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) |	NRM_ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) |	Distance to first 1 bit in mantissa = X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) |	Distance to 0 from exponent = Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) |	If X < Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) |	Then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) |	  nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) |	Else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) |	  shift mantissa by Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) |	  set exponent = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) |input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) |	FP_SCR1 = exponent, ms mantissa part, ls mantissa part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) |output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) |	L_SCR1{4} = fpte15 or ete15 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.global	nrm_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) nrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	movew	LOCAL_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	cmpw   #64,%d0          |see if exp > 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	bmis	d0_less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	bsr	nrm_set		|exp > 64 so exp won't exceed 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) d0_less:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	moveml	%d2/%d3/%d5/%d6,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	movel	LOCAL_HI(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	movel	LOCAL_LO(%a0),%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	bfffo	%d1{#0:#32},%d3	|get the distance to the first 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) |				;in ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	beqs	ms_clr		|branch if no bits were set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	cmpw	%d3,%d0		|of X>Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	bmis	greater		|then exp will go past 0 (neg) if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) |				;it is just shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	bsr	nrm_set		|else exp won't go past 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	moveml	(%a7)+,%d2/%d3/%d5/%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) greater:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	movel	%d2,%d6		|save ls mant in d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	lsll	%d0,%d2		|shift ls mant by count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	lsll	%d0,%d1		|shift ms mant by count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	movel	#32,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	subl	%d0,%d5		|make op a denorm by shifting bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	lsrl	%d5,%d6		|by the number in the exp, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) |				;set exp = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	orl	%d6,%d1		|shift the ls mant bits into the ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	movel	#0,%d0		|same as if decremented exp to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) |				;while shifting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	movew	%d0,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	movel	%d1,LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	movel	%d2,LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	moveml	(%a7)+,%d2/%d3/%d5/%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ms_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	bfffo	%d2{#0:#32},%d3	|check if any bits set in ls mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	beqs	all_clr		|branch if none set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	addw	#32,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	cmpw	%d3,%d0		|if X>Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	bmis	greater		|then branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	bsr	nrm_set		|else exp won't go past 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	moveml	(%a7)+,%d2/%d3/%d5/%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) all_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	movew	#0,LOCAL_EX(%a0)	|no mantissa bits set. Set exp = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	moveml	(%a7)+,%d2/%d3/%d5/%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) |	NRM_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	.global	nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) nrm_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	movel	%d7,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	bfffo	LOCAL_HI(%a0){#0:#32},%d7 |find first 1 in ms mant to d7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	beqs	lower		|branch if ms mant is all 0's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	movel	%d6,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	subw	%d7,LOCAL_EX(%a0)	|sub exponent by count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	movel	LOCAL_HI(%a0),%d0	|d0 has ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	movel	LOCAL_LO(%a0),%d1 |d1 has ls mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	lsll	%d7,%d0		|shift first 1 to j bit position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	movel	%d1,%d6		|copy ls mant into d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	lsll	%d7,%d6		|shift ls mant by count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	movel	%d6,LOCAL_LO(%a0)	|store ls mant into memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	moveql	#32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	subl	%d7,%d6		|continue shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	lsrl	%d6,%d1		|shift off all bits but those that will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) |				;be shifted into ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	orl	%d1,%d0		|shift the ls mant bits into the ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	movel	%d0,LOCAL_HI(%a0)	|store ms mant into memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	moveml	(%a7)+,%d7/%d6	|restore registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) | We get here if ms mant was = 0, and we assume ls mant has bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) | set (otherwise this would have been tagged a zero not a denorm).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) lower:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	movew	LOCAL_EX(%a0),%d0	|d0 has exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	movel	LOCAL_LO(%a0),%d1	|d1 has ls mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	subw	#32,%d0		|account for ms mant being all zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	bfffo	%d1{#0:#32},%d7	|find first 1 in ls mant to d7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	subw	%d7,%d0		|subtract shift count from exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	lsll	%d7,%d1		|shift first 1 to integer bit in ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	movew	%d0,LOCAL_EX(%a0)	|store ms mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	movel	%d1,LOCAL_HI(%a0)	|store exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	clrl	LOCAL_LO(%a0)	|clear ls mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	movel	(%a7)+,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) |	denorm --- denormalize an intermediate result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) |	Used by underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) | Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) |	a0	 points to the operand to be denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) |		 (in the internal extended format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) |	d0:	 rounding precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) | Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) |	a0	 points to the denormalized result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) |		 (in the internal extended format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) |	d0	is guard,round,sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) | d0 comes into this routine with the rounding precision. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) | is then loaded with the denormalized exponent threshold for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) | rounding precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	.global	denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	btstb	#6,LOCAL_EX(%a0)	|check for exponents between $7fff-$4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	beqs	no_sgn_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	bsetb	#7,LOCAL_EX(%a0)	|sign extend if it is so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) no_sgn_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	cmpib	#0,%d0		|if 0 then extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	bnes	not_ext		|else branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	clrl	%d1		|load d1 with ext threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	clrl	%d0		|clear the sticky flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	bsr	dnrm_lp		|denormalize the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	tstb	%d1		|check for inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	beq	no_inex		|if clr, no inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	bras	dnrm_inex	|if set, set inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	cmpil	#1,%d0		|if 1 then single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	beqs	load_sgl	|else must be 2, double prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) load_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	movew	#dbl_thresh,%d1	|put copy of threshold in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	movel	%d1,%d0		|copy d1 into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	subw	LOCAL_EX(%a0),%d0	|diff = threshold - exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	cmpw	#67,%d0		|if diff > 67 (mant + grs bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	bpls	chk_stky	|then branch (all bits would be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) |				; shifted off in denorm routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	clrl	%d0		|else clear the sticky flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	bsr	dnrm_lp		|denormalize the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	tstb	%d1		|check flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	beqs	no_inex		|if clr, no inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	bras	dnrm_inex	|if set, set inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) load_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	movew	#sgl_thresh,%d1	|put copy of threshold in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	movel	%d1,%d0		|copy d1 into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	subw	LOCAL_EX(%a0),%d0	|diff = threshold - exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	cmpw	#67,%d0		|if diff > 67 (mant + grs bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	bpls	chk_stky	|then branch (all bits would be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) |				; shifted off in denorm routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	clrl	%d0		|else clear the sticky flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	bsr	dnrm_lp		|denormalize the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	tstb	%d1		|check flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	beqs	no_inex		|if clr, no inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	bras	dnrm_inex	|if set, set inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) chk_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	tstl	LOCAL_HI(%a0)	|check for any bits set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	bnes	set_stky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	tstl	LOCAL_LO(%a0)	|check for any bits set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	bnes	set_stky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	bras	clr_mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) set_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	orl	#inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	movel	#0x20000000,%d0	|set sticky bit in return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) clr_mant:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	movew	%d1,LOCAL_EX(%a0)		|load exp with threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	movel	#0,LOCAL_HI(%a0)	|set d1 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	movel	#0,LOCAL_LO(%a0)		|set d2 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dnrm_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	orl	#inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) no_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) |	dnrm_lp --- normalize exponent/mantissa to specified threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) | Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) |	a0		points to the operand to be denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) |	d0{31:29}	initial guard,round,sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) |	d1{15:0}	denormalization threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) | Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) |	a0		points to the denormalized operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) |	d0{31:29}	final guard,round,sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) |	d1.b		inexact flag:  all ones means inexact result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) | The LOCAL_LO and LOCAL_GRS parts of the value are copied to FP_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) | so that bfext can be used to extract the new low part of the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) | Dnrm_lp can be called with a0 pointing to ETEMP or WBTEMP and there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) | is no LOCAL_GRS scratch word following it on the fsave frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	.global	dnrm_lp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dnrm_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	movel	%d2,-(%sp)		|save d2 for temp use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	btstb	#E3,E_BYTE(%a6)		|test for type E3 exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	beqs	not_E3			|not type E3 exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	bfextu	WBTEMP_GRS(%a6){#6:#3},%d2	|extract guard,round, sticky  bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	movel	#29,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	lsll	%d0,%d2			|shift g,r,s to their positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	movel	%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) not_E3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	movel	(%sp)+,%d2		|restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	movel	LOCAL_LO(%a0),FP_SCR2+LOCAL_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	movel	%d0,FP_SCR2+LOCAL_GRS(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	movel	%d1,%d0			|copy the denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	subw	LOCAL_EX(%a0),%d1		|d1 = threshold - uns exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	bles	no_lp			|d1 <= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	cmpw	#32,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	blts	case_1			|0 = d1 < 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	cmpw	#64,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	blts	case_2			|32 <= d1 < 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	bra	case_3			|d1 >= 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) | No normalization necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) no_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	clrb	%d1			|set no inex2 reported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	movel	FP_SCR2+LOCAL_GRS(%a6),%d0	|restore original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) | case (0<d1<32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	movel	%d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	movew	%d0,LOCAL_EX(%a0)		|exponent = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	movel	#32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	subw	%d1,%d0			|d0 = 32 - d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	bfextu	LOCAL_EX(%a0){%d0:#32},%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	bfextu	%d2{%d1:%d0},%d2		|d2 = new LOCAL_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	bfextu	LOCAL_HI(%a0){%d0:#32},%d1	|d1 = new LOCAL_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	bfextu	FP_SCR2+LOCAL_LO(%a6){%d0:#32},%d0	|d0 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	movel	%d2,LOCAL_HI(%a0)		|store new LOCAL_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	movel	%d1,LOCAL_LO(%a0)		|store new LOCAL_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	clrb	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	bftst	%d0{#2:#30}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	beqs	c1nstky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	bsetl	#rnd_stky_bit,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	st	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) c1nstky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	movel	FP_SCR2+LOCAL_GRS(%a6),%d2	|restore original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	andil	#0xe0000000,%d2		|clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	tstl	%d2			|test if original G,R,S are clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	beqs	grs_clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	orl	#0x20000000,%d0		|set sticky bit in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) grs_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	andil	#0xe0000000,%d0		|clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	movel	(%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) | case (32<=d1<64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	movel	%d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	movew	%d0,LOCAL_EX(%a0)		|unsigned exponent = threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	subw	#32,%d1			|d1 now between 0 and 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	movel	#32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	subw	%d1,%d0			|d0 = 32 - d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	bfextu	LOCAL_EX(%a0){%d0:#32},%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	bfextu	%d2{%d1:%d0},%d2		|d2 = new LOCAL_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	bfextu	LOCAL_HI(%a0){%d0:#32},%d1	|d1 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	bftst	%d1{#2:#30}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	bnes	c2_sstky		|bra if sticky bit to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	bftst	FP_SCR2+LOCAL_LO(%a6){%d0:#32}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	bnes	c2_sstky		|bra if sticky bit to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	movel	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	clrb	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	bras	end_c2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) c2_sstky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	movel	%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	bsetl	#rnd_stky_bit,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	st	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) end_c2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	clrl	LOCAL_HI(%a0)		|store LOCAL_HI = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	movel	%d2,LOCAL_LO(%a0)		|store LOCAL_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	movel	FP_SCR2+LOCAL_GRS(%a6),%d2	|restore original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	andil	#0xe0000000,%d2		|clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	tstl	%d2			|test if original G,R,S are clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	beqs	clear_grs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	orl	#0x20000000,%d0		|set sticky bit in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) clear_grs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	andil	#0xe0000000,%d0		|get rid of all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	movel	(%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) | d1 >= 64 Force the exponent to be the denorm threshold with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) | correct sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	movew	%d0,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	tstw	LOCAL_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	bges	c3con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) c3neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	orl	#0x80000000,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) c3con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	cmpw	#64,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	beqs	sixty_four
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	cmpw	#65,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	beqs	sixty_five
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) | Shift value is out of range.  Set d1 for inex2 flag and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) | return a zero with the given threshold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	movel	#0x20000000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	st	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) sixty_four:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	movel	LOCAL_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	bfextu	%d0{#2:#30},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	andil	#0xc0000000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	bras	c3com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) sixty_five:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	movel	LOCAL_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	bfextu	%d0{#1:#31},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	andil	#0x80000000,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	lsrl	#1,%d0			|shift high bit into R bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) c3com:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	tstl	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	bnes	c3ssticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	tstl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	bnes	c3ssticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	tstb	FP_SCR2+LOCAL_GRS(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	bnes	c3ssticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	clrb	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	bras	c3end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) c3ssticky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	bsetl	#rnd_stky_bit,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	st	%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) c3end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	clrl	LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	clrl	LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	|end