root/arch/m68k/fpsp040/util.S

/* [<][>][^][v][top][bottom][index][help] */
   1 |
   2 |       util.sa 3.7 7/29/91
   3 |
   4 |       This file contains routines used by other programs.
   5 |
   6 |       ovf_res: used by overflow to force the correct
   7 |                result. ovf_r_k, ovf_r_x2, ovf_r_x3 are
   8 |                derivatives of this routine.
   9 |       get_fline: get user's opcode word
  10 |       g_dfmtou: returns the destination format.
  11 |       g_opcls: returns the opclass of the float instruction.
  12 |       g_rndpr: returns the rounding precision.
  13 |       reg_dest: write byte, word, or long data to Dn
  14 |
  15 |
  16 |               Copyright (C) Motorola, Inc. 1990
  17 |                       All Rights Reserved
  18 |
  19 |       For details on the license for this file, please see the
  20 |       file, README, in this same directory.
  21 
  22 |UTIL   idnt    2,1 | Motorola 040 Floating Point Software Package
  23 
  24         |section        8
  25 
  26 #include "fpsp.h"
  27 
  28         |xref   mem_read
  29 
  30         .global g_dfmtou
  31         .global g_opcls
  32         .global g_rndpr
  33         .global get_fline
  34         .global reg_dest
  35 
  36 |
  37 | Final result table for ovf_res. Note that the negative counterparts
  38 | are unnecessary as ovf_res always returns the sign separately from
  39 | the exponent.
  40 |                                       ;+inf
  41 EXT_PINF:       .long   0x7fff0000,0x00000000,0x00000000,0x00000000
  42 |                                       ;largest +ext
  43 EXT_PLRG:       .long   0x7ffe0000,0xffffffff,0xffffffff,0x00000000
  44 |                                       ;largest magnitude +sgl in ext
  45 SGL_PLRG:       .long   0x407e0000,0xffffff00,0x00000000,0x00000000
  46 |                                       ;largest magnitude +dbl in ext
  47 DBL_PLRG:       .long   0x43fe0000,0xffffffff,0xfffff800,0x00000000
  48 |                                       ;largest -ext
  49 
  50 tblovfl:
  51         .long   EXT_RN
  52         .long   EXT_RZ
  53         .long   EXT_RM
  54         .long   EXT_RP
  55         .long   SGL_RN
  56         .long   SGL_RZ
  57         .long   SGL_RM
  58         .long   SGL_RP
  59         .long   DBL_RN
  60         .long   DBL_RZ
  61         .long   DBL_RM
  62         .long   DBL_RP
  63         .long   error
  64         .long   error
  65         .long   error
  66         .long   error
  67 
  68 
  69 |
  70 |       ovf_r_k --- overflow result calculation
  71 |
  72 | This entry point is used by kernel_ex.
  73 |
  74 | This forces the destination precision to be extended
  75 |
  76 | Input:        operand in ETEMP
  77 | Output:       a result is in ETEMP (internal extended format)
  78 |
  79         .global ovf_r_k
  80 ovf_r_k:
  81         lea     ETEMP(%a6),%a0  |a0 points to source operand
  82         bclrb   #sign_bit,ETEMP_EX(%a6)
  83         sne     ETEMP_SGN(%a6)  |convert to internal IEEE format
  84 
  85 |
  86 |       ovf_r_x2 --- overflow result calculation
  87 |
  88 | This entry point used by x_ovfl.  (opclass 0 and 2)
  89 |
  90 | Input         a0  points to an operand in the internal extended format
  91 | Output        a0  points to the result in the internal extended format
  92 |
  93 | This sets the round precision according to the user's FPCR unless the
  94 | instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul,
  95 | fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg.
  96 | If the instruction is fsgldiv of fsglmul, the rounding precision must be
  97 | extended.  If the instruction is not fsgldiv or fsglmul but a force-
  98 | precision instruction, the rounding precision is then set to the force
  99 | precision.
 100 
 101         .global ovf_r_x2
 102 ovf_r_x2:
 103         btstb   #E3,E_BYTE(%a6)         |check for nu exception
 104         beql    ovf_e1_exc              |it is cu exception
 105 ovf_e3_exc:
 106         movew   CMDREG3B(%a6),%d0               |get the command word
 107         andiw   #0x00000060,%d0         |clear all bits except 6 and 5
 108         cmpil   #0x00000040,%d0
 109         beql    ovff_sgl                |force precision is single
 110         cmpil   #0x00000060,%d0
 111         beql    ovff_dbl                |force precision is double
 112         movew   CMDREG3B(%a6),%d0               |get the command word again
 113         andil   #0x7f,%d0                       |clear all except operation
 114         cmpil   #0x33,%d0
 115         beql    ovf_fsgl                |fsglmul or fsgldiv
 116         cmpil   #0x30,%d0
 117         beql    ovf_fsgl
 118         bra     ovf_fpcr                |instruction is none of the above
 119 |                                       ;use FPCR
 120 ovf_e1_exc:
 121         movew   CMDREG1B(%a6),%d0               |get command word
 122         andil   #0x00000044,%d0         |clear all bits except 6 and 2
 123         cmpil   #0x00000040,%d0
 124         beql    ovff_sgl                |the instruction is force single
 125         cmpil   #0x00000044,%d0
 126         beql    ovff_dbl                |the instruction is force double
 127         movew   CMDREG1B(%a6),%d0               |again get the command word
 128         andil   #0x0000007f,%d0         |clear all except the op code
 129         cmpil   #0x00000027,%d0
 130         beql    ovf_fsgl                |fsglmul
 131         cmpil   #0x00000024,%d0
 132         beql    ovf_fsgl                |fsgldiv
 133         bra     ovf_fpcr                |none of the above, use FPCR
 134 |
 135 |
 136 | Inst is either fsgldiv or fsglmul.  Force extended precision.
 137 |
 138 ovf_fsgl:
 139         clrl    %d0
 140         bra     ovf_res
 141 
 142 ovff_sgl:
 143         movel   #0x00000001,%d0         |set single
 144         bra     ovf_res
 145 ovff_dbl:
 146         movel   #0x00000002,%d0         |set double
 147         bra     ovf_res
 148 |
 149 | The precision is in the fpcr.
 150 |
 151 ovf_fpcr:
 152         bfextu  FPCR_MODE(%a6){#0:#2},%d0 |set round precision
 153         bra     ovf_res
 154 
 155 |
 156 |
 157 |       ovf_r_x3 --- overflow result calculation
 158 |
 159 | This entry point used by x_ovfl. (opclass 3 only)
 160 |
 161 | Input         a0  points to an operand in the internal extended format
 162 | Output        a0  points to the result in the internal extended format
 163 |
 164 | This sets the round precision according to the destination size.
 165 |
 166         .global ovf_r_x3
 167 ovf_r_x3:
 168         bsr     g_dfmtou        |get dest fmt in d0{1:0}
 169 |                               ;for fmovout, the destination format
 170 |                               ;is the rounding precision
 171 
 172 |
 173 |       ovf_res --- overflow result calculation
 174 |
 175 | Input:
 176 |       a0      points to operand in internal extended format
 177 | Output:
 178 |       a0      points to result in internal extended format
 179 |
 180         .global ovf_res
 181 ovf_res:
 182         lsll    #2,%d0          |move round precision to d0{3:2}
 183         bfextu  FPCR_MODE(%a6){#2:#2},%d1 |set round mode
 184         orl     %d1,%d0         |index is fmt:mode in d0{3:0}
 185         leal    tblovfl,%a1     |load a1 with table address
 186         movel   %a1@(%d0:l:4),%a1       |use d0 as index to the table
 187         jmp     (%a1)           |go to the correct routine
 188 |
 189 |case DEST_FMT = EXT
 190 |
 191 EXT_RN:
 192         leal    EXT_PINF,%a1    |answer is +/- infinity
 193         bsetb   #inf_bit,FPSR_CC(%a6)
 194         bra     set_sign        |now go set the sign
 195 EXT_RZ:
 196         leal    EXT_PLRG,%a1    |answer is +/- large number
 197         bra     set_sign        |now go set the sign
 198 EXT_RM:
 199         tstb    LOCAL_SGN(%a0)  |if negative overflow
 200         beqs    e_rm_pos
 201 e_rm_neg:
 202         leal    EXT_PINF,%a1    |answer is negative infinity
 203         orl     #neginf_mask,USER_FPSR(%a6)
 204         bra     end_ovfr
 205 e_rm_pos:
 206         leal    EXT_PLRG,%a1    |answer is large positive number
 207         bra     end_ovfr
 208 EXT_RP:
 209         tstb    LOCAL_SGN(%a0)  |if negative overflow
 210         beqs    e_rp_pos
 211 e_rp_neg:
 212         leal    EXT_PLRG,%a1    |answer is large negative number
 213         bsetb   #neg_bit,FPSR_CC(%a6)
 214         bra     end_ovfr
 215 e_rp_pos:
 216         leal    EXT_PINF,%a1    |answer is positive infinity
 217         bsetb   #inf_bit,FPSR_CC(%a6)
 218         bra     end_ovfr
 219 |
 220 |case DEST_FMT = DBL
 221 |
 222 DBL_RN:
 223         leal    EXT_PINF,%a1    |answer is +/- infinity
 224         bsetb   #inf_bit,FPSR_CC(%a6)
 225         bra     set_sign
 226 DBL_RZ:
 227         leal    DBL_PLRG,%a1    |answer is +/- large number
 228         bra     set_sign        |now go set the sign
 229 DBL_RM:
 230         tstb    LOCAL_SGN(%a0)  |if negative overflow
 231         beqs    d_rm_pos
 232 d_rm_neg:
 233         leal    EXT_PINF,%a1    |answer is negative infinity
 234         orl     #neginf_mask,USER_FPSR(%a6)
 235         bra     end_ovfr        |inf is same for all precisions (ext,dbl,sgl)
 236 d_rm_pos:
 237         leal    DBL_PLRG,%a1    |answer is large positive number
 238         bra     end_ovfr
 239 DBL_RP:
 240         tstb    LOCAL_SGN(%a0)  |if negative overflow
 241         beqs    d_rp_pos
 242 d_rp_neg:
 243         leal    DBL_PLRG,%a1    |answer is large negative number
 244         bsetb   #neg_bit,FPSR_CC(%a6)
 245         bra     end_ovfr
 246 d_rp_pos:
 247         leal    EXT_PINF,%a1    |answer is positive infinity
 248         bsetb   #inf_bit,FPSR_CC(%a6)
 249         bra     end_ovfr
 250 |
 251 |case DEST_FMT = SGL
 252 |
 253 SGL_RN:
 254         leal    EXT_PINF,%a1    |answer is +/-  infinity
 255         bsetb   #inf_bit,FPSR_CC(%a6)
 256         bras    set_sign
 257 SGL_RZ:
 258         leal    SGL_PLRG,%a1    |answer is +/- large number
 259         bras    set_sign
 260 SGL_RM:
 261         tstb    LOCAL_SGN(%a0)  |if negative overflow
 262         beqs    s_rm_pos
 263 s_rm_neg:
 264         leal    EXT_PINF,%a1    |answer is negative infinity
 265         orl     #neginf_mask,USER_FPSR(%a6)
 266         bras    end_ovfr
 267 s_rm_pos:
 268         leal    SGL_PLRG,%a1    |answer is large positive number
 269         bras    end_ovfr
 270 SGL_RP:
 271         tstb    LOCAL_SGN(%a0)  |if negative overflow
 272         beqs    s_rp_pos
 273 s_rp_neg:
 274         leal    SGL_PLRG,%a1    |answer is large negative number
 275         bsetb   #neg_bit,FPSR_CC(%a6)
 276         bras    end_ovfr
 277 s_rp_pos:
 278         leal    EXT_PINF,%a1    |answer is positive infinity
 279         bsetb   #inf_bit,FPSR_CC(%a6)
 280         bras    end_ovfr
 281 
 282 set_sign:
 283         tstb    LOCAL_SGN(%a0)  |if negative overflow
 284         beqs    end_ovfr
 285 neg_sign:
 286         bsetb   #neg_bit,FPSR_CC(%a6)
 287 
 288 end_ovfr:
 289         movew   LOCAL_EX(%a1),LOCAL_EX(%a0) |do not overwrite sign
 290         movel   LOCAL_HI(%a1),LOCAL_HI(%a0)
 291         movel   LOCAL_LO(%a1),LOCAL_LO(%a0)
 292         rts
 293 
 294 
 295 |
 296 |       ERROR
 297 |
 298 error:
 299         rts
 300 |
 301 |       get_fline --- get f-line opcode of interrupted instruction
 302 |
 303 |       Returns opcode in the low word of d0.
 304 |
 305 get_fline:
 306         movel   USER_FPIAR(%a6),%a0     |opcode address
 307         movel   #0,-(%a7)       |reserve a word on the stack
 308         leal    2(%a7),%a1      |point to low word of temporary
 309         movel   #2,%d0          |count
 310         bsrl    mem_read
 311         movel   (%a7)+,%d0
 312         rts
 313 |
 314 |       g_rndpr --- put rounding precision in d0{1:0}
 315 |
 316 |       valid return codes are:
 317 |               00 - extended
 318 |               01 - single
 319 |               10 - double
 320 |
 321 | begin
 322 | get rounding precision (cmdreg3b{6:5})
 323 | begin
 324 |  case opclass = 011 (move out)
 325 |       get destination format - this is the also the rounding precision
 326 |
 327 |  case opclass = 0x0
 328 |       if E3
 329 |           *case RndPr(from cmdreg3b{6:5} = 11  then RND_PREC = DBL
 330 |           *case RndPr(from cmdreg3b{6:5} = 10  then RND_PREC = SGL
 331 |            case RndPr(from cmdreg3b{6:5} = 00 | 01
 332 |               use precision from FPCR{7:6}
 333 |                       case 00 then RND_PREC = EXT
 334 |                       case 01 then RND_PREC = SGL
 335 |                       case 10 then RND_PREC = DBL
 336 |       else E1
 337 |            use precision in FPCR{7:6}
 338 |            case 00 then RND_PREC = EXT
 339 |            case 01 then RND_PREC = SGL
 340 |            case 10 then RND_PREC = DBL
 341 | end
 342 |
 343 g_rndpr:
 344         bsr     g_opcls         |get opclass in d0{2:0}
 345         cmpw    #0x0003,%d0     |check for opclass 011
 346         bnes    op_0x0
 347 
 348 |
 349 | For move out instructions (opclass 011) the destination format
 350 | is the same as the rounding precision.  Pass results from g_dfmtou.
 351 |
 352         bsr     g_dfmtou
 353         rts
 354 op_0x0:
 355         btstb   #E3,E_BYTE(%a6)
 356         beql    unf_e1_exc      |branch to e1 underflow
 357 unf_e3_exc:
 358         movel   CMDREG3B(%a6),%d0       |rounding precision in d0{10:9}
 359         bfextu  %d0{#9:#2},%d0  |move the rounding prec bits to d0{1:0}
 360         cmpil   #0x2,%d0
 361         beql    unff_sgl        |force precision is single
 362         cmpil   #0x3,%d0                |force precision is double
 363         beql    unff_dbl
 364         movew   CMDREG3B(%a6),%d0       |get the command word again
 365         andil   #0x7f,%d0               |clear all except operation
 366         cmpil   #0x33,%d0
 367         beql    unf_fsgl        |fsglmul or fsgldiv
 368         cmpil   #0x30,%d0
 369         beql    unf_fsgl        |fsgldiv or fsglmul
 370         bra     unf_fpcr
 371 unf_e1_exc:
 372         movel   CMDREG1B(%a6),%d0       |get 32 bits off the stack, 1st 16 bits
 373 |                               ;are the command word
 374         andil   #0x00440000,%d0 |clear all bits except bits 6 and 2
 375         cmpil   #0x00400000,%d0
 376         beql    unff_sgl        |force single
 377         cmpil   #0x00440000,%d0 |force double
 378         beql    unff_dbl
 379         movel   CMDREG1B(%a6),%d0       |get the command word again
 380         andil   #0x007f0000,%d0 |clear all bits except the operation
 381         cmpil   #0x00270000,%d0
 382         beql    unf_fsgl        |fsglmul
 383         cmpil   #0x00240000,%d0
 384         beql    unf_fsgl        |fsgldiv
 385         bra     unf_fpcr
 386 
 387 |
 388 | Convert to return format.  The values from cmdreg3b and the return
 389 | values are:
 390 |       cmdreg3b        return       precision
 391 |       --------        ------       ---------
 392 |         00,01           0             ext
 393 |          10             1             sgl
 394 |          11             2             dbl
 395 | Force single
 396 |
 397 unff_sgl:
 398         movel   #1,%d0          |return 1
 399         rts
 400 |
 401 | Force double
 402 |
 403 unff_dbl:
 404         movel   #2,%d0          |return 2
 405         rts
 406 |
 407 | Force extended
 408 |
 409 unf_fsgl:
 410         movel   #0,%d0
 411         rts
 412 |
 413 | Get rounding precision set in FPCR{7:6}.
 414 |
 415 unf_fpcr:
 416         movel   USER_FPCR(%a6),%d0 |rounding precision bits in d0{7:6}
 417         bfextu  %d0{#24:#2},%d0 |move the rounding prec bits to d0{1:0}
 418         rts
 419 |
 420 |       g_opcls --- put opclass in d0{2:0}
 421 |
 422 g_opcls:
 423         btstb   #E3,E_BYTE(%a6)
 424         beqs    opc_1b          |if set, go to cmdreg1b
 425 opc_3b:
 426         clrl    %d0             |if E3, only opclass 0x0 is possible
 427         rts
 428 opc_1b:
 429         movel   CMDREG1B(%a6),%d0
 430         bfextu  %d0{#0:#3},%d0  |shift opclass bits d0{31:29} to d0{2:0}
 431         rts
 432 |
 433 |       g_dfmtou --- put destination format in d0{1:0}
 434 |
 435 |       If E1, the format is from cmdreg1b{12:10}
 436 |       If E3, the format is extended.
 437 |
 438 |       Dest. Fmt.
 439 |               extended  010 -> 00
 440 |               single    001 -> 01
 441 |               double    101 -> 10
 442 |
 443 g_dfmtou:
 444         btstb   #E3,E_BYTE(%a6)
 445         beqs    op011
 446         clrl    %d0             |if E1, size is always ext
 447         rts
 448 op011:
 449         movel   CMDREG1B(%a6),%d0
 450         bfextu  %d0{#3:#3},%d0  |dest fmt from cmdreg1b{12:10}
 451         cmpb    #1,%d0          |check for single
 452         bnes    not_sgl
 453         movel   #1,%d0
 454         rts
 455 not_sgl:
 456         cmpb    #5,%d0          |check for double
 457         bnes    not_dbl
 458         movel   #2,%d0
 459         rts
 460 not_dbl:
 461         clrl    %d0             |must be extended
 462         rts
 463 
 464 |
 465 |
 466 | Final result table for unf_sub. Note that the negative counterparts
 467 | are unnecessary as unf_sub always returns the sign separately from
 468 | the exponent.
 469 |                                       ;+zero
 470 EXT_PZRO:       .long   0x00000000,0x00000000,0x00000000,0x00000000
 471 |                                       ;+zero
 472 SGL_PZRO:       .long   0x3f810000,0x00000000,0x00000000,0x00000000
 473 |                                       ;+zero
 474 DBL_PZRO:       .long   0x3c010000,0x00000000,0x00000000,0x00000000
 475 |                                       ;smallest +ext denorm
 476 EXT_PSML:       .long   0x00000000,0x00000000,0x00000001,0x00000000
 477 |                                       ;smallest +sgl denorm
 478 SGL_PSML:       .long   0x3f810000,0x00000100,0x00000000,0x00000000
 479 |                                       ;smallest +dbl denorm
 480 DBL_PSML:       .long   0x3c010000,0x00000000,0x00000800,0x00000000
 481 |
 482 |       UNF_SUB --- underflow result calculation
 483 |
 484 | Input:
 485 |       d0      contains round precision
 486 |       a0      points to input operand in the internal extended format
 487 |
 488 | Output:
 489 |       a0      points to correct internal extended precision result.
 490 |
 491 
 492 tblunf:
 493         .long   uEXT_RN
 494         .long   uEXT_RZ
 495         .long   uEXT_RM
 496         .long   uEXT_RP
 497         .long   uSGL_RN
 498         .long   uSGL_RZ
 499         .long   uSGL_RM
 500         .long   uSGL_RP
 501         .long   uDBL_RN
 502         .long   uDBL_RZ
 503         .long   uDBL_RM
 504         .long   uDBL_RP
 505         .long   uDBL_RN
 506         .long   uDBL_RZ
 507         .long   uDBL_RM
 508         .long   uDBL_RP
 509 
 510         .global unf_sub
 511 unf_sub:
 512         lsll    #2,%d0          |move round precision to d0{3:2}
 513         bfextu  FPCR_MODE(%a6){#2:#2},%d1 |set round mode
 514         orl     %d1,%d0         |index is fmt:mode in d0{3:0}
 515         leal    tblunf,%a1      |load a1 with table address
 516         movel   %a1@(%d0:l:4),%a1       |use d0 as index to the table
 517         jmp     (%a1)           |go to the correct routine
 518 |
 519 |case DEST_FMT = EXT
 520 |
 521 uEXT_RN:
 522         leal    EXT_PZRO,%a1    |answer is +/- zero
 523         bsetb   #z_bit,FPSR_CC(%a6)
 524         bra     uset_sign       |now go set the sign
 525 uEXT_RZ:
 526         leal    EXT_PZRO,%a1    |answer is +/- zero
 527         bsetb   #z_bit,FPSR_CC(%a6)
 528         bra     uset_sign       |now go set the sign
 529 uEXT_RM:
 530         tstb    LOCAL_SGN(%a0)  |if negative underflow
 531         beqs    ue_rm_pos
 532 ue_rm_neg:
 533         leal    EXT_PSML,%a1    |answer is negative smallest denorm
 534         bsetb   #neg_bit,FPSR_CC(%a6)
 535         bra     end_unfr
 536 ue_rm_pos:
 537         leal    EXT_PZRO,%a1    |answer is positive zero
 538         bsetb   #z_bit,FPSR_CC(%a6)
 539         bra     end_unfr
 540 uEXT_RP:
 541         tstb    LOCAL_SGN(%a0)  |if negative underflow
 542         beqs    ue_rp_pos
 543 ue_rp_neg:
 544         leal    EXT_PZRO,%a1    |answer is negative zero
 545         oril    #negz_mask,USER_FPSR(%a6)
 546         bra     end_unfr
 547 ue_rp_pos:
 548         leal    EXT_PSML,%a1    |answer is positive smallest denorm
 549         bra     end_unfr
 550 |
 551 |case DEST_FMT = DBL
 552 |
 553 uDBL_RN:
 554         leal    DBL_PZRO,%a1    |answer is +/- zero
 555         bsetb   #z_bit,FPSR_CC(%a6)
 556         bra     uset_sign
 557 uDBL_RZ:
 558         leal    DBL_PZRO,%a1    |answer is +/- zero
 559         bsetb   #z_bit,FPSR_CC(%a6)
 560         bra     uset_sign       |now go set the sign
 561 uDBL_RM:
 562         tstb    LOCAL_SGN(%a0)  |if negative overflow
 563         beqs    ud_rm_pos
 564 ud_rm_neg:
 565         leal    DBL_PSML,%a1    |answer is smallest denormalized negative
 566         bsetb   #neg_bit,FPSR_CC(%a6)
 567         bra     end_unfr
 568 ud_rm_pos:
 569         leal    DBL_PZRO,%a1    |answer is positive zero
 570         bsetb   #z_bit,FPSR_CC(%a6)
 571         bra     end_unfr
 572 uDBL_RP:
 573         tstb    LOCAL_SGN(%a0)  |if negative overflow
 574         beqs    ud_rp_pos
 575 ud_rp_neg:
 576         leal    DBL_PZRO,%a1    |answer is negative zero
 577         oril    #negz_mask,USER_FPSR(%a6)
 578         bra     end_unfr
 579 ud_rp_pos:
 580         leal    DBL_PSML,%a1    |answer is smallest denormalized negative
 581         bra     end_unfr
 582 |
 583 |case DEST_FMT = SGL
 584 |
 585 uSGL_RN:
 586         leal    SGL_PZRO,%a1    |answer is +/- zero
 587         bsetb   #z_bit,FPSR_CC(%a6)
 588         bras    uset_sign
 589 uSGL_RZ:
 590         leal    SGL_PZRO,%a1    |answer is +/- zero
 591         bsetb   #z_bit,FPSR_CC(%a6)
 592         bras    uset_sign
 593 uSGL_RM:
 594         tstb    LOCAL_SGN(%a0)  |if negative overflow
 595         beqs    us_rm_pos
 596 us_rm_neg:
 597         leal    SGL_PSML,%a1    |answer is smallest denormalized negative
 598         bsetb   #neg_bit,FPSR_CC(%a6)
 599         bras    end_unfr
 600 us_rm_pos:
 601         leal    SGL_PZRO,%a1    |answer is positive zero
 602         bsetb   #z_bit,FPSR_CC(%a6)
 603         bras    end_unfr
 604 uSGL_RP:
 605         tstb    LOCAL_SGN(%a0)  |if negative overflow
 606         beqs    us_rp_pos
 607 us_rp_neg:
 608         leal    SGL_PZRO,%a1    |answer is negative zero
 609         oril    #negz_mask,USER_FPSR(%a6)
 610         bras    end_unfr
 611 us_rp_pos:
 612         leal    SGL_PSML,%a1    |answer is smallest denormalized positive
 613         bras    end_unfr
 614 
 615 uset_sign:
 616         tstb    LOCAL_SGN(%a0)  |if negative overflow
 617         beqs    end_unfr
 618 uneg_sign:
 619         bsetb   #neg_bit,FPSR_CC(%a6)
 620 
 621 end_unfr:
 622         movew   LOCAL_EX(%a1),LOCAL_EX(%a0) |be careful not to overwrite sign
 623         movel   LOCAL_HI(%a1),LOCAL_HI(%a0)
 624         movel   LOCAL_LO(%a1),LOCAL_LO(%a0)
 625         rts
 626 |
 627 |       reg_dest --- write byte, word, or long data to Dn
 628 |
 629 |
 630 | Input:
 631 |       L_SCR1: Data
 632 |       d1:     data size and dest register number formatted as:
 633 |
 634 |       32              5    4     3     2     1     0
 635 |       -----------------------------------------------
 636 |       |        0        |    Size   |  Dest Reg #   |
 637 |       -----------------------------------------------
 638 |
 639 |       Size is:
 640 |               0 - Byte
 641 |               1 - Word
 642 |               2 - Long/Single
 643 |
 644 pregdst:
 645         .long   byte_d0
 646         .long   byte_d1
 647         .long   byte_d2
 648         .long   byte_d3
 649         .long   byte_d4
 650         .long   byte_d5
 651         .long   byte_d6
 652         .long   byte_d7
 653         .long   word_d0
 654         .long   word_d1
 655         .long   word_d2
 656         .long   word_d3
 657         .long   word_d4
 658         .long   word_d5
 659         .long   word_d6
 660         .long   word_d7
 661         .long   long_d0
 662         .long   long_d1
 663         .long   long_d2
 664         .long   long_d3
 665         .long   long_d4
 666         .long   long_d5
 667         .long   long_d6
 668         .long   long_d7
 669 
 670 reg_dest:
 671         leal    pregdst,%a0
 672         movel   %a0@(%d1:l:4),%a0
 673         jmp     (%a0)
 674 
 675 byte_d0:
 676         moveb   L_SCR1(%a6),USER_D0+3(%a6)
 677         rts
 678 byte_d1:
 679         moveb   L_SCR1(%a6),USER_D1+3(%a6)
 680         rts
 681 byte_d2:
 682         moveb   L_SCR1(%a6),%d2
 683         rts
 684 byte_d3:
 685         moveb   L_SCR1(%a6),%d3
 686         rts
 687 byte_d4:
 688         moveb   L_SCR1(%a6),%d4
 689         rts
 690 byte_d5:
 691         moveb   L_SCR1(%a6),%d5
 692         rts
 693 byte_d6:
 694         moveb   L_SCR1(%a6),%d6
 695         rts
 696 byte_d7:
 697         moveb   L_SCR1(%a6),%d7
 698         rts
 699 word_d0:
 700         movew   L_SCR1(%a6),USER_D0+2(%a6)
 701         rts
 702 word_d1:
 703         movew   L_SCR1(%a6),USER_D1+2(%a6)
 704         rts
 705 word_d2:
 706         movew   L_SCR1(%a6),%d2
 707         rts
 708 word_d3:
 709         movew   L_SCR1(%a6),%d3
 710         rts
 711 word_d4:
 712         movew   L_SCR1(%a6),%d4
 713         rts
 714 word_d5:
 715         movew   L_SCR1(%a6),%d5
 716         rts
 717 word_d6:
 718         movew   L_SCR1(%a6),%d6
 719         rts
 720 word_d7:
 721         movew   L_SCR1(%a6),%d7
 722         rts
 723 long_d0:
 724         movel   L_SCR1(%a6),USER_D0(%a6)
 725         rts
 726 long_d1:
 727         movel   L_SCR1(%a6),USER_D1(%a6)
 728         rts
 729 long_d2:
 730         movel   L_SCR1(%a6),%d2
 731         rts
 732 long_d3:
 733         movel   L_SCR1(%a6),%d3
 734         rts
 735 long_d4:
 736         movel   L_SCR1(%a6),%d4
 737         rts
 738 long_d5:
 739         movel   L_SCR1(%a6),%d5
 740         rts
 741 long_d6:
 742         movel   L_SCR1(%a6),%d6
 743         rts
 744 long_d7:
 745         movel   L_SCR1(%a6),%d7
 746         rts
 747         |end

/* [<][>][^][v][top][bottom][index][help] */