3 ; [sign] 1.[23bits] E[8bits(n-127)]
5 ; SEEEEEEE Emmmmmmm mmmmmmmm mmmmmmmm
12 ; Special values (xxx != 0):
15 ; [HL+3] [HL+2] [HL+1] [HL+0]
16 ; s1111111 10000000 00000000 00000000 infinity
17 ; s1111111 1xxxxxxx xxxxxxxx xxxxxxxx NaN
18 ; s0000000 00000000 00000000 00000000 zero
19 ; s0000000 0xxxxxxx xxxxxxxx xxxxxxxx denormals
21 ; Note that CMPtype is "signed char" for rl78
30 ; __int_isnan [HL] -> Z if NaN
31 ; __int_iszero [HL] -> Z if zero
33 START_FUNC __int_isinf
34 ;; [HL] points to value, returns Z if it's #Inf
43 ret ; return NZ if not NaN
52 #define A_SIGN [hl+0] /* byte */
53 #define A_EXP [hl+2] /* word */
54 #define A_FRAC_L [hl+4] /* word */
55 #define A_FRAC_LH [hl+5] /* byte */
56 #define A_FRAC_H [hl+6] /* word or byte */
57 #define A_FRAC_HH [hl+7] /* byte */
61 #define B_FRAC_L [hl+12]
62 #define B_FRAC_LH [hl+13]
63 #define B_FRAC_H [hl+14]
64 #define B_FRAC_HH [hl+15]
66 START_FUNC _int_unpack_sf
67 ;; convert 32-bit SFmode [DE] to 6-byte struct [HL] ("A")
76 movw bc, ax ; remember if the exponent is all zeros
77 subw ax, #127 ; exponent is now non-biased
85 cmp0 c ; if the exp is all zeros, it's denormal
106 END_FUNC _int_unpack_sf
116 ;; Note - we cannot just change the sign of B on the stack and
117 ;; then fall through into __addsf3. The stack'ed value may be
118 ;; used again (it was created by our caller after all). Instead
119 ;; we have to allocate some stack space of our own, copy A and B,
120 ;; change the sign of B, call __addsf3, release the allocated stack
142 ;; if (isnan(a)) return a
155 1: ;; if (isnan (b)) return b;
175 ;; if (isinf (b) && a->sign != b->sign) return NaN
193 3: ;; if (isinf (b)) return b;
223 4: ;; if (iszero (a)) return b;
230 ; Normalize the two numbers relative to each other. At this point,
231 ; we need the numbers converted to their "unpacked" format.
233 subw sp, #16 ; Save room for two unpacked values.
239 call $!_int_unpack_sf
246 call $!_int_unpack_sf
251 ;; diff = a.exponent - b.exponent
252 movw ax, B_EXP ; sign/exponent word
254 movw ax, A_EXP ; sign/exponent word
256 subw ax, bc ; a = a.exp - b.exp
257 movw de, ax ; d = sdiff
259 ;; if (diff < 0) diff = -diff
265 ;; if (diff >= 23) zero the smaller one
267 bc $.L661 ; if a < 23 goto 661
269 ;; zero out the smaller one
272 bt a.7, $1f ; if sdiff < 0 (a_exp < b_exp) goto 1f
290 ;; shift the smaller one so they have the same exponents
294 cmpw ax, #0 ; sdiff > 0
295 bnh $1f ; if (sdiff <= 0) goto 1f
298 incw B_EXP ; because it's [HL+byte]
316 incw A_EXP ; because it's [HL+byte]
331 5: ;; At this point, A and B have the same exponent.
337 ;; Same sign, just add.
350 1: ;; Signs differ - A has A_SIGN still.
353 ;; A is negative, do B-A
366 ;; B is negative, do A-B
378 ;; A is still A_FRAC_HH
381 ;; subtraction was positive
387 ;; subtraction was negative
391 ;; This negates A_FRAC
393 xor a, #0xff ; XOR doesn't mess with carry
394 add a, #1 ; INC doesn't set the carry
410 ;; Renormalize the subtraction
418 ;; Mantissa is not zero, left shift until the MSB is in the
436 ;; normalize A and pack it
441 ;; overflow in the mantissa; adjust
454 call $!__rl78_int_pack_a_r8
460 START_FUNC __rl78_int_pack_a_r8
463 addw ax, #126 ; not 127, we want the "bt/bf" test to check for denormals
483 incw ax ; now it's as if we added 127
488 ;; store #Inf instead
497 bf a.7, $1f ; note AX has EXP at top of loop
498 ;; underflow, denormal?
513 ;; undo the rounding-bit-shift
523 ;; If the rounding set the bit beyond the end of the fraction, increment the exponent.
566 END_FUNC __rl78_int_pack_a_r8
570 ;; if (isnan(a)) return a
583 xor a, b ; sign is always a ^ b
587 ;; if (isnan (b)) return b;
600 xor a, b ; sign is always a ^ b
604 ;; if (isinf (a)) return (b==0) ? nan : a
617 movw r8, #0x0001 ; return NaN
622 ;; if (isinf (b)) return (a==0) ? nan : b
635 movw r8, #0x0001 ; return NaN
652 ;; at this point, we're doing the multiplication.
654 subw sp, #16 ; save room for two unpacked values
660 call $!_int_unpack_sf
667 call $!_int_unpack_sf
672 ;; multiply SI a.FRAC * SI b.FRAC to DI r8
691 call !!___muldi3 ; MTMPa * MTMPb -> R8..R15
697 ;; add the exponents together
700 movw bc, ax ; exponent in BC
702 ;; now, re-normalize the DI value in R8..R15 to have the
703 ;; MSB in the "right" place, adjusting BC as we shift it.
705 ;; The value will normally be in this range:
707 ;; 0001_0000_0000_0000
708 ;; 0003_ffff_fc00_0001
710 ;; so to speed it up, we normalize to:
711 ;; 0001_xxxx_xxxx_xxxx
712 ;; then extract the bytes we want (r11-r14)
722 ;; shift right, inc exponent
735 ;; we don't care about r8/r9/r10 if we're shifting this way
742 ;; shift left, dec exponent
758 ;; at this point, FRAC is in R11..R14 and EXP is in BC
775 call $!__rl78_int_pack_a_r8
784 ;; if (isnan(a)) return a
797 xor a, b ; sign is always a ^ b
801 ;; if (isnan (b)) return b;
814 xor a, b ; sign is always a ^ b
819 ;; if (isinf (a)) return isinf(b) ? nan : a
833 movw r8, #0x0001 ; return NaN
839 ;; if (iszero (a)) return iszero(b) ? nan : a
855 ;; if (isinf (b)) return 0
874 ;; if (iszero (b)) return Inf
893 ;; at this point, we're doing the division. Normalized
894 ;; mantissas look like:
897 ;; 01.xx.xx.xx.00.00.00.00
899 ;; to get approx 00.80.00.00.00 to 01.ff.ff.ff.00
902 subw sp, #16 ; save room for two unpacked values
908 call $!_int_unpack_sf
915 call $!_int_unpack_sf
920 ;; divide DI a.FRAC / SI b.FRAC to DI r8
939 call !!___divdi3 ; MTMPa / MTMPb -> R8..R15
945 ;; subtract the exponents A - B
948 movw bc, ax ; exponent in BC
950 ;; now, re-normalize the DI value in R8..R15 to have the
951 ;; MSB in the "right" place, adjusting BC as we shift it.
953 ;; The value will normally be in this range:
955 ;; 0000_0000_8000_0000
956 ;; 0000_0001_ffff_ff00
958 ;; so to speed it up, we normalize to:
959 ;; 0000_0001_xxxx_xxxx
960 ;; then extract the bytes we want (r9-r12)
970 ;; shift right, inc exponent
996 ;; the previous loop leaves r15.r13 zero
1000 ;; shift left, dec exponent
1010 ;; don't need to do r14
1014 ;; at this point, FRAC is in R8..R11 and EXP is in BC
1031 call $!__rl78_int_pack_a_r8