root/arch/m68k/fpsp040/util.S

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

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