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

Annotation of sys/arch/m68k/fpsp/do_func.sa, Revision 1.1

1.1     ! nbrk        1: *      $OpenBSD: do_func.sa,v 1.2 1996/05/29 21:05:27 niklas Exp $
        !             2: *      $NetBSD: do_func.sa,v 1.2 1994/10/26 07:49:02 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: *      do_func.sa 3.4 2/18/91
        !            36: *
        !            37: * Do_func performs the unimplemented operation.  The operation
        !            38: * to be performed is determined from the lower 7 bits of the
        !            39: * extension word (except in the case of fmovecr and fsincos).
        !            40: * The opcode and tag bits form an index into a jump table in
        !            41: * tbldo.sa.  Cases of zero, infinity and NaN are handled in
        !            42: * do_func by forcing the default result.  Normalized and
        !            43: * denormalized (there are no unnormalized numbers at this
        !            44: * point) are passed onto the emulation code.
        !            45: *
        !            46: * CMDREG1B and STAG are extracted from the fsave frame
        !            47: * and combined to form the table index.  The function called
        !            48: * will start with a0 pointing to the ETEMP operand.  Dyadic
        !            49: * functions can find FPTEMP at -12(a0).
        !            50: *
        !            51: * Called functions return their result in fp0.  Sincos returns
        !            52: * sin(x) in fp0 and cos(x) in fp1.
        !            53: *
        !            54:
        !            55: DO_FUNC        IDNT    2,1 Motorola 040 Floating Point Software Package
        !            56:
        !            57:        section 8
        !            58:
        !            59:        include fpsp.h
        !            60:
        !            61:        xref    t_dz2
        !            62:        xref    t_operr
        !            63:        xref    t_inx2
        !            64:        xref    t_resdnrm
        !            65:        xref    dst_nan
        !            66:        xref    src_nan
        !            67:        xref    nrm_set
        !            68:        xref    sto_cos
        !            69:
        !            70:        xref    tblpre
        !            71:        xref    slognp1,slogn,slog10,slog2
        !            72:        xref    slognd,slog10d,slog2d
        !            73:        xref    smod,srem
        !            74:        xref    sscale
        !            75:        xref    smovcr
        !            76:
        !            77: PONE   dc.l    $3fff0000,$80000000,$00000000   ;+1
        !            78: MONE   dc.l    $bfff0000,$80000000,$00000000   ;-1
        !            79: PZERO  dc.l    $00000000,$00000000,$00000000   ;+0
        !            80: MZERO  dc.l    $80000000,$00000000,$00000000   ;-0
        !            81: PINF   dc.l    $7fff0000,$00000000,$00000000   ;+inf
        !            82: MINF   dc.l    $ffff0000,$00000000,$00000000   ;-inf
        !            83: QNAN   dc.l    $7fff0000,$ffffffff,$ffffffff   ;non-signaling nan
        !            84: PPIBY2  dc.l   $3FFF0000,$C90FDAA2,$2168C235   ;+PI/2
        !            85: MPIBY2  dc.l   $bFFF0000,$C90FDAA2,$2168C235   ;-PI/2
        !            86:
        !            87:        xdef    do_func
        !            88: do_func:
        !            89:        clr.b   CU_ONLY(a6)
        !            90: *
        !            91: * Check for fmovecr.  It does not follow the format of fp gen
        !            92: * unimplemented instructions.  The test is on the upper 6 bits;
        !            93: * if they are $17, the inst is fmovecr.  Call entry smovcr
        !            94: * directly.
        !            95: *
        !            96:        bfextu  CMDREG1B(a6){0:6},d0 ;get opclass and src fields
        !            97:        cmpi.l  #$17,d0         ;if op class and size fields are $17,
        !            98: *                              ;it is FMOVECR; if not, continue
        !            99:        bne.b   not_fmovecr
        !           100:        jmp     smovcr          ;fmovecr; jmp directly to emulation
        !           101:
        !           102: not_fmovecr:
        !           103:        move.w  CMDREG1B(a6),d0
        !           104:        and.l   #$7F,d0
        !           105:        cmpi.l  #$38,d0         ;if the extension is >= $38,
        !           106:        bge.b   serror          ;it is illegal
        !           107:        bfextu  STAG(a6){0:3},d1
        !           108:        lsl.l   #3,d0           ;make room for STAG
        !           109:        add.l   d1,d0           ;combine for final index into table
        !           110:        lea.l   tblpre,a1       ;start of monster jump table
        !           111:        move.l  (a1,d0.w*4),a1  ;real target address
        !           112:        lea.l   ETEMP(a6),a0    ;a0 is pointer to src op
        !           113:        move.l  USER_FPCR(a6),d1
        !           114:        and.l   #$FF,d1         ; discard all but rounding mode/prec
        !           115:        fmove.l #0,fpcr
        !           116:        jmp     (a1)
        !           117: *
        !           118: *      ERROR
        !           119: *
        !           120:        xdef    serror
        !           121: serror:
        !           122:        st.b    STORE_FLG(a6)
        !           123:        rts
        !           124: *
        !           125: * These routines load forced values into fp0.  They are called
        !           126: * by index into tbldo.
        !           127: *
        !           128: * Load a signed zero to fp0 and set inex2/ainex
        !           129: *
        !           130:        xdef    snzrinx
        !           131: snzrinx:
        !           132:        btst.b  #sign_bit,LOCAL_EX(a0)  ;get sign of source operand
        !           133:        bne.b   ld_mzinx        ;if negative, branch
        !           134:        bsr     ld_pzero        ;bsr so we can return and set inx
        !           135:        bra     t_inx2          ;now, set the inx for the next inst
        !           136: ld_mzinx:
        !           137:        bsr     ld_mzero        ;if neg, load neg zero, return here
        !           138:        bra     t_inx2          ;now, set the inx for the next inst
        !           139: *
        !           140: * Load a signed zero to fp0; do not set inex2/ainex
        !           141: *
        !           142:        xdef    szero
        !           143: szero:
        !           144:        btst.b  #sign_bit,LOCAL_EX(a0) ;get sign of source operand
        !           145:        bne     ld_mzero        ;if neg, load neg zero
        !           146:        bra     ld_pzero        ;load positive zero
        !           147: *
        !           148: * Load a signed infinity to fp0; do not set inex2/ainex
        !           149: *
        !           150:        xdef    sinf
        !           151: sinf:
        !           152:        btst.b  #sign_bit,LOCAL_EX(a0)  ;get sign of source operand
        !           153:        bne     ld_minf                 ;if negative branch
        !           154:        bra     ld_pinf
        !           155: *
        !           156: * Load a signed one to fp0; do not set inex2/ainex
        !           157: *
        !           158:        xdef    sone
        !           159: sone:
        !           160:        btst.b  #sign_bit,LOCAL_EX(a0)  ;check sign of source
        !           161:        bne     ld_mone
        !           162:        bra     ld_pone
        !           163: *
        !           164: * Load a signed pi/2 to fp0; do not set inex2/ainex
        !           165: *
        !           166:        xdef    spi_2
        !           167: spi_2:
        !           168:        btst.b  #sign_bit,LOCAL_EX(a0)  ;check sign of source
        !           169:        bne     ld_mpi2
        !           170:        bra     ld_ppi2
        !           171: *
        !           172: * Load either a +0 or +inf for plus/minus operand
        !           173: *
        !           174:        xdef    szr_inf
        !           175: szr_inf:
        !           176:        btst.b  #sign_bit,LOCAL_EX(a0)  ;check sign of source
        !           177:        bne     ld_pzero
        !           178:        bra     ld_pinf
        !           179: *
        !           180: * Result is either an operr or +inf for plus/minus operand
        !           181: * [Used by slogn, slognp1, slog10, and slog2]
        !           182: *
        !           183:        xdef    sopr_inf
        !           184: sopr_inf:
        !           185:        btst.b  #sign_bit,LOCAL_EX(a0)  ;check sign of source
        !           186:        bne     t_operr
        !           187:        bra     ld_pinf
        !           188: *
        !           189: *      FLOGNP1
        !           190: *
        !           191:        xdef    sslognp1
        !           192: sslognp1:
        !           193:        fmovem.x (a0),fp0
        !           194:        fcmp.b  #-1,fp0
        !           195:        fbgt    slognp1
        !           196:        fbeq    t_dz2           ;if = -1, divide by zero exception
        !           197:        fmove.l #0,FPSR         ;clr N flag
        !           198:        bra     t_operr         ;take care of operands < -1
        !           199: *
        !           200: *      FETOXM1
        !           201: *
        !           202:        xdef    setoxm1i
        !           203: setoxm1i:
        !           204:        btst.b  #sign_bit,LOCAL_EX(a0)  ;check sign of source
        !           205:        bne     ld_mone
        !           206:        bra     ld_pinf
        !           207: *
        !           208: *      FLOGN
        !           209: *
        !           210: * Test for 1.0 as an input argument, returning +zero.  Also check
        !           211: * the sign and return operr if negative.
        !           212: *
        !           213:        xdef    sslogn
        !           214: sslogn:
        !           215:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           216:        bne     t_operr         ;take care of operands < 0
        !           217:        cmpi.w  #$3fff,LOCAL_EX(a0) ;test for 1.0 input
        !           218:        bne     slogn
        !           219:        cmpi.l  #$80000000,LOCAL_HI(a0)
        !           220:        bne     slogn
        !           221:        tst.l   LOCAL_LO(a0)
        !           222:        bne     slogn
        !           223:        fmove.x PZERO,fp0
        !           224:        rts
        !           225:
        !           226:        xdef    sslognd
        !           227: sslognd:
        !           228:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           229:        beq     slognd
        !           230:        bra     t_operr         ;take care of operands < 0
        !           231:
        !           232: *
        !           233: *      FLOG10
        !           234: *
        !           235:        xdef    sslog10
        !           236: sslog10:
        !           237:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           238:        bne     t_operr         ;take care of operands < 0
        !           239:        cmpi.w  #$3fff,LOCAL_EX(a0) ;test for 1.0 input
        !           240:        bne     slog10
        !           241:        cmpi.l  #$80000000,LOCAL_HI(a0)
        !           242:        bne     slog10
        !           243:        tst.l   LOCAL_LO(a0)
        !           244:        bne     slog10
        !           245:        fmove.x PZERO,fp0
        !           246:        rts
        !           247:
        !           248:        xdef    sslog10d
        !           249: sslog10d:
        !           250:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           251:        beq     slog10d
        !           252:        bra     t_operr         ;take care of operands < 0
        !           253:
        !           254: *
        !           255: *      FLOG2
        !           256: *
        !           257:        xdef    sslog2
        !           258: sslog2:
        !           259:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           260:        bne     t_operr         ;take care of operands < 0
        !           261:        cmpi.w  #$3fff,LOCAL_EX(a0) ;test for 1.0 input
        !           262:        bne     slog2
        !           263:        cmpi.l  #$80000000,LOCAL_HI(a0)
        !           264:        bne     slog2
        !           265:        tst.l   LOCAL_LO(a0)
        !           266:        bne     slog2
        !           267:        fmove.x PZERO,fp0
        !           268:        rts
        !           269:
        !           270:        xdef    sslog2d
        !           271: sslog2d:
        !           272:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           273:        beq     slog2d
        !           274:        bra     t_operr         ;take care of operands < 0
        !           275:
        !           276: *
        !           277: *      FMOD
        !           278: *
        !           279: pmodt:
        !           280: *                              ;$21 fmod
        !           281: *                              ;dtag,stag
        !           282:        dc.l    smod            ;  00,00  norm,norm = normal
        !           283:        dc.l    smod_oper       ;  00,01  norm,zero = nan with operr
        !           284:        dc.l    smod_fpn        ;  00,10  norm,inf  = fpn
        !           285:        dc.l    smod_snan       ;  00,11  norm,nan  = nan
        !           286:        dc.l    smod_zro        ;  01,00  zero,norm = +-zero
        !           287:        dc.l    smod_oper       ;  01,01  zero,zero = nan with operr
        !           288:        dc.l    smod_zro        ;  01,10  zero,inf  = +-zero
        !           289:        dc.l    smod_snan       ;  01,11  zero,nan  = nan
        !           290:        dc.l    smod_oper       ;  10,00  inf,norm  = nan with operr
        !           291:        dc.l    smod_oper       ;  10,01  inf,zero  = nan with operr
        !           292:        dc.l    smod_oper       ;  10,10  inf,inf   = nan with operr
        !           293:        dc.l    smod_snan       ;  10,11  inf,nan   = nan
        !           294:        dc.l    smod_dnan       ;  11,00  nan,norm  = nan
        !           295:        dc.l    smod_dnan       ;  11,01  nan,zero  = nan
        !           296:        dc.l    smod_dnan       ;  11,10  nan,inf   = nan
        !           297:        dc.l    smod_dnan       ;  11,11  nan,nan   = nan
        !           298:
        !           299:        xdef    pmod
        !           300: pmod:
        !           301:        clr.b   FPSR_QBYTE(a6) ; clear quotient field
        !           302:        bfextu  STAG(a6){0:3},d0 ;stag = d0
        !           303:        bfextu  DTAG(a6){0:3},d1 ;dtag = d1
        !           304:
        !           305: *
        !           306: * Alias extended denorms to norms for the jump table.
        !           307: *
        !           308:        bclr.l  #2,d0
        !           309:        bclr.l  #2,d1
        !           310:
        !           311:        lsl.b   #2,d1
        !           312:        or.b    d0,d1           ;d1{3:2} = dtag, d1{1:0} = stag
        !           313: *                              ;Tag values:
        !           314: *                              ;00 = norm or denorm
        !           315: *                              ;01 = zero
        !           316: *                              ;10 = inf
        !           317: *                              ;11 = nan
        !           318:        lea     pmodt,a1
        !           319:        move.l  (a1,d1.w*4),a1
        !           320:        jmp     (a1)
        !           321:
        !           322: smod_snan:
        !           323:        bra     src_nan
        !           324: smod_dnan:
        !           325:        bra     dst_nan
        !           326: smod_oper:
        !           327:        bra     t_operr
        !           328: smod_zro:
        !           329:        move.b  ETEMP(a6),d1    ;get sign of src op
        !           330:        move.b  FPTEMP(a6),d0   ;get sign of dst op
        !           331:        eor.b   d0,d1           ;get exor of sign bits
        !           332:        btst.l  #7,d1           ;test for sign
        !           333:        beq.b   smod_zsn        ;if clr, do not set sign big
        !           334:        bset.b  #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
        !           335: smod_zsn:
        !           336:        btst.l  #7,d0           ;test if + or -
        !           337:        beq     ld_pzero        ;if pos then load +0
        !           338:        bra     ld_mzero        ;else neg load -0
        !           339:
        !           340: smod_fpn:
        !           341:        move.b  ETEMP(a6),d1    ;get sign of src op
        !           342:        move.b  FPTEMP(a6),d0   ;get sign of dst op
        !           343:        eor.b   d0,d1           ;get exor of sign bits
        !           344:        btst.l  #7,d1           ;test for sign
        !           345:        beq.b   smod_fsn        ;if clr, do not set sign big
        !           346:        bset.b  #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
        !           347: smod_fsn:
        !           348:        tst.b   DTAG(a6)        ;filter out denormal destination case
        !           349:        bpl.b   smod_nrm        ;
        !           350:        lea.l   FPTEMP(a6),a0   ;a0<- addr(FPTEMP)
        !           351:        bra     t_resdnrm       ;force UNFL(but exact) result
        !           352: smod_nrm:
        !           353:        fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
        !           354:        fmove.x FPTEMP(a6),fp0  ;return dest to fp0
        !           355:        rts
        !           356:
        !           357: *
        !           358: *      FREM
        !           359: *
        !           360: premt:
        !           361: *                              ;$25 frem
        !           362: *                              ;dtag,stag
        !           363:        dc.l    srem            ;  00,00  norm,norm = normal
        !           364:        dc.l    srem_oper       ;  00,01  norm,zero = nan with operr
        !           365:        dc.l    srem_fpn        ;  00,10  norm,inf  = fpn
        !           366:        dc.l    srem_snan       ;  00,11  norm,nan  = nan
        !           367:        dc.l    srem_zro        ;  01,00  zero,norm = +-zero
        !           368:        dc.l    srem_oper       ;  01,01  zero,zero = nan with operr
        !           369:        dc.l    srem_zro        ;  01,10  zero,inf  = +-zero
        !           370:        dc.l    srem_snan       ;  01,11  zero,nan  = nan
        !           371:        dc.l    srem_oper       ;  10,00  inf,norm  = nan with operr
        !           372:        dc.l    srem_oper       ;  10,01  inf,zero  = nan with operr
        !           373:        dc.l    srem_oper       ;  10,10  inf,inf   = nan with operr
        !           374:        dc.l    srem_snan       ;  10,11  inf,nan   = nan
        !           375:        dc.l    srem_dnan       ;  11,00  nan,norm  = nan
        !           376:        dc.l    srem_dnan       ;  11,01  nan,zero  = nan
        !           377:        dc.l    srem_dnan       ;  11,10  nan,inf   = nan
        !           378:        dc.l    srem_dnan       ;  11,11  nan,nan   = nan
        !           379:
        !           380:        xdef    prem
        !           381: prem:
        !           382:        clr.b   FPSR_QBYTE(a6)   ;clear quotient field
        !           383:        bfextu  STAG(a6){0:3},d0 ;stag = d0
        !           384:        bfextu  DTAG(a6){0:3},d1 ;dtag = d1
        !           385: *
        !           386: * Alias extended denorms to norms for the jump table.
        !           387: *
        !           388:        bclr    #2,d0
        !           389:        bclr    #2,d1
        !           390:
        !           391:        lsl.b   #2,d1
        !           392:        or.b    d0,d1           ;d1{3:2} = dtag, d1{1:0} = stag
        !           393: *                              ;Tag values:
        !           394: *                              ;00 = norm or denorm
        !           395: *                              ;01 = zero
        !           396: *                              ;10 = inf
        !           397: *                              ;11 = nan
        !           398:        lea     premt,a1
        !           399:        move.l  (a1,d1.w*4),a1
        !           400:        jmp     (a1)
        !           401:
        !           402: srem_snan:
        !           403:        bra     src_nan
        !           404: srem_dnan:
        !           405:        bra     dst_nan
        !           406: srem_oper:
        !           407:        bra     t_operr
        !           408: srem_zro:
        !           409:        move.b  ETEMP(a6),d1    ;get sign of src op
        !           410:        move.b  FPTEMP(a6),d0   ;get sign of dst op
        !           411:        eor.b   d0,d1           ;get exor of sign bits
        !           412:        btst.l  #7,d1           ;test for sign
        !           413:        beq.b   srem_zsn        ;if clr, do not set sign big
        !           414:        bset.b  #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
        !           415: srem_zsn:
        !           416:        btst.l  #7,d0           ;test if + or -
        !           417:        beq     ld_pzero        ;if pos then load +0
        !           418:        bra     ld_mzero        ;else neg load -0
        !           419:
        !           420: srem_fpn:
        !           421:        move.b  ETEMP(a6),d1    ;get sign of src op
        !           422:        move.b  FPTEMP(a6),d0   ;get sign of dst op
        !           423:        eor.b   d0,d1           ;get exor of sign bits
        !           424:        btst.l  #7,d1           ;test for sign
        !           425:        beq.b   srem_fsn        ;if clr, do not set sign big
        !           426:        bset.b  #q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
        !           427: srem_fsn:
        !           428:        tst.b   DTAG(a6)        ;filter out denormal destination case
        !           429:        bpl.b   srem_nrm        ;
        !           430:        lea.l   FPTEMP(a6),a0   ;a0<- addr(FPTEMP)
        !           431:        bra     t_resdnrm       ;force UNFL(but exact) result
        !           432: srem_nrm:
        !           433:        fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
        !           434:        fmove.x FPTEMP(a6),fp0  ;return dest to fp0
        !           435:        rts
        !           436: *
        !           437: *      FSCALE
        !           438: *
        !           439: pscalet:
        !           440: *                              ;$26 fscale
        !           441: *                              ;dtag,stag
        !           442:        dc.l    sscale          ;  00,00  norm,norm = result
        !           443:        dc.l    sscale          ;  00,01  norm,zero = fpn
        !           444:        dc.l    scl_opr         ;  00,10  norm,inf  = nan with operr
        !           445:        dc.l    scl_snan        ;  00,11  norm,nan  = nan
        !           446:        dc.l    scl_zro         ;  01,00  zero,norm = +-zero
        !           447:        dc.l    scl_zro         ;  01,01  zero,zero = +-zero
        !           448:        dc.l    scl_opr         ;  01,10  zero,inf  = nan with operr
        !           449:        dc.l    scl_snan        ;  01,11  zero,nan  = nan
        !           450:        dc.l    scl_inf         ;  10,00  inf,norm  = +-inf
        !           451:        dc.l    scl_inf         ;  10,01  inf,zero  = +-inf
        !           452:        dc.l    scl_opr         ;  10,10  inf,inf   = nan with operr
        !           453:        dc.l    scl_snan        ;  10,11  inf,nan   = nan
        !           454:        dc.l    scl_dnan        ;  11,00  nan,norm  = nan
        !           455:        dc.l    scl_dnan        ;  11,01  nan,zero  = nan
        !           456:        dc.l    scl_dnan        ;  11,10  nan,inf   = nan
        !           457:        dc.l    scl_dnan        ;  11,11  nan,nan   = nan
        !           458:
        !           459:        xdef    pscale
        !           460: pscale:
        !           461:        bfextu  STAG(a6){0:3},d0 ;stag in d0
        !           462:        bfextu  DTAG(a6){0:3},d1 ;dtag in d1
        !           463:        bclr.l  #2,d0           ;alias  denorm into norm
        !           464:        bclr.l  #2,d1           ;alias  denorm into norm
        !           465:        lsl.b   #2,d1
        !           466:        or.b    d0,d1           ;d1{4:2} = dtag, d1{1:0} = stag
        !           467: *                              ;dtag values     stag values:
        !           468: *                              ;000 = norm      00 = norm
        !           469: *                              ;001 = zero      01 = zero
        !           470: *                              ;010 = inf       10 = inf
        !           471: *                              ;011 = nan       11 = nan
        !           472: *                              ;100 = dnrm
        !           473: *
        !           474: *
        !           475:        lea.l   pscalet,a1      ;load start of jump table
        !           476:        move.l  (a1,d1.w*4),a1  ;load a1 with label depending on tag
        !           477:        jmp     (a1)            ;go to the routine
        !           478:
        !           479: scl_opr:
        !           480:        bra     t_operr
        !           481:
        !           482: scl_dnan:
        !           483:        bra     dst_nan
        !           484:
        !           485: scl_zro:
        !           486:        btst.b  #sign_bit,FPTEMP_EX(a6) ;test if + or -
        !           487:        beq     ld_pzero                ;if pos then load +0
        !           488:        bra     ld_mzero                ;if neg then load -0
        !           489: scl_inf:
        !           490:        btst.b  #sign_bit,FPTEMP_EX(a6) ;test if + or -
        !           491:        beq     ld_pinf                 ;if pos then load +inf
        !           492:        bra     ld_minf                 ;else neg load -inf
        !           493: scl_snan:
        !           494:        bra     src_nan
        !           495: *
        !           496: *      FSINCOS
        !           497: *
        !           498:        xdef    ssincosz
        !           499: ssincosz:
        !           500:        btst.b  #sign_bit,ETEMP(a6)     ;get sign
        !           501:        beq.b   sincosp
        !           502:        fmove.x MZERO,fp0
        !           503:        bra.b   sincoscom
        !           504: sincosp:
        !           505:        fmove.x PZERO,fp0
        !           506: sincoscom:
        !           507:        fmovem.x PONE,fp1       ;do not allow FPSR to be affected
        !           508:        bra     sto_cos         ;store cosine result
        !           509:
        !           510:        xdef    ssincosi
        !           511: ssincosi:
        !           512:        fmove.x QNAN,fp1        ;load NAN
        !           513:        bsr     sto_cos         ;store cosine result
        !           514:        fmove.x QNAN,fp0        ;load NAN
        !           515:        bra     t_operr
        !           516:
        !           517:        xdef    ssincosnan
        !           518: ssincosnan:
        !           519:        move.l  ETEMP_EX(a6),FP_SCR1(a6)
        !           520:        move.l  ETEMP_HI(a6),FP_SCR1+4(a6)
        !           521:        move.l  ETEMP_LO(a6),FP_SCR1+8(a6)
        !           522:        bset.b  #signan_bit,FP_SCR1+4(a6)
        !           523:        fmovem.x FP_SCR1(a6),fp1
        !           524:        bsr     sto_cos
        !           525:        bra     src_nan
        !           526: *
        !           527: * This code forces default values for the zero, inf, and nan cases
        !           528: * in the transcendentals code.  The CC bits must be set in the
        !           529: * stacked FPSR to be correctly reported.
        !           530: *
        !           531: ***Returns +PI/2
        !           532:        xdef    ld_ppi2
        !           533: ld_ppi2:
        !           534:        fmove.x PPIBY2,fp0              ;load +pi/2
        !           535:        bra     t_inx2                  ;set inex2 exc
        !           536:
        !           537: ***Returns -PI/2
        !           538:        xdef    ld_mpi2
        !           539: ld_mpi2:
        !           540:        fmove.x MPIBY2,fp0              ;load -pi/2
        !           541:        or.l    #neg_mask,USER_FPSR(a6) ;set N bit
        !           542:        bra     t_inx2                  ;set inex2 exc
        !           543:
        !           544: ***Returns +inf
        !           545:        xdef    ld_pinf
        !           546: ld_pinf:
        !           547:        fmove.x PINF,fp0                ;load +inf
        !           548:        or.l    #inf_mask,USER_FPSR(a6) ;set I bit
        !           549:        rts
        !           550:
        !           551: ***Returns -inf
        !           552:        xdef    ld_minf
        !           553: ld_minf:
        !           554:        fmove.x MINF,fp0                ;load -inf
        !           555:        or.l    #neg_mask+inf_mask,USER_FPSR(a6)        ;set N and I bits
        !           556:        rts
        !           557:
        !           558: ***Returns +1
        !           559:        xdef    ld_pone
        !           560: ld_pone:
        !           561:        fmove.x PONE,fp0                ;load +1
        !           562:        rts
        !           563:
        !           564: ***Returns -1
        !           565:        xdef    ld_mone
        !           566: ld_mone:
        !           567:        fmove.x MONE,fp0                ;load -1
        !           568:        or.l    #neg_mask,USER_FPSR(a6) ;set N bit
        !           569:        rts
        !           570:
        !           571: ***Returns +0
        !           572:        xdef    ld_pzero
        !           573: ld_pzero:
        !           574:        fmove.x PZERO,fp0               ;load +0
        !           575:        or.l    #z_mask,USER_FPSR(a6)   ;set Z bit
        !           576:        rts
        !           577:
        !           578: ***Returns -0
        !           579:        xdef    ld_mzero
        !           580: ld_mzero:
        !           581:        fmove.x MZERO,fp0               ;load -0
        !           582:        or.l    #neg_mask+z_mask,USER_FPSR(a6)  ;set N and Z bits
        !           583:        rts
        !           584:
        !           585:        end

CVSweb