summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S')
-rw-r--r--c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S678
1 files changed, 0 insertions, 678 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S b/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S
deleted file mode 100644
index a8a114b734..0000000000
--- a/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S
+++ /dev/null
@@ -1,678 +0,0 @@
-#include "fpsp-namespace.h"
-//
-//
-// get_op.sa 3.6 5/19/92
-//
-// get_op.sa 3.5 4/26/91
-//
-// Description: This routine is called by the unsupported format/data
-// type exception handler ('unsupp' - vector 55) and the unimplemented
-// instruction exception handler ('unimp' - vector 11). 'get_op'
-// determines the opclass (0, 2, or 3) and branches to the
-// opclass handler routine. See 68881/2 User's Manual table 4-11
-// for a description of the opclasses.
-//
-// For UNSUPPORTED data/format (exception vector 55) and for
-// UNIMPLEMENTED instructions (exception vector 11) the following
-// applies:
-//
-// - For unnormalized numbers (opclass 0, 2, or 3) the
-// number(s) is normalized and the operand type tag is updated.
-//
-// - For a packed number (opclass 2) the number is unpacked and the
-// operand type tag is updated.
-//
-// - For denormalized numbers (opclass 0 or 2) the number(s) is not
-// changed but passed to the next module. The next module for
-// unimp is do_func, the next module for unsupp is res_func.
-//
-// For UNSUPPORTED data/format (exception vector 55) only the
-// following applies:
-//
-// - If there is a move out with a packed number (opclass 3) the
-// number is packed and written to user memory. For the other
-// opclasses the number(s) are written back to the fsave stack
-// and the instruction is then restored back into the '040. The
-// '040 is then able to complete the instruction.
-//
-// For example:
-// fadd.x fpm,fpn where the fpm contains an unnormalized number.
-// The '040 takes an unsupported data trap and gets to this
-// routine. The number is normalized, put back on the stack and
-// then an frestore is done to restore the instruction back into
-// the '040. The '040 then re-executes the fadd.x fpm,fpn with
-// a normalized number in the source and the instruction is
-// successful.
-//
-// Next consider if in the process of normalizing the un-
-// normalized number it becomes a denormalized number. The
-// routine which converts the unnorm to a norm (called mk_norm)
-// detects this and tags the number as a denorm. The routine
-// res_func sees the denorm tag and converts the denorm to a
-// norm. The instruction is then restored back into the '040
-// which re_executes the instruction.
-//
-//
-// Copyright (C) Motorola, Inc. 1990
-// All Rights Reserved
-//
-// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
-// The copyright notice above does not evidence any
-// actual or intended publication of such source code.
-
-GET_OP: //idnt 2,1 | Motorola 040 Floating Point Software Package
-
- |section 8
-
-#include "fpsp.defs"
-
- .global PIRN,PIRZRM,PIRP
- .global SMALRN,SMALRZRM,SMALRP
- .global BIGRN,BIGRZRM,BIGRP
-
-PIRN:
- .long 0x40000000,0xc90fdaa2,0x2168c235 //pi
-PIRZRM:
- .long 0x40000000,0xc90fdaa2,0x2168c234 //pi
-PIRP:
- .long 0x40000000,0xc90fdaa2,0x2168c235 //pi
-
-//round to nearest
-SMALRN:
- .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2)
- .long 0x40000000,0xadf85458,0xa2bb4a9a //e
- .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e)
- .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
- .long 0x00000000,0x00000000,0x00000000 //0.0
-// round to zero;round to negative infinity
-SMALRZRM:
- .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2)
- .long 0x40000000,0xadf85458,0xa2bb4a9a //e
- .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb //log2(e)
- .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
- .long 0x00000000,0x00000000,0x00000000 //0.0
-// round to positive infinity
-SMALRP:
- .long 0x3ffd0000,0x9a209a84,0xfbcff799 //log10(2)
- .long 0x40000000,0xadf85458,0xa2bb4a9b //e
- .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e)
- .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
- .long 0x00000000,0x00000000,0x00000000 //0.0
-
-//round to nearest
-BIGRN:
- .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2)
- .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10)
- .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
-
- .global PTENRN
-PTENRN:
- .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
- .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
- .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
- .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
- .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
- .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32
- .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64
- .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128
- .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256
- .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512
- .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024
- .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048
- .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096
-//round to minus infinity
-BIGRZRM:
- .long 0x3ffe0000,0xb17217f7,0xd1cf79ab //ln(2)
- .long 0x40000000,0x935d8ddd,0xaaa8ac16 //ln(10)
- .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
-
- .global PTENRM
-PTENRM:
- .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
- .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
- .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
- .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
- .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
- .long 0x40690000,0x9DC5ADA8,0x2B70B59D //10 ^ 32
- .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64
- .long 0x41A80000,0x93BA47C9,0x80E98CDF //10 ^ 128
- .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D //10 ^ 256
- .long 0x46A30000,0xE319A0AE,0xA60E91C6 //10 ^ 512
- .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024
- .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048
- .long 0x75250000,0xC4605202,0x8A20979A //10 ^ 4096
-//round to positive infinity
-BIGRP:
- .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2)
- .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10)
- .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
-
- .global PTENRP
-PTENRP:
- .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
- .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
- .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
- .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
- .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
- .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32
- .long 0x40D30000,0xC2781F49,0xFFCFA6D6 //10 ^ 64
- .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128
- .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256
- .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512
- .long 0x4D480000,0xC9767586,0x81750C18 //10 ^ 1024
- .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 //10 ^ 2048
- .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096
-
- |xref nrm_zero
- |xref decbin
- |xref round
-
- .global get_op
- .global uns_getop
- .global uni_getop
-get_op:
- clrb DY_MO_FLG(%a6)
- tstb UFLG_TMP(%a6) //test flag for unsupp/unimp state
- beq uni_getop
-
-uns_getop:
- btstb #direction_bit,CMDREG1B(%a6)
- bne opclass3 //branch if a fmove out (any kind)
- btstb #6,CMDREG1B(%a6)
- beqs uns_notpacked
-
- bfextu CMDREG1B(%a6){#3:#3},%d0
- cmpb #3,%d0
- beq pack_source //check for a packed src op, branch if so
-uns_notpacked:
- bsr chk_dy_mo //set the dyadic/monadic flag
- tstb DY_MO_FLG(%a6)
- beqs src_op_ck //if monadic, go check src op
-// ;else, check dst op (fall through)
-
- btstb #7,DTAG(%a6)
- beqs src_op_ck //if dst op is norm, check src op
- bras dst_ex_dnrm //else, handle destination unnorm/dnrm
-
-uni_getop:
- bfextu CMDREG1B(%a6){#0:#6},%d0 //get opclass and src fields
- cmpil #0x17,%d0 //if op class and size fields are $17,
-// ;it is FMOVECR; if not, continue
-//
-// If the instruction is fmovecr, exit get_op. It is handled
-// in do_func and smovecr.sa.
-//
- bne not_fmovecr //handle fmovecr as an unimplemented inst
- rts
-
-not_fmovecr:
- btstb #E1,E_BYTE(%a6) //if set, there is a packed operand
- bne pack_source //check for packed src op, branch if so
-
-// The following lines of are coded to optimize on normalized operands
- moveb STAG(%a6),%d0
- orb DTAG(%a6),%d0 //check if either of STAG/DTAG msb set
- bmis dest_op_ck //if so, some op needs to be fixed
- rts
-
-dest_op_ck:
- btstb #7,DTAG(%a6) //check for unsupported data types in
- beqs src_op_ck //the destination, if not, check src op
- bsr chk_dy_mo //set dyadic/monadic flag
- tstb DY_MO_FLG(%a6) //
- beqs src_op_ck //if monadic, check src op
-//
-// At this point, destination has an extended denorm or unnorm.
-//
-dst_ex_dnrm:
- movew FPTEMP_EX(%a6),%d0 //get destination exponent
- andiw #0x7fff,%d0 //mask sign, check if exp = 0000
- beqs src_op_ck //if denorm then check source op.
-// ;denorms are taken care of in res_func
-// ;(unsupp) or do_func (unimp)
-// ;else unnorm fall through
- leal FPTEMP(%a6),%a0 //point a0 to dop - used in mk_norm
- bsr mk_norm //go normalize - mk_norm returns:
-// ;L_SCR1{7:5} = operand tag
-// ; (000 = norm, 100 = denorm)
-// ;L_SCR1{4} = fpte15 or ete15
-// ; 0 = exp > $3fff
-// ; 1 = exp <= $3fff
-// ;and puts the normalized num back
-// ;on the fsave stack
-//
- moveb L_SCR1(%a6),DTAG(%a6) //write the new tag & fpte15
-// ;to the fsave stack and fall
-// ;through to check source operand
-//
-src_op_ck:
- btstb #7,STAG(%a6)
- beq end_getop //check for unsupported data types on the
-// ;source operand
- btstb #5,STAG(%a6)
- bnes src_sd_dnrm //if bit 5 set, handle sgl/dbl denorms
-//
-// At this point only unnorms or extended denorms are possible.
-//
-src_ex_dnrm:
- movew ETEMP_EX(%a6),%d0 //get source exponent
- andiw #0x7fff,%d0 //mask sign, check if exp = 0000
- beq end_getop //if denorm then exit, denorms are
-// ;handled in do_func
- leal ETEMP(%a6),%a0 //point a0 to sop - used in mk_norm
- bsr mk_norm //go normalize - mk_norm returns:
-// ;L_SCR1{7:5} = operand tag
-// ; (000 = norm, 100 = denorm)
-// ;L_SCR1{4} = fpte15 or ete15
-// ; 0 = exp > $3fff
-// ; 1 = exp <= $3fff
-// ;and puts the normalized num back
-// ;on the fsave stack
-//
- moveb L_SCR1(%a6),STAG(%a6) //write the new tag & ete15
- rts //end_getop
-
-//
-// At this point, only single or double denorms are possible.
-// If the inst is not fmove, normalize the source. If it is,
-// do nothing to the input.
-//
-src_sd_dnrm:
- btstb #4,CMDREG1B(%a6) //differentiate between sgl/dbl denorm
- bnes is_double
-is_single:
- movew #0x3f81,%d1 //write bias for sgl denorm
- bras common //goto the common code
-is_double:
- movew #0x3c01,%d1 //write the bias for a dbl denorm
-common:
- btstb #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa
- beqs pos
- bset #15,%d1 //set sign bit because it is negative
-pos:
- movew %d1,ETEMP_EX(%a6)
-// ;put exponent on stack
-
- movew CMDREG1B(%a6),%d1
- andw #0xe3ff,%d1 //clear out source specifier
- orw #0x0800,%d1 //set source specifier to extended prec
- movew %d1,CMDREG1B(%a6) //write back to the command word in stack
-// ;this is needed to fix unsupp data stack
- leal ETEMP(%a6),%a0 //point a0 to sop
-
- bsr mk_norm //convert sgl/dbl denorm to norm
- moveb L_SCR1(%a6),STAG(%a6) //put tag into source tag reg - d0
- rts //end_getop
-//
-// At this point, the source is definitely packed, whether
-// instruction is dyadic or monadic is still unknown
-//
-pack_source:
- movel FPTEMP_LO(%a6),ETEMP(%a6) //write ms part of packed
-// ;number to etemp slot
- bsr chk_dy_mo //set dyadic/monadic flag
- bsr unpack
-
- tstb DY_MO_FLG(%a6)
- beqs end_getop //if monadic, exit
-// ;else, fix FPTEMP
-pack_dya:
- bfextu CMDREG1B(%a6){#6:#3},%d0 //extract dest fp reg
- movel #7,%d1
- subl %d0,%d1
- clrl %d0
- bsetl %d1,%d0 //set up d0 as a dynamic register mask
- fmovemx %d0,FPTEMP(%a6) //write to FPTEMP
-
- btstb #7,DTAG(%a6) //check dest tag for unnorm or denorm
- bne dst_ex_dnrm //else, handle the unnorm or ext denorm
-//
-// Dest is not denormalized. Check for norm, and set fpte15
-// accordingly.
-//
- moveb DTAG(%a6),%d0
- andib #0xf0,%d0 //strip to only dtag:fpte15
- tstb %d0 //check for normalized value
- bnes end_getop //if inf/nan/zero leave get_op
- movew FPTEMP_EX(%a6),%d0
- andiw #0x7fff,%d0
- cmpiw #0x3fff,%d0 //check if fpte15 needs setting
- bges end_getop //if >= $3fff, leave fpte15=0
- orb #0x10,DTAG(%a6)
- bras end_getop
-
-//
-// At this point, it is either an fmoveout packed, unnorm or denorm
-//
-opclass3:
- clrb DY_MO_FLG(%a6) //set dyadic/monadic flag to monadic
- bfextu CMDREG1B(%a6){#4:#2},%d0
- cmpib #3,%d0
- bne src_ex_dnrm //if not equal, must be unnorm or denorm
-// ;else it is a packed move out
-// ;exit
-end_getop:
- rts
-
-//
-// Sets the DY_MO_FLG correctly. This is used only on if it is an
-// unsupported data type exception. Set if dyadic.
-//
-chk_dy_mo:
- movew CMDREG1B(%a6),%d0
- btstl #5,%d0 //testing extension command word
- beqs set_mon //if bit 5 = 0 then monadic
- btstl #4,%d0 //know that bit 5 = 1
- beqs set_dya //if bit 4 = 0 then dyadic
- andiw #0x007f,%d0 //get rid of all but extension bits {6:0}
- cmpiw #0x0038,%d0 //if extension = $38 then fcmp (dyadic)
- bnes set_mon
-set_dya:
- st DY_MO_FLG(%a6) //set the inst flag type to dyadic
- rts
-set_mon:
- clrb DY_MO_FLG(%a6) //set the inst flag type to monadic
- rts
-//
-// MK_NORM
-//
-// Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
-// exception if denorm.
-//
-// CASE opclass 0x0 unsupp
-// mk_norm till msb set
-// set tag = norm
-//
-// CASE opclass 0x0 unimp
-// mk_norm till msb set or exp = 0
-// if integer bit = 0
-// tag = denorm
-// else
-// tag = norm
-//
-// CASE opclass 011 unsupp
-// mk_norm till msb set or exp = 0
-// if integer bit = 0
-// tag = denorm
-// set unfl_nmcexe = 1
-// else
-// tag = norm
-//
-// if exp <= $3fff
-// set ete15 or fpte15 = 1
-// else set ete15 or fpte15 = 0
-
-// input:
-// a0 = points to operand to be normalized
-// output:
-// L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
-// L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
-// the normalized operand is placed back on the fsave stack
-mk_norm:
- clrl L_SCR1(%a6)
- bclrb #sign_bit,LOCAL_EX(%a0)
- sne LOCAL_SGN(%a0) //transform into internal extended format
-
- cmpib #0x2c,1+EXC_VEC(%a6) //check if unimp
- bnes uns_data //branch if unsupp
- bsr uni_inst //call if unimp (opclass 0x0)
- bras reload
-uns_data:
- btstb #direction_bit,CMDREG1B(%a6) //check transfer direction
- bnes bit_set //branch if set (opclass 011)
- bsr uns_opx //call if opclass 0x0
- bras reload
-bit_set:
- bsr uns_op3 //opclass 011
-reload:
- cmpw #0x3fff,LOCAL_EX(%a0) //if exp > $3fff
- bgts end_mk // fpte15/ete15 already set to 0
- bsetb #4,L_SCR1(%a6) //else set fpte15/ete15 to 1
-// ;calling routine actually sets the
-// ;value on the stack (along with the
-// ;tag), since this routine doesn't
-// ;know if it should set ete15 or fpte15
-// ;ie, it doesn't know if this is the
-// ;src op or dest op.
-end_mk:
- bfclr LOCAL_SGN(%a0){#0:#8}
- beqs end_mk_pos
- bsetb #sign_bit,LOCAL_EX(%a0) //convert back to IEEE format
-end_mk_pos:
- rts
-//
-// CASE opclass 011 unsupp
-//
-uns_op3:
- bsr nrm_zero //normalize till msb = 1 or exp = zero
- btstb #7,LOCAL_HI(%a0) //if msb = 1
- bnes no_unfl //then branch
-set_unfl:
- orw #dnrm_tag,L_SCR1(%a6) //set denorm tag
- bsetb #unfl_bit,FPSR_EXCEPT(%a6) //set unfl exception bit
-no_unfl:
- rts
-//
-// CASE opclass 0x0 unsupp
-//
-uns_opx:
- bsr nrm_zero //normalize the number
- btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set
- beqs uns_den //if clear then now have a denorm
-uns_nrm:
- orb #norm_tag,L_SCR1(%a6) //set tag to norm
- rts
-uns_den:
- orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm
- rts
-//
-// CASE opclass 0x0 unimp
-//
-uni_inst:
- bsr nrm_zero
- btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set
- beqs uni_den //if clear then now have a denorm
-uni_nrm:
- orb #norm_tag,L_SCR1(%a6) //set tag to norm
- rts
-uni_den:
- orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm
- rts
-
-//
-// Decimal to binary conversion
-//
-// Special cases of inf and NaNs are completed outside of decbin.
-// If the input is an snan, the snan bit is not set.
-//
-// input:
-// ETEMP(a6) - points to packed decimal string in memory
-// output:
-// fp0 - contains packed string converted to extended precision
-// ETEMP - same as fp0
-unpack:
- movew CMDREG1B(%a6),%d0 //examine command word, looking for fmove's
- andw #0x3b,%d0
- beq move_unpack //special handling for fmove: must set FPSR_CC
-
- movew ETEMP(%a6),%d0 //get word with inf information
- bfextu %d0{#20:#12},%d1 //get exponent into d1
- cmpiw #0x0fff,%d1 //test for inf or NaN
- bnes try_zero //if not equal, it is not special
- bfextu %d0{#17:#3},%d1 //get SE and y bits into d1
- cmpiw #7,%d1 //SE and y bits must be on for special
- bnes try_zero //if not on, it is not special
-//input is of the special cases of inf and NaN
- tstl ETEMP_HI(%a6) //check ms mantissa
- bnes fix_nan //if non-zero, it is a NaN
- tstl ETEMP_LO(%a6) //check ls mantissa
- bnes fix_nan //if non-zero, it is a NaN
- bra finish //special already on stack
-fix_nan:
- btstb #signan_bit,ETEMP_HI(%a6) //test for snan
- bne finish
- orl #snaniop_mask,USER_FPSR(%a6) //always set snan if it is so
- bra finish
-try_zero:
- movew ETEMP_EX+2(%a6),%d0 //get word 4
- andiw #0x000f,%d0 //clear all but last ni(y)bble
- tstw %d0 //check for zero.
- bne not_spec
- tstl ETEMP_HI(%a6) //check words 3 and 2
- bne not_spec
- tstl ETEMP_LO(%a6) //check words 1 and 0
- bne not_spec
- tstl ETEMP(%a6) //test sign of the zero
- bges pos_zero
- movel #0x80000000,ETEMP(%a6) //write neg zero to etemp
- clrl ETEMP_HI(%a6)
- clrl ETEMP_LO(%a6)
- bra finish
-pos_zero:
- clrl ETEMP(%a6)
- clrl ETEMP_HI(%a6)
- clrl ETEMP_LO(%a6)
- bra finish
-
-not_spec:
- fmovemx %fp0-%fp1,-(%a7) //save fp0 - decbin returns in it
- bsr decbin
- fmovex %fp0,ETEMP(%a6) //put the unpacked sop in the fsave stack
- fmovemx (%a7)+,%fp0-%fp1
- fmovel #0,%FPSR //clr fpsr from decbin
- bra finish
-
-//
-// Special handling for packed move in: Same results as all other
-// packed cases, but we must set the FPSR condition codes properly.
-//
-move_unpack:
- movew ETEMP(%a6),%d0 //get word with inf information
- bfextu %d0{#20:#12},%d1 //get exponent into d1
- cmpiw #0x0fff,%d1 //test for inf or NaN
- bnes mtry_zero //if not equal, it is not special
- bfextu %d0{#17:#3},%d1 //get SE and y bits into d1
- cmpiw #7,%d1 //SE and y bits must be on for special
- bnes mtry_zero //if not on, it is not special
-//input is of the special cases of inf and NaN
- tstl ETEMP_HI(%a6) //check ms mantissa
- bnes mfix_nan //if non-zero, it is a NaN
- tstl ETEMP_LO(%a6) //check ls mantissa
- bnes mfix_nan //if non-zero, it is a NaN
-//input is inf
- orl #inf_mask,USER_FPSR(%a6) //set I bit
- tstl ETEMP(%a6) //check sign
- bge finish
- orl #neg_mask,USER_FPSR(%a6) //set N bit
- bra finish //special already on stack
-mfix_nan:
- orl #nan_mask,USER_FPSR(%a6) //set NaN bit
- moveb #nan_tag,STAG(%a6) //set stag to NaN
- btstb #signan_bit,ETEMP_HI(%a6) //test for snan
- bnes mn_snan
- orl #snaniop_mask,USER_FPSR(%a6) //set snan bit
- btstb #snan_bit,FPCR_ENABLE(%a6) //test for snan enabled
- bnes mn_snan
- bsetb #signan_bit,ETEMP_HI(%a6) //force snans to qnans
-mn_snan:
- tstl ETEMP(%a6) //check for sign
- bge finish //if clr, go on
- orl #neg_mask,USER_FPSR(%a6) //set N bit
- bra finish
-
-mtry_zero:
- movew ETEMP_EX+2(%a6),%d0 //get word 4
- andiw #0x000f,%d0 //clear all but last ni(y)bble
- tstw %d0 //check for zero.
- bnes mnot_spec
- tstl ETEMP_HI(%a6) //check words 3 and 2
- bnes mnot_spec
- tstl ETEMP_LO(%a6) //check words 1 and 0
- bnes mnot_spec
- tstl ETEMP(%a6) //test sign of the zero
- bges mpos_zero
- orl #neg_mask+z_mask,USER_FPSR(%a6) //set N and Z
- movel #0x80000000,ETEMP(%a6) //write neg zero to etemp
- clrl ETEMP_HI(%a6)
- clrl ETEMP_LO(%a6)
- bras finish
-mpos_zero:
- orl #z_mask,USER_FPSR(%a6) //set Z
- clrl ETEMP(%a6)
- clrl ETEMP_HI(%a6)
- clrl ETEMP_LO(%a6)
- bras finish
-
-mnot_spec:
- fmovemx %fp0-%fp1,-(%a7) //save fp0 ,fp1 - decbin returns in fp0
- bsr decbin
- fmovex %fp0,ETEMP(%a6)
-// ;put the unpacked sop in the fsave stack
- fmovemx (%a7)+,%fp0-%fp1
-
-finish:
- movew CMDREG1B(%a6),%d0 //get the command word
- andw #0xfbff,%d0 //change the source specifier field to
-// ;extended (was packed).
- movew %d0,CMDREG1B(%a6) //write command word back to fsave stack
-// ;we need to do this so the 040 will
-// ;re-execute the inst. without taking
-// ;another packed trap.
-
-fix_stag:
-//Converted result is now in etemp on fsave stack, now set the source
-//tag (stag)
-// if (ete =$7fff) then INF or NAN
-// if (etemp = $x.0----0) then
-// stag = INF
-// else
-// stag = NAN
-// else
-// if (ete = $0000) then
-// stag = ZERO
-// else
-// stag = NORM
-//
-// Note also that the etemp_15 bit (just right of the stag) must
-// be set accordingly.
-//
- movew ETEMP_EX(%a6),%d1
- andiw #0x7fff,%d1 //strip sign
- cmpw #0x7fff,%d1
- bnes z_or_nrm
- movel ETEMP_HI(%a6),%d1
- bnes is_nan
- movel ETEMP_LO(%a6),%d1
- bnes is_nan
-is_inf:
- moveb #0x40,STAG(%a6)
- movel #0x40,%d0
- rts
-is_nan:
- moveb #0x60,STAG(%a6)
- movel #0x60,%d0
- rts
-z_or_nrm:
- tstw %d1
- bnes is_nrm
-is_zro:
-// For a zero, set etemp_15
- moveb #0x30,STAG(%a6)
- movel #0x20,%d0
- rts
-is_nrm:
-// For a norm, check if the exp <= $3fff; if so, set etemp_15
- cmpiw #0x3fff,%d1
- bles set_bit15
- moveb #0,STAG(%a6)
- bras end_is_nrm
-set_bit15:
- moveb #0x10,STAG(%a6)
-end_is_nrm:
- movel #0,%d0
-end_fix:
- rts
-
-end_get:
- rts
- |end