[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     ! 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