root/arch/m68k/fpsp040/x_store.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 |
   2 |       x_store.sa 3.2 1/24/91
   3 |
   4 |       store --- store operand to memory or register
   5 |
   6 |       Used by underflow and overflow handlers.
   7 |
   8 |       a6 = points to fp value to be stored.
   9 |
  10 
  11 |               Copyright (C) Motorola, Inc. 1990
  12 |                       All Rights Reserved
  13 |
  14 |       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 
  15 |       The copyright notice above does not evidence any  
  16 |       actual or intended publication of such source code.
  17 
  18 X_STORE:        |idnt    2,1 | Motorola 040 Floating Point Software Package
  19 
  20         |section        8
  21 
  22 fpreg_mask:
  23         .byte   0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
  24 
  25         .include "fpsp.h"
  26 
  27         |xref   mem_write
  28         |xref   get_fline
  29         |xref   g_opcls
  30         |xref   g_dfmtou
  31         |xref   reg_dest
  32 
  33         .global dest_ext
  34         .global dest_dbl
  35         .global dest_sgl
  36 
  37         .global store
  38 store:
  39         btstb   #E3,E_BYTE(%a6)
  40         beqs    E1_sto
  41 E3_sto:
  42         movel   CMDREG3B(%a6),%d0
  43         bfextu  %d0{#6:#3},%d0          |isolate dest. reg from cmdreg3b
  44 sto_fp:
  45         lea     fpreg_mask,%a1
  46         moveb   (%a1,%d0.w),%d0         |convert reg# to dynamic register mask
  47         tstb    LOCAL_SGN(%a0)
  48         beqs    is_pos
  49         bsetb   #sign_bit,LOCAL_EX(%a0)
  50 is_pos:
  51         fmovemx (%a0),%d0               |move to correct register
  52 |
  53 |       if fp0-fp3 is being modified, we must put a copy
  54 |       in the USER_FPn variable on the stack because all exception
  55 |       handlers restore fp0-fp3 from there.
  56 |
  57         cmpb    #0x80,%d0               
  58         bnes    not_fp0
  59         fmovemx %fp0-%fp0,USER_FP0(%a6)
  60         rts
  61 not_fp0:
  62         cmpb    #0x40,%d0
  63         bnes    not_fp1
  64         fmovemx %fp1-%fp1,USER_FP1(%a6)
  65         rts
  66 not_fp1:
  67         cmpb    #0x20,%d0
  68         bnes    not_fp2
  69         fmovemx %fp2-%fp2,USER_FP2(%a6)
  70         rts
  71 not_fp2:
  72         cmpb    #0x10,%d0
  73         bnes    not_fp3
  74         fmovemx %fp3-%fp3,USER_FP3(%a6)
  75         rts
  76 not_fp3:
  77         rts
  78 
  79 E1_sto:
  80         bsrl    g_opcls         |returns opclass in d0
  81         cmpib   #3,%d0
  82         beq     opc011          |branch if opclass 3
  83         movel   CMDREG1B(%a6),%d0
  84         bfextu  %d0{#6:#3},%d0  |extract destination register
  85         bras    sto_fp
  86 
  87 opc011:
  88         bsrl    g_dfmtou        |returns dest format in d0
  89 |                               ;ext=00, sgl=01, dbl=10
  90         movel   %a0,%a1         |save source addr in a1
  91         movel   EXC_EA(%a6),%a0 |get the address
  92         cmpil   #0,%d0          |if dest format is extended
  93         beq     dest_ext        |then branch
  94         cmpil   #1,%d0          |if dest format is single
  95         beqs    dest_sgl        |then branch
  96 |
  97 |       fall through to dest_dbl
  98 |
  99 
 100 |
 101 |       dest_dbl --- write double precision value to user space
 102 |
 103 |Input
 104 |       a0 -> destination address
 105 |       a1 -> source in extended precision
 106 |Output
 107 |       a0 -> destroyed
 108 |       a1 -> destroyed
 109 |       d0 -> 0
 110 |
 111 |Changes extended precision to double precision.
 112 | Note: no attempt is made to round the extended value to double.
 113 |       dbl_sign = ext_sign
 114 |       dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
 115 |       get rid of ext integer bit
 116 |       dbl_mant = ext_mant{62:12}
 117 |
 118 |               ---------------   ---------------    ---------------
 119 |  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
 120 |               ---------------   ---------------    ---------------
 121 |                95         64    63 62       32      31     11   0
 122 |                                    |                       |
 123 |                                    |                       |
 124 |                                    |                       |
 125 |                                    v                       v
 126 |                             ---------------   ---------------
 127 |  double   ->                |s|exp| mant  |   |  mant       |
 128 |                             ---------------   ---------------
 129 |                             63     51   32   31              0
 130 |
 131 dest_dbl:
 132         clrl    %d0             |clear d0
 133         movew   LOCAL_EX(%a1),%d0       |get exponent
 134         subw    #0x3fff,%d0     |subtract extended precision bias
 135         cmpw    #0x4000,%d0     |check if inf
 136         beqs    inf             |if so, special case
 137         addw    #0x3ff,%d0      |add double precision bias
 138         swap    %d0             |d0 now in upper word
 139         lsll    #4,%d0          |d0 now in proper place for dbl prec exp
 140         tstb    LOCAL_SGN(%a1)  
 141         beqs    get_mant        |if positive, go process mantissa
 142         bsetl   #31,%d0         |if negative, put in sign information
 143 |                               ; before continuing
 144         bras    get_mant        |go process mantissa
 145 inf:
 146         movel   #0x7ff00000,%d0 |load dbl inf exponent
 147         clrl    LOCAL_HI(%a1)   |clear msb
 148         tstb    LOCAL_SGN(%a1)
 149         beqs    dbl_inf         |if positive, go ahead and write it
 150         bsetl   #31,%d0         |if negative put in sign information
 151 dbl_inf:
 152         movel   %d0,LOCAL_EX(%a1)       |put the new exp back on the stack
 153         bras    dbl_wrt
 154 get_mant:
 155         movel   LOCAL_HI(%a1),%d1       |get ms mantissa
 156         bfextu  %d1{#1:#20},%d1 |get upper 20 bits of ms
 157         orl     %d1,%d0         |put these bits in ms word of double
 158         movel   %d0,LOCAL_EX(%a1)       |put the new exp back on the stack
 159         movel   LOCAL_HI(%a1),%d1       |get ms mantissa
 160         movel   #21,%d0         |load shift count
 161         lsll    %d0,%d1         |put lower 11 bits in upper bits
 162         movel   %d1,LOCAL_HI(%a1)       |build lower lword in memory
 163         movel   LOCAL_LO(%a1),%d1       |get ls mantissa
 164         bfextu  %d1{#0:#21},%d0 |get ls 21 bits of double
 165         orl     %d0,LOCAL_HI(%a1)       |put them in double result
 166 dbl_wrt:
 167         movel   #0x8,%d0                |byte count for double precision number
 168         exg     %a0,%a1         |a0=supervisor source, a1=user dest
 169         bsrl    mem_write       |move the number to the user's memory
 170         rts
 171 |
 172 |       dest_sgl --- write single precision value to user space
 173 |
 174 |Input
 175 |       a0 -> destination address
 176 |       a1 -> source in extended precision
 177 |
 178 |Output
 179 |       a0 -> destroyed
 180 |       a1 -> destroyed
 181 |       d0 -> 0
 182 |
 183 |Changes extended precision to single precision.
 184 |       sgl_sign = ext_sign
 185 |       sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
 186 |       get rid of ext integer bit
 187 |       sgl_mant = ext_mant{62:12}
 188 |
 189 |               ---------------   ---------------    ---------------
 190 |  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |
 191 |               ---------------   ---------------    ---------------
 192 |                95         64    63 62    40 32      31     12   0
 193 |                                    |     |
 194 |                                    |     |
 195 |                                    |     |
 196 |                                    v     v
 197 |                             ---------------
 198 |  single   ->                |s|exp| mant  |
 199 |                             ---------------
 200 |                             31     22     0
 201 |
 202 dest_sgl:
 203         clrl    %d0
 204         movew   LOCAL_EX(%a1),%d0       |get exponent
 205         subw    #0x3fff,%d0     |subtract extended precision bias
 206         cmpw    #0x4000,%d0     |check if inf
 207         beqs    sinf            |if so, special case
 208         addw    #0x7f,%d0               |add single precision bias
 209         swap    %d0             |put exp in upper word of d0
 210         lsll    #7,%d0          |shift it into single exp bits
 211         tstb    LOCAL_SGN(%a1)  
 212         beqs    get_sman        |if positive, continue
 213         bsetl   #31,%d0         |if negative, put in sign first
 214         bras    get_sman        |get mantissa
 215 sinf:
 216         movel   #0x7f800000,%d0 |load single inf exp to d0
 217         tstb    LOCAL_SGN(%a1)
 218         beqs    sgl_wrt         |if positive, continue
 219         bsetl   #31,%d0         |if negative, put in sign info
 220         bras    sgl_wrt
 221 
 222 get_sman:
 223         movel   LOCAL_HI(%a1),%d1       |get ms mantissa
 224         bfextu  %d1{#1:#23},%d1 |get upper 23 bits of ms
 225         orl     %d1,%d0         |put these bits in ms word of single
 226 
 227 sgl_wrt:
 228         movel   %d0,L_SCR1(%a6) |put the new exp back on the stack
 229         movel   #0x4,%d0                |byte count for single precision number
 230         tstl    %a0             |users destination address
 231         beqs    sgl_Dn          |destination is a data register
 232         exg     %a0,%a1         |a0=supervisor source, a1=user dest
 233         leal    L_SCR1(%a6),%a0 |point a0 to data
 234         bsrl    mem_write       |move the number to the user's memory
 235         rts
 236 sgl_Dn:
 237         bsrl    get_fline       |returns fline word in d0
 238         andw    #0x7,%d0                |isolate register number
 239         movel   %d0,%d1         |d1 has size:reg formatted for reg_dest
 240         orl     #0x10,%d1               |reg_dest wants size added to reg#
 241         bral    reg_dest        |size is X, rts in reg_dest will
 242 |                               ;return to caller of dest_sgl
 243         
 244 dest_ext:
 245         tstb    LOCAL_SGN(%a1)  |put back sign into exponent word
 246         beqs    dstx_cont
 247         bsetb   #sign_bit,LOCAL_EX(%a1)
 248 dstx_cont:
 249         clrb    LOCAL_SGN(%a1)  |clear out the sign byte
 250 
 251         movel   #0x0c,%d0               |byte count for extended number
 252         exg     %a0,%a1         |a0=supervisor source, a1=user dest
 253         bsrl    mem_write       |move the number to the user's memory
 254         rts
 255 
 256         |end

/* [previous][next][first][last][top][bottom][index][help] */