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

Annotation of sys/arch/m68k/fpsp/util.sa, Revision 1.1.1.1

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

CVSweb