OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [fpsp040/] [get_op.S] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.