When I wrote fef 8, I forgot to test denormalized numbers. Oops. Now fix two of my mistakes: - When checking for zero, `extrwi r6, r3, 22, 12` needs to be `extrwi r6, r3, 20, 12`. There are only 20 bits to extract. - After the multiplication by 2**64, I forgot to put the fraction in [0.5, 1) or (-1, 0.5] by setting IEEE exponent = 1022. Teach fif 8 about signed zero and NaN. In ncg/table, change cmf so NaN is not equal to any value, and comment why ordered comparisons don't work with NaN. Also add cost for fctwiz, remove extra `uses REG`. Edit comment in cfu8.s because the conditional branch might be before or after fctwiz.
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
.sect .text
 | 
						|
 | 
						|
! Multiplies two single-precision floats, then splits the product into
 | 
						|
! fraction and integer, both as floats, like modff(3) in C,
 | 
						|
! http://en.cppreference.com/w/c/numeric/math/modf
 | 
						|
!
 | 
						|
! Stack: ( a b -- fraction integer )
 | 
						|
 | 
						|
.define .fif4
 | 
						|
.fif4:
 | 
						|
	lfs f1, 4(sp)
 | 
						|
	lfs f2, 0(sp)
 | 
						|
	fmuls f1, f1, f2		! f1 = a * b
 | 
						|
	stfs f1, 0(sp)
 | 
						|
	lwz r3, 0(sp)			! r3 = word of float bits
 | 
						|
 | 
						|
	! IEEE single = sign * 1.fraction * 2**(exponent - 127)
 | 
						|
	!   sign  exponent  fraction
 | 
						|
	!   0     1..8      9..31
 | 
						|
	!
 | 
						|
	! Subtract 127 from the IEEE exponent.  If the result is from
 | 
						|
	! 0 to 23, then the IEEE fraction has that many integer bits.
 | 
						|
 | 
						|
	extrwi r5, r3, 8, 1		! r5 = IEEE exponent
 | 
						|
	addic. r5, r5, -127		! r5 = nr of integer bits
 | 
						|
	blt 3f				! branch if no integer
 | 
						|
	cmpwi r5, 24
 | 
						|
	bge 4f				! branch if no fraction
 | 
						|
	! fall through if integer with fraction
 | 
						|
 | 
						|
	! f1 has r5 = 0 to 23 integer bits in the IEEE fraction.
 | 
						|
	! There are 23 - r5 fraction bits.
 | 
						|
	li r6, 23
 | 
						|
	subf r6, r5, r6
 | 
						|
	srw r3, r3, r6
 | 
						|
	slw r3, r3, r6			! clear fraction in word
 | 
						|
	! fall through
 | 
						|
 | 
						|
1:	stw r3, 0(sp)
 | 
						|
	lfs f2, 0(sp)			! integer = high word, low word
 | 
						|
	fsubs f1, f1, f2		! fraction = value - integer
 | 
						|
2:	stfs f1, 4(sp)			! push fraction
 | 
						|
	stfs f2, 0(sp)			! push integer
 | 
						|
	blr
 | 
						|
 | 
						|
	! f1 is a fraction without integer (or zero).
 | 
						|
	! Then integer is zero with same sign.
 | 
						|
3:	extlwi r3, r3, 1, 0		! extract sign bit
 | 
						|
	stfs f1, 4(sp)			! push fraction
 | 
						|
	stw r3, 0(sp)			! push integer = zero with sign
 | 
						|
	blr
 | 
						|
 | 
						|
	! f1 is an integer without fraction (or infinity or NaN).
 | 
						|
	! Unless NaN, then fraction is zero with same sign.
 | 
						|
4:	fcmpu cr0, f1, f1
 | 
						|
	bun cr0, 5f
 | 
						|
	extlwi r3, r3, 1, 0		! extract sign bit
 | 
						|
	stw r3, 4(sp)			! push fraction = zero with sign
 | 
						|
	stfs f1, 0(sp)			! push integer
 | 
						|
	blr
 | 
						|
 | 
						|
	! f1 is NaN, so both fraction and integer are NaN.
 | 
						|
5:	fmr f2, f1
 | 
						|
	b 2b
 |