^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) | do_func.sa 3.4 2/18/91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | Do_func performs the unimplemented operation. The operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | to be performed is determined from the lower 7 bits of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | extension word (except in the case of fmovecr and fsincos).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | The opcode and tag bits form an index into a jump table in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | tbldo.sa. Cases of zero, infinity and NaN are handled in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | do_func by forcing the default result. Normalized and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | denormalized (there are no unnormalized numbers at this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) | point) are passed onto the emulation code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) | CMDREG1B and STAG are extracted from the fsave frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) | and combined to form the table index. The function called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) | will start with a0 pointing to the ETEMP operand. Dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | functions can find FPTEMP at -12(a0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | Called functions return their result in fp0. Sincos returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | sin(x) in fp0 and cos(x) in fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) | Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) | file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) DO_FUNC: |idnt 2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) |section 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) |xref t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) |xref t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) |xref t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) |xref t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) |xref dst_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) |xref src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) |xref nrm_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) |xref sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) |xref tblpre
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) |xref slognp1,slogn,slog10,slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) |xref slognd,slog10d,slog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) |xref smod,srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) |xref sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) |xref smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) PONE: .long 0x3fff0000,0x80000000,0x00000000 |+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MONE: .long 0xbfff0000,0x80000000,0x00000000 |-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) PZERO: .long 0x00000000,0x00000000,0x00000000 |+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MZERO: .long 0x80000000,0x00000000,0x00000000 |-0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) PINF: .long 0x7fff0000,0x00000000,0x00000000 |+inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MINF: .long 0xffff0000,0x00000000,0x00000000 |-inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) QNAN: .long 0x7fff0000,0xffffffff,0xffffffff |non-signaling nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) PPIBY2: .long 0x3FFF0000,0xC90FDAA2,0x2168C235 |+PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MPIBY2: .long 0xbFFF0000,0xC90FDAA2,0x2168C235 |-PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .global do_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) do_func:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) clrb CU_ONLY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) | Check for fmovecr. It does not follow the format of fp gen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) | unimplemented instructions. The test is on the upper 6 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) | if they are $17, the inst is fmovecr. Call entry smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) | directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) cmpil #0x17,%d0 |if op class and size fields are $17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) | ;it is FMOVECR; if not, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) bnes not_fmovecr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) jmp smovcr |fmovecr; jmp directly to emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) not_fmovecr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) movew CMDREG1B(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) andl #0x7F,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) cmpil #0x38,%d0 |if the extension is >= $38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) bge serror |it is illegal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bfextu STAG(%a6){#0:#3},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) lsll #3,%d0 |make room for STAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) addl %d1,%d0 |combine for final index into table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) leal tblpre,%a1 |start of monster jump table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) movel (%a1,%d0.w*4),%a1 |real target address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) leal ETEMP(%a6),%a0 |a0 is pointer to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) movel USER_FPCR(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) andl #0xFF,%d1 | discard all but rounding mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) fmovel #0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) jmp (%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) | ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .global serror
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) serror:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) st STORE_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) | These routines load forced values into fp0. They are called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) | by index into tbldo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) | Load a signed zero to fp0 and set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .global snzrinx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) snzrinx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bnes ld_mzinx |if negative, branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) bsr ld_pzero |bsr so we can return and set inx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bra t_inx2 |now, set the inx for the next inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ld_mzinx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bsr ld_mzero |if neg, load neg zero, return here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bra t_inx2 |now, set the inx for the next inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) | Load a signed zero to fp0; do not set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .global szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) bne ld_mzero |if neg, load neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bra ld_pzero |load positive zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) | Load a signed infinity to fp0; do not set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .global sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) btstb #sign_bit,LOCAL_EX(%a0) |get sign of source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) bne ld_minf |if negative branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bra ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) | Load a signed one to fp0; do not set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .global sone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) sone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) btstb #sign_bit,LOCAL_EX(%a0) |check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bne ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bra ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) | Load a signed pi/2 to fp0; do not set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .global spi_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) spi_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) btstb #sign_bit,LOCAL_EX(%a0) |check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bne ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bra ld_ppi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) | Load either a +0 or +inf for plus/minus operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .global szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) szr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) btstb #sign_bit,LOCAL_EX(%a0) |check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bne ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) bra ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) | Result is either an operr or +inf for plus/minus operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) | [Used by slogn, slognp1, slog10, and slog2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .global sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) sopr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) btstb #sign_bit,LOCAL_EX(%a0) |check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) bne t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) bra ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) | FLOGNP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .global sslognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sslognp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fmovemx (%a0),%fp0-%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) fcmpb #-1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) fbgt slognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) fbeq t_dz2 |if = -1, divide by zero exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) fmovel #0,%FPSR |clr N flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) bra t_operr |take care of operands < -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) | FETOXM1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .global setoxm1i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) setoxm1i:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) btstb #sign_bit,LOCAL_EX(%a0) |check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) bne ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bra ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) | FLOGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) | Test for 1.0 as an input argument, returning +zero. Also check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) | the sign and return operr if negative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .global sslogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) sslogn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bne t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) bne slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cmpil #0x80000000,LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bne slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) tstl LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) bne slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) fmovex PZERO,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .global sslognd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) sslognd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) beq slognd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) bra t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) | FLOG10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .global sslog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) sslog10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bne t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) bne slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) cmpil #0x80000000,LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) bne slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) tstl LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) bne slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) fmovex PZERO,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .global sslog10d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) sslog10d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) beq slog10d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bra t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) | FLOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .global sslog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) sslog2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bne t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) cmpiw #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) bne slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) cmpil #0x80000000,LOCAL_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bne slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) tstl LOCAL_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) bne slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) fmovex PZERO,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .global sslog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) sslog2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) btstb #sign_bit,LOCAL_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) beq slog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) bra t_operr |take care of operands < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) | FMOD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pmodt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) | ;$21 fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) | ;dtag,stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .long smod | 00,00 norm,norm = normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .long smod_oper | 00,01 norm,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .long smod_fpn | 00,10 norm,inf = fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .long smod_snan | 00,11 norm,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .long smod_zro | 01,00 zero,norm = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .long smod_oper | 01,01 zero,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .long smod_zro | 01,10 zero,inf = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .long smod_snan | 01,11 zero,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .long smod_oper | 10,00 inf,norm = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .long smod_oper | 10,01 inf,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .long smod_oper | 10,10 inf,inf = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .long smod_snan | 10,11 inf,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .long smod_dnan | 11,00 nan,norm = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .long smod_dnan | 11,01 nan,zero = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .long smod_dnan | 11,10 nan,inf = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .long smod_dnan | 11,11 nan,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .global pmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pmod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) clrb FPSR_QBYTE(%a6) | clear quotient field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bfextu STAG(%a6){#0:#3},%d0 |stag = d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) bfextu DTAG(%a6){#0:#3},%d1 |dtag = d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) | Alias extended denorms to norms for the jump table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) bclrl #2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) bclrl #2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) lslb #2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) orb %d0,%d1 |d1{3:2} = dtag, d1{1:0} = stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) | ;Tag values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) | ;00 = norm or denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) | ;01 = zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) | ;10 = inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) | ;11 = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) lea pmodt,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) movel (%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) jmp (%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) smod_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) bra src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) smod_dnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bra dst_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) smod_oper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) smod_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) moveb ETEMP(%a6),%d1 |get sign of src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) moveb FPTEMP(%a6),%d0 |get sign of dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) eorb %d0,%d1 |get exor of sign bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) btstl #7,%d1 |test for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) beqs smod_zsn |if clr, do not set sign big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) smod_zsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) btstl #7,%d0 |test if + or -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) beq ld_pzero |if pos then load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) bra ld_mzero |else neg load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) smod_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) moveb ETEMP(%a6),%d1 |get sign of src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) moveb FPTEMP(%a6),%d0 |get sign of dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) eorb %d0,%d1 |get exor of sign bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) btstl #7,%d1 |test for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) beqs smod_fsn |if clr, do not set sign big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) smod_fsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) tstb DTAG(%a6) |filter out denormal destination case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) bpls smod_nrm |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) leal FPTEMP(%a6),%a0 |a0<- addr(FPTEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bra t_resdnrm |force UNFL(but exact) result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) smod_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) fmovex FPTEMP(%a6),%fp0 |return dest to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) | FREM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) premt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) | ;$25 frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) | ;dtag,stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .long srem | 00,00 norm,norm = normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .long srem_oper | 00,01 norm,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .long srem_fpn | 00,10 norm,inf = fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .long srem_snan | 00,11 norm,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .long srem_zro | 01,00 zero,norm = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .long srem_oper | 01,01 zero,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .long srem_zro | 01,10 zero,inf = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .long srem_snan | 01,11 zero,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .long srem_oper | 10,00 inf,norm = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .long srem_oper | 10,01 inf,zero = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .long srem_oper | 10,10 inf,inf = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .long srem_snan | 10,11 inf,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .long srem_dnan | 11,00 nan,norm = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .long srem_dnan | 11,01 nan,zero = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .long srem_dnan | 11,10 nan,inf = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .long srem_dnan | 11,11 nan,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .global prem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) prem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) clrb FPSR_QBYTE(%a6) |clear quotient field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bfextu STAG(%a6){#0:#3},%d0 |stag = d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) bfextu DTAG(%a6){#0:#3},%d1 |dtag = d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) | Alias extended denorms to norms for the jump table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bclr #2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) bclr #2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) lslb #2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) orb %d0,%d1 |d1{3:2} = dtag, d1{1:0} = stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) | ;Tag values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) | ;00 = norm or denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) | ;01 = zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) | ;10 = inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) | ;11 = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) lea premt,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) movel (%a1,%d1.w*4),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) jmp (%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) srem_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) bra src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) srem_dnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) bra dst_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) srem_oper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) srem_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) moveb ETEMP(%a6),%d1 |get sign of src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) moveb FPTEMP(%a6),%d0 |get sign of dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) eorb %d0,%d1 |get exor of sign bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) btstl #7,%d1 |test for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) beqs srem_zsn |if clr, do not set sign big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) srem_zsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) btstl #7,%d0 |test if + or -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) beq ld_pzero |if pos then load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) bra ld_mzero |else neg load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) srem_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) moveb ETEMP(%a6),%d1 |get sign of src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) moveb FPTEMP(%a6),%d0 |get sign of dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) eorb %d0,%d1 |get exor of sign bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) btstl #7,%d1 |test for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) beqs srem_fsn |if clr, do not set sign big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) bsetb #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) srem_fsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) tstb DTAG(%a6) |filter out denormal destination case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) bpls srem_nrm |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) leal FPTEMP(%a6),%a0 |a0<- addr(FPTEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) bra t_resdnrm |force UNFL(but exact) result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) srem_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) fmovex FPTEMP(%a6),%fp0 |return dest to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) | FSCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pscalet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) | ;$26 fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) | ;dtag,stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .long sscale | 00,00 norm,norm = result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .long sscale | 00,01 norm,zero = fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .long scl_opr | 00,10 norm,inf = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .long scl_snan | 00,11 norm,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .long scl_zro | 01,00 zero,norm = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .long scl_zro | 01,01 zero,zero = +-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .long scl_opr | 01,10 zero,inf = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .long scl_snan | 01,11 zero,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .long scl_inf | 10,00 inf,norm = +-inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .long scl_inf | 10,01 inf,zero = +-inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .long scl_opr | 10,10 inf,inf = nan with operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .long scl_snan | 10,11 inf,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .long scl_dnan | 11,00 nan,norm = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .long scl_dnan | 11,01 nan,zero = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .long scl_dnan | 11,10 nan,inf = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .long scl_dnan | 11,11 nan,nan = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .global pscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bfextu STAG(%a6){#0:#3},%d0 |stag in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) bfextu DTAG(%a6){#0:#3},%d1 |dtag in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) bclrl #2,%d0 |alias denorm into norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) bclrl #2,%d1 |alias denorm into norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) lslb #2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) orb %d0,%d1 |d1{4:2} = dtag, d1{1:0} = stag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) | ;dtag values stag values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) | ;000 = norm 00 = norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) | ;001 = zero 01 = zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) | ;010 = inf 10 = inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) | ;011 = nan 11 = nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) | ;100 = dnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) leal pscalet,%a1 |load start of jump table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) movel (%a1,%d1.w*4),%a1 |load a1 with label depending on tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) jmp (%a1) |go to the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) scl_opr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) scl_dnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) bra dst_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) scl_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) btstb #sign_bit,FPTEMP_EX(%a6) |test if + or -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) beq ld_pzero |if pos then load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bra ld_mzero |if neg then load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) scl_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) btstb #sign_bit,FPTEMP_EX(%a6) |test if + or -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) beq ld_pinf |if pos then load +inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) bra ld_minf |else neg load -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) scl_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) bra src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) | FSINCOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .global ssincosz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ssincosz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) btstb #sign_bit,ETEMP(%a6) |get sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) beqs sincosp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) fmovex MZERO,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bras sincoscom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sincosp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) fmovex PZERO,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) sincoscom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) fmovemx PONE,%fp1-%fp1 |do not allow FPSR to be affected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) bra sto_cos |store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .global ssincosi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ssincosi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fmovex QNAN,%fp1 |load NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) bsr sto_cos |store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) fmovex QNAN,%fp0 |load NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .global ssincosnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ssincosnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) movel ETEMP_EX(%a6),FP_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) movel ETEMP_HI(%a6),FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) movel ETEMP_LO(%a6),FP_SCR1+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) bsetb #signan_bit,FP_SCR1+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) fmovemx FP_SCR1(%a6),%fp1-%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) bsr sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) bra src_nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) | This code forces default values for the zero, inf, and nan cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) | in the transcendentals code. The CC bits must be set in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) | stacked FPSR to be correctly reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) |**Returns +PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .global ld_ppi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ld_ppi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) fmovex PPIBY2,%fp0 |load +pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) bra t_inx2 |set inex2 exc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) |**Returns -PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .global ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ld_mpi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) fmovex MPIBY2,%fp0 |load -pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) orl #neg_mask,USER_FPSR(%a6) |set N bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) bra t_inx2 |set inex2 exc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) |**Returns +inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .global ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ld_pinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) fmovex PINF,%fp0 |load +inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) orl #inf_mask,USER_FPSR(%a6) |set I bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) |**Returns -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .global ld_minf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ld_minf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) fmovex MINF,%fp0 |load -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) orl #neg_mask+inf_mask,USER_FPSR(%a6) |set N and I bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) |**Returns +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .global ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ld_pone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) fmovex PONE,%fp0 |load +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) |**Returns -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .global ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ld_mone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) fmovex MONE,%fp0 |load -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) orl #neg_mask,USER_FPSR(%a6) |set N bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) |**Returns +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .global ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ld_pzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) fmovex PZERO,%fp0 |load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) orl #z_mask,USER_FPSR(%a6) |set Z bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) |**Returns -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .global ld_mzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ld_mzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) fmovex MZERO,%fp0 |load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) |end