[BACK]Return to x_store.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

Annotation of sys/arch/m68k/fpsp/x_store.sa, Revision 1.1

1.1     ! nbrk        1: *      $OpenBSD: x_store.sa,v 1.2 1996/05/29 21:05:49 niklas Exp $
        !             2: *      $NetBSD: x_store.sa,v 1.3 1994/10/26 07:50:29 cgd Exp $
        !             3:
        !             4: *      MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
        !             5: *      M68000 Hi-Performance Microprocessor Division
        !             6: *      M68040 Software Package
        !             7: *
        !             8: *      M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
        !             9: *      All rights reserved.
        !            10: *
        !            11: *      THE SOFTWARE is provided on an "AS IS" basis and without warranty.
        !            12: *      To the maximum extent permitted by applicable law,
        !            13: *      MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
        !            14: *      INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
        !            15: *      PARTICULAR PURPOSE and any warranty against infringement with
        !            16: *      regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
        !            17: *      and any accompanying written materials.
        !            18: *
        !            19: *      To the maximum extent permitted by applicable law,
        !            20: *      IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
        !            21: *      (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
        !            22: *      PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
        !            23: *      OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
        !            24: *      SOFTWARE.  Motorola assumes no responsibility for the maintenance
        !            25: *      and support of the SOFTWARE.
        !            26: *
        !            27: *      You are hereby granted a copyright license to use, modify, and
        !            28: *      distribute the SOFTWARE so long as this entire notice is retained
        !            29: *      without alteration in any modified and/or redistributed versions,
        !            30: *      and that such modified versions are clearly identified as such.
        !            31: *      No licenses are granted by implication, estoppel or otherwise
        !            32: *      under any patents or trademarks of Motorola, Inc.
        !            33:
        !            34: *
        !            35: *      x_store.sa 3.2 1/24/91
        !            36: *
        !            37: *      store --- store operand to memory or register
        !            38: *
        !            39: *      Used by underflow and overflow handlers.
        !            40: *
        !            41: *      a6 = points to fp value to be stored.
        !            42: *
        !            43:
        !            44: X_STORE        IDNT    2,1 Motorola 040 Floating Point Software Package
        !            45:
        !            46:        section 8
        !            47:
        !            48: fpreg_mask:
        !            49:        dc.b    $80,$40,$20,$10,$08,$04,$02,$01
        !            50:
        !            51:        include fpsp.h
        !            52:
        !            53:        xref    mem_write
        !            54:        xref    get_fline
        !            55:        xref    g_opcls
        !            56:        xref    g_dfmtou
        !            57:        xref    reg_dest
        !            58:
        !            59:        xdef    dest_ext
        !            60:        xdef    dest_dbl
        !            61:        xdef    dest_sgl
        !            62:
        !            63:        xdef    store
        !            64: store:
        !            65:        btst.b  #E3,E_BYTE(a6)
        !            66:        beq.b   E1_sto
        !            67: E3_sto:
        !            68:        move.l  CMDREG3B(a6),d0
        !            69:        bfextu  d0{6:3},d0              ;isolate dest. reg from cmdreg3b
        !            70: sto_fp:
        !            71:        lea     fpreg_mask,a1
        !            72:        move.b  (a1,d0.w),d0            ;convert reg# to dynamic register mask
        !            73:        tst.b   LOCAL_SGN(a0)
        !            74:        beq.b   is_pos
        !            75:        bset.b  #sign_bit,LOCAL_EX(a0)
        !            76: is_pos:
        !            77:        fmovem.x (a0),d0                ;move to correct register
        !            78: *
        !            79: *      if fp0-fp3 is being modified, we must put a copy
        !            80: *      in the USER_FPn variable on the stack because all exception
        !            81: *      handlers restore fp0-fp3 from there.
        !            82: *
        !            83:        cmp.b   #$80,d0
        !            84:        bne.b   not_fp0
        !            85:        fmovem.x fp0,USER_FP0(a6)
        !            86:        rts
        !            87: not_fp0:
        !            88:        cmp.b   #$40,d0
        !            89:        bne.b   not_fp1
        !            90:        fmovem.x fp1,USER_FP1(a6)
        !            91:        rts
        !            92: not_fp1:
        !            93:        cmp.b   #$20,d0
        !            94:        bne.b   not_fp2
        !            95:        fmovem.x fp2,USER_FP2(a6)
        !            96:        rts
        !            97: not_fp2:
        !            98:        cmp.b   #$10,d0
        !            99:        bne.b   not_fp3
        !           100:        fmovem.x fp3,USER_FP3(a6)
        !           101:        rts
        !           102: not_fp3:
        !           103:        rts
        !           104:
        !           105: E1_sto:
        !           106:        bsr.l   g_opcls         ;returns opclass in d0
        !           107:        cmpi.b  #3,d0
        !           108:        beq     opc011          ;branch if opclass 3
        !           109:        move.l  CMDREG1B(a6),d0
        !           110:        bfextu  d0{6:3},d0      ;extract destination register
        !           111:        bra.b   sto_fp
        !           112:
        !           113: opc011:
        !           114:        bsr.l   g_dfmtou        ;returns dest format in d0
        !           115: *                              ;ext=00, sgl=01, dbl=10
        !           116:        move.l  a0,a1           ;save source addr in a1
        !           117:        move.l  EXC_EA(a6),a0   ;get the address
        !           118:        tst.l   d0              ;if dest format is extended
        !           119:        beq.w   dest_ext        ;then branch
        !           120:        cmpi.l  #1,d0           ;if dest format is single
        !           121:        beq.b   dest_sgl        ;then branch
        !           122: *
        !           123: *      fall through to dest_dbl
        !           124: *
        !           125:
        !           126: *
        !           127: *      dest_dbl --- write double precision value to user space
        !           128: *
        !           129: *Input
        !           130: *      a0 -> destination address
        !           131: *      a1 -> source in extended precision
        !           132: *Output
        !           133: *      a0 -> destroyed
        !           134: *      a1 -> destroyed
        !           135: *      d0 -> 0
        !           136: *
        !           137: *Changes extended precision to double precision.
        !           138: * Note: no attempt is made to round the extended value to double.
        !           139: *      dbl_sign = ext_sign
        !           140: *      dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
        !           141: *      get rid of ext integer bit
        !           142: *      dbl_mant = ext_mant{62:12}
        !           143: *
        !           144: *              ---------------   ---------------    ---------------
        !           145: *  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
        !           146: *              ---------------   ---------------    ---------------
        !           147: *               95         64    63 62       32      31     11   0
        !           148: *                                   |                       |
        !           149: *                                   |                       |
        !           150: *                                   |                       |
        !           151: *                                   v                       v
        !           152: *                            ---------------   ---------------
        !           153: *  double   ->               |s|exp| mant  |   |  mant       |
        !           154: *                            ---------------   ---------------
        !           155: *                            63     51   32   31              0
        !           156: *
        !           157: dest_dbl:
        !           158:        clr.l   d0              ;clear d0
        !           159:        move.w  LOCAL_EX(a1),d0 ;get exponent
        !           160:        sub.w   #$3fff,d0       ;subtract extended precision bias
        !           161:        cmp.w   #$4000,d0       ;check if inf
        !           162:        beq.b   inf             ;if so, special case
        !           163:        add.w   #$3ff,d0        ;add double precision bias
        !           164:        swap    d0              ;d0 now in upper word
        !           165:        lsl.l   #4,d0           ;d0 now in proper place for dbl prec exp
        !           166:        tst.b   LOCAL_SGN(a1)
        !           167:        beq.b   get_mant        ;if postive, go process mantissa
        !           168:        bset.l  #31,d0          ;if negative, put in sign information
        !           169: *                              ; before continuing
        !           170:        bra.b   get_mant        ;go process mantissa
        !           171: inf:
        !           172:        move.l  #$7ff00000,d0   ;load dbl inf exponent
        !           173:        clr.l   LOCAL_HI(a1)    ;clear msb
        !           174:        tst.b   LOCAL_SGN(a1)
        !           175:        beq.b   dbl_inf         ;if positive, go ahead and write it
        !           176:        bset.l  #31,d0          ;if negative put in sign information
        !           177: dbl_inf:
        !           178:        move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
        !           179:        bra.b   dbl_wrt
        !           180: get_mant:
        !           181:        move.l  LOCAL_HI(a1),d1 ;get ms mantissa
        !           182:        bfextu  d1{1:20},d1     ;get upper 20 bits of ms
        !           183:        or.l    d1,d0           ;put these bits in ms word of double
        !           184:        move.l  d0,LOCAL_EX(a1) ;put the new exp back on the stack
        !           185:        move.l  LOCAL_HI(a1),d1 ;get ms mantissa
        !           186:        move.l  #21,d0          ;load shift count
        !           187:        lsl.l   d0,d1           ;put lower 11 bits in upper bits
        !           188:        move.l  d1,LOCAL_HI(a1) ;build lower lword in memory
        !           189:        move.l  LOCAL_LO(a1),d1 ;get ls mantissa
        !           190:        bfextu  d1{0:21},d0     ;get ls 21 bits of double
        !           191:        or.l    d0,LOCAL_HI(a1) ;put them in double result
        !           192: dbl_wrt:
        !           193:        move.l  #$8,d0          ;byte count for double precision number
        !           194:        exg     a0,a1           ;a0=supervisor source, a1=user dest
        !           195:        bsr.l   mem_write       ;move the number to the user's memory
        !           196:        rts
        !           197: *
        !           198: *      dest_sgl --- write single precision value to user space
        !           199: *
        !           200: *Input
        !           201: *      a0 -> destination address
        !           202: *      a1 -> source in extended precision
        !           203: *
        !           204: *Output
        !           205: *      a0 -> destroyed
        !           206: *      a1 -> destroyed
        !           207: *      d0 -> 0
        !           208: *
        !           209: *Changes extended precision to single precision.
        !           210: *      sgl_sign = ext_sign
        !           211: *      sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
        !           212: *      get rid of ext integer bit
        !           213: *      sgl_mant = ext_mant{62:12}
        !           214: *
        !           215: *              ---------------   ---------------    ---------------
        !           216: *  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
        !           217: *              ---------------   ---------------    ---------------
        !           218: *               95         64    63 62    40 32      31     12   0
        !           219: *                                   |     |
        !           220: *                                   |     |
        !           221: *                                   |     |
        !           222: *                                   v     v
        !           223: *                            ---------------
        !           224: *  single   ->               |s|exp| mant  |
        !           225: *                            ---------------
        !           226: *                            31     22     0
        !           227: *
        !           228: dest_sgl:
        !           229:        clr.l   d0
        !           230:        move.w  LOCAL_EX(a1),d0 ;get exponent
        !           231:        sub.w   #$3fff,d0       ;subtract extended precision bias
        !           232:        cmp.w   #$4000,d0       ;check if inf
        !           233:        beq.b   sinf            ;if so, special case
        !           234:        add.w   #$7f,d0         ;add single precision bias
        !           235:        swap    d0              ;put exp in upper word of d0
        !           236:        lsl.l   #7,d0           ;shift it into single exp bits
        !           237:        tst.b   LOCAL_SGN(a1)
        !           238:        beq.b   get_sman        ;if positive, continue
        !           239:        bset.l  #31,d0          ;if negative, put in sign first
        !           240:        bra.b   get_sman        ;get mantissa
        !           241: sinf:
        !           242:        move.l  #$7f800000,d0   ;load single inf exp to d0
        !           243:        tst.b   LOCAL_SGN(a1)
        !           244:        beq.b   sgl_wrt         ;if positive, continue
        !           245:        bset.l  #31,d0          ;if negative, put in sign info
        !           246:        bra.b   sgl_wrt
        !           247:
        !           248: get_sman:
        !           249:        move.l  LOCAL_HI(a1),d1 ;get ms mantissa
        !           250:        bfextu  d1{1:23},d1     ;get upper 23 bits of ms
        !           251:        or.l    d1,d0           ;put these bits in ms word of single
        !           252:
        !           253: sgl_wrt:
        !           254:        move.l  d0,L_SCR1(a6)   ;put the new exp back on the stack
        !           255:        move.l  #$4,d0          ;byte count for single precision number
        !           256:        tst.l   a0              ;users destination address
        !           257:        beq.b   sgl_Dn          ;destination is a data register
        !           258:        exg     a0,a1           ;a0=supervisor source, a1=user dest
        !           259:        lea.l   L_SCR1(a6),a0   ;point a0 to data
        !           260:        bsr.l   mem_write       ;move the number to the user's memory
        !           261:        rts
        !           262: sgl_Dn:
        !           263:        bsr.l   get_fline       ;returns fline word in d0
        !           264:        and.w   #$7,d0          ;isolate register number
        !           265:        move.l  d0,d1           ;d1 has size:reg formatted for reg_dest
        !           266:        or.l    #$10,d1         ;reg_dest wants size added to reg#
        !           267:        bra.l   reg_dest        ;size is X, rts in reg_dest will
        !           268: *                              ;return to caller of dest_sgl
        !           269:
        !           270: dest_ext:
        !           271:        tst.b   LOCAL_SGN(a1)   ;put back sign into exponent word
        !           272:        beq.b   dstx_cont
        !           273:        bset.b  #sign_bit,LOCAL_EX(a1)
        !           274: dstx_cont:
        !           275:        clr.b   LOCAL_SGN(a1)   ;clear out the sign byte
        !           276:
        !           277:        move.l  #$0c,d0         ;byte count for extended number
        !           278:        exg     a0,a1           ;a0=supervisor source, a1=user dest
        !           279:        bsr.l   mem_write       ;move the number to the user's memory
        !           280:        rts
        !           281:
        !           282:        end

CVSweb