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

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

1.1     ! nbrk        1: *      $OpenBSD: bugfix.sa,v 1.2 1996/05/29 21:05:26 niklas Exp $
        !             2: *      $NetBSD: bugfix.sa,v 1.3 1994/10/26 07:48:55 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: *      bugfix.sa 3.2 1/31/91
        !            36: *
        !            37: *
        !            38: *      This file contains workarounds for bugs in the 040
        !            39: *      relating to the Floating-Point Software Package (FPSP)
        !            40: *
        !            41: *      Fixes for bugs: 1238
        !            42: *
        !            43: *      Bug: 1238
        !            44: *
        !            45: *
        !            46: *    /* The following dirty_bit clear should be left in
        !            47: *     * the handler permanently to improve throughput.
        !            48: *     * The dirty_bits are located at bits [23:16] in
        !            49: *     * longword $08 in the busy frame $4x60.  Bit 16
        !            50: *     * corresponds to FP0, bit 17 corresponds to FP1,
        !            51: *     * and so on.
        !            52: *     */
        !            53: *    if  (E3_exception_just_serviced)   {
        !            54: *         dirty_bit[cmdreg3b[9:7]] = 0;
        !            55: *         }
        !            56: *
        !            57: *    if  (fsave_format_version != $40)  {goto NOFIX}
        !            58: *
        !            59: *    if !(E3_exception_just_serviced)   {goto NOFIX}
        !            60: *    if  (cupc == 0000000)              {goto NOFIX}
        !            61: *    if  ((cmdreg1b[15:13] != 000) &&
        !            62: *         (cmdreg1b[15:10] != 010001))  {goto NOFIX}
        !            63: *    if (((cmdreg1b[15:13] != 000) || ((cmdreg1b[12:10] != cmdreg2b[9:7]) &&
        !            64: *                                    (cmdreg1b[12:10] != cmdreg3b[9:7]))  ) &&
        !            65: *       ((cmdreg1b[ 9: 7] != cmdreg2b[9:7]) &&
        !            66: *        (cmdreg1b[ 9: 7] != cmdreg3b[9:7])) )  {goto NOFIX}
        !            67: *
        !            68: *    /* Note: for 6d43b or 8d43b, you may want to add the following code
        !            69: *     * to get better coverage.  (If you do not insert this code, the part
        !            70: *     * won't lock up; it will simply get the wrong answer.)
        !            71: *     * Do NOT insert this code for 10d43b or later parts.
        !            72: *     *
        !            73: *     *  if (fpiarcu == integer stack return address) {
        !            74: *     *       cupc = 0000000;
        !            75: *     *       goto NOFIX;
        !            76: *     *       }
        !            77: *     */
        !            78: *
        !            79: *    if (cmdreg1b[15:13] != 000)   {goto FIX_OPCLASS2}
        !            80: *    FIX_OPCLASS0:
        !            81: *    if (((cmdreg1b[12:10] == cmdreg2b[9:7]) ||
        !            82: *       (cmdreg1b[ 9: 7] == cmdreg2b[9:7])) &&
        !            83: *      (cmdreg1b[12:10] != cmdreg3b[9:7]) &&
        !            84: *      (cmdreg1b[ 9: 7] != cmdreg3b[9:7]))  {  /* xu conflict only */
        !            85: *      /* We execute the following code if there is an
        !            86: *         xu conflict and NOT an nu conflict */
        !            87: *
        !            88: *      /* first save some values on the fsave frame */
        !            89: *      stag_temp     = STAG[fsave_frame];
        !            90: *      cmdreg1b_temp = CMDREG1B[fsave_frame];
        !            91: *      dtag_temp     = DTAG[fsave_frame];
        !            92: *      ete15_temp    = ETE15[fsave_frame];
        !            93: *
        !            94: *      CUPC[fsave_frame] = 0000000;
        !            95: *      FRESTORE
        !            96: *      FSAVE
        !            97: *
        !            98: *      /* If the xu instruction is exceptional, we punt.
        !            99: *       * Otherwise, we would have to include OVFL/UNFL handler
        !           100: *       * code here to get the correct answer.
        !           101: *       */
        !           102: *      if (fsave_frame_format == $4060) {goto KILL_PROCESS}
        !           103: *
        !           104: *      fsave_frame = /* build a long frame of all zeros */
        !           105: *      fsave_frame_format = $4060;  /* label it as long frame */
        !           106: *
        !           107: *      /* load it with the temps we saved */
        !           108: *      STAG[fsave_frame]     =  stag_temp;
        !           109: *      CMDREG1B[fsave_frame] =  cmdreg1b_temp;
        !           110: *      DTAG[fsave_frame]     =  dtag_temp;
        !           111: *      ETE15[fsave_frame]    =  ete15_temp;
        !           112: *
        !           113: *      /* Make sure that the cmdreg3b dest reg is not going to
        !           114: *       * be destroyed by a FMOVEM at the end of all this code.
        !           115: *       * If it is, you should move the current value of the reg
        !           116: *       * onto the stack so that the reg will loaded with that value.
        !           117: *       */
        !           118: *
        !           119: *      /* All done.  Proceed with the code below */
        !           120: *    }
        !           121: *
        !           122: *    etemp  = FP_reg_[cmdreg1b[12:10]];
        !           123: *    ete15  = ~ete14;
        !           124: *    cmdreg1b[15:10] = 010010;
        !           125: *    clear(bug_flag_procIDxxxx);
        !           126: *    FRESTORE and return;
        !           127: *
        !           128: *
        !           129: *    FIX_OPCLASS2:
        !           130: *    if ((cmdreg1b[9:7] == cmdreg2b[9:7]) &&
        !           131: *      (cmdreg1b[9:7] != cmdreg3b[9:7]))  {  /* xu conflict only */
        !           132: *      /* We execute the following code if there is an
        !           133: *         xu conflict and NOT an nu conflict */
        !           134: *
        !           135: *      /* first save some values on the fsave frame */
        !           136: *      stag_temp     = STAG[fsave_frame];
        !           137: *      cmdreg1b_temp = CMDREG1B[fsave_frame];
        !           138: *      dtag_temp     = DTAG[fsave_frame];
        !           139: *      ete15_temp    = ETE15[fsave_frame];
        !           140: *      etemp_temp    = ETEMP[fsave_frame];
        !           141: *
        !           142: *      CUPC[fsave_frame] = 0000000;
        !           143: *      FRESTORE
        !           144: *      FSAVE
        !           145: *
        !           146: *
        !           147: *      /* If the xu instruction is exceptional, we punt.
        !           148: *       * Otherwise, we would have to include OVFL/UNFL handler
        !           149: *       * code here to get the correct answer.
        !           150: *       */
        !           151: *      if (fsave_frame_format == $4060) {goto KILL_PROCESS}
        !           152: *
        !           153: *      fsave_frame = /* build a long frame of all zeros */
        !           154: *      fsave_frame_format = $4060;  /* label it as long frame */
        !           155: *
        !           156: *      /* load it with the temps we saved */
        !           157: *      STAG[fsave_frame]     =  stag_temp;
        !           158: *      CMDREG1B[fsave_frame] =  cmdreg1b_temp;
        !           159: *      DTAG[fsave_frame]     =  dtag_temp;
        !           160: *      ETE15[fsave_frame]    =  ete15_temp;
        !           161: *      ETEMP[fsave_frame]    =  etemp_temp;
        !           162: *
        !           163: *      /* Make sure that the cmdreg3b dest reg is not going to
        !           164: *       * be destroyed by a FMOVEM at the end of all this code.
        !           165: *       * If it is, you should move the current value of the reg
        !           166: *       * onto the stack so that the reg will loaded with that value.
        !           167: *       */
        !           168: *
        !           169: *      /* All done.  Proceed with the code below */
        !           170: *    }
        !           171: *
        !           172: *    if (etemp_exponent == min_sgl)   etemp_exponent = min_dbl;
        !           173: *    if (etemp_exponent == max_sgl)   etemp_exponent = max_dbl;
        !           174: *    cmdreg1b[15:10] = 010101;
        !           175: *    clear(bug_flag_procIDxxxx);
        !           176: *    FRESTORE and return;
        !           177: *
        !           178: *
        !           179: *    NOFIX:
        !           180: *    clear(bug_flag_procIDxxxx);
        !           181: *    FRESTORE and return;
        !           182: *
        !           183:
        !           184: BUGFIX    IDNT    2,1 Motorola 040 Floating Point Software Package
        !           185:
        !           186:        section 8
        !           187:
        !           188:        include fpsp.h
        !           189:
        !           190:        xref    fpsp_fmt_error
        !           191:
        !           192:        xdef    b1238_fix
        !           193: b1238_fix:
        !           194: *
        !           195: * This code is entered only on completion of the handling of an
        !           196: * nu-generated ovfl, unfl, or inex exception.  If the version
        !           197: * number of the fsave is not $40, this handler is not necessary.
        !           198: * Simply branch to fix_done and exit normally.
        !           199: *
        !           200:        cmpi.b  #VER_40,4(a7)
        !           201:        bne.w   fix_done
        !           202: *
        !           203: * Test for cu_savepc equal to zero.  If not, this is not a bug
        !           204: * #1238 case.
        !           205: *
        !           206:        move.b  CU_SAVEPC(a6),d0
        !           207:        andi.b  #$FE,d0
        !           208:        beq     fix_done        ;if zero, this is not bug #1238
        !           209:
        !           210: *
        !           211: * Test the register conflict aspect.  If opclass0, check for
        !           212: * cu src equal to xu dest or equal to nu dest.  If so, go to
        !           213: * op0.  Else, or if opclass2, check for cu dest equal to
        !           214: * xu dest or equal to nu dest.  If so, go to tst_opcl.  Else,
        !           215: * exit, it is not the bug case.
        !           216: *
        !           217: * Check for opclass 0.  If not, go and check for opclass 2 and sgl.
        !           218: *
        !           219:        move.w  CMDREG1B(a6),d0
        !           220:        andi.w  #$E000,d0               ;strip all but opclass
        !           221:        bne     op2sgl                  ;not opclass 0, check op2
        !           222: *
        !           223: * Check for cu and nu register conflict.  If one exists, this takes
        !           224: * priority over a cu and xu conflict.
        !           225: *
        !           226:        bfextu  CMDREG1B(a6){3:3},d0    ;get 1st src
        !           227:        bfextu  CMDREG3B(a6){6:3},d1    ;get 3rd dest
        !           228:        cmp.b   d0,d1
        !           229:        beq.b   op0                     ;if equal, continue bugfix
        !           230: *
        !           231: * Check for cu dest equal to nu dest.  If so, go and fix the
        !           232: * bug condition.  Otherwise, exit.
        !           233: *
        !           234:        bfextu  CMDREG1B(a6){6:3},d0    ;get 1st dest
        !           235:        cmp.b   d0,d1                   ;cmp 1st dest with 3rd dest
        !           236:        beq.b   op0                     ;if equal, continue bugfix
        !           237: *
        !           238: * Check for cu and xu register conflict.
        !           239: *
        !           240:        bfextu  CMDREG2B(a6){6:3},d1    ;get 2nd dest
        !           241:        cmp.b   d0,d1                   ;cmp 1st dest with 2nd dest
        !           242:        beq.b   op0_xu                  ;if equal, continue bugfix
        !           243:        bfextu  CMDREG1B(a6){3:3},d0    ;get 1st src
        !           244:        cmp.b   d0,d1                   ;cmp 1st src with 2nd dest
        !           245:        beq     op0_xu
        !           246:        bne     fix_done                ;if the reg checks fail, exit
        !           247: *
        !           248: * We have the opclass 0 situation.
        !           249: *
        !           250: op0:
        !           251:        bfextu  CMDREG1B(a6){3:3},d0    ;get source register no
        !           252:        move.l  #7,d1
        !           253:        sub.l   d0,d1
        !           254:        clr.l   d0
        !           255:        bset.l  d1,d0
        !           256:        fmovem.x d0,ETEMP(a6)           ;load source to ETEMP
        !           257:
        !           258:        move.b  #$12,d0
        !           259:        bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, extended
        !           260: *
        !           261: *      Set ETEMP exponent bit 15 as the opposite of ete14
        !           262: *
        !           263:        btst    #6,ETEMP_EX(a6)         ;check etemp exponent bit 14
        !           264:        beq     setete15
        !           265:        bclr    #etemp15_bit,STAG(a6)
        !           266:        bra     finish
        !           267: setete15:
        !           268:        bset    #etemp15_bit,STAG(a6)
        !           269:        bra     finish
        !           270:
        !           271: *
        !           272: * We have the case in which a conflict exists between the cu src or
        !           273: * dest and the dest of the xu.  We must clear the instruction in
        !           274: * the cu and restore the state, allowing the instruction in the
        !           275: * xu to complete.  Remember, the instruction in the nu
        !           276: * was exceptional, and was completed by the appropriate handler.
        !           277: * If the result of the xu instruction is not exceptional, we can
        !           278: * restore the instruction from the cu to the frame and continue
        !           279: * processing the original exception.  If the result is also
        !           280: * exceptional, we choose to kill the process.
        !           281: *
        !           282: *      Items saved from the stack:
        !           283: *
        !           284: *              $3c stag     - L_SCR1
        !           285: *              $40 cmdreg1b - L_SCR2
        !           286: *              $44 dtag     - L_SCR3
        !           287: *
        !           288: * The cu savepc is set to zero, and the frame is restored to the
        !           289: * fpu.
        !           290: *
        !           291: op0_xu:
        !           292:        move.l  STAG(a6),L_SCR1(a6)
        !           293:        move.l  CMDREG1B(a6),L_SCR2(a6)
        !           294:        move.l  DTAG(a6),L_SCR3(a6)
        !           295:        andi.l  #$e0000000,L_SCR3(a6)
        !           296:        clr.b   CU_SAVEPC(a6)
        !           297:        move.l  (a7)+,d1                ;save return address from bsr
        !           298:        frestore (a7)+
        !           299:        fsave   -(a7)
        !           300: *
        !           301: * Check if the instruction which just completed was exceptional.
        !           302: *
        !           303:        cmp.w   #$4060,(a7)
        !           304:        beq     op0_xb
        !           305: *
        !           306: * It is necessary to isolate the result of the instruction in the
        !           307: * xu if it is to fp0 - fp3 and write that value to the USER_FPn
        !           308: * locations on the stack.  The correct destination register is in
        !           309: * cmdreg2b.
        !           310: *
        !           311:        bfextu  CMDREG2B(a6){6:3},d0    ;get dest register no
        !           312:        cmpi.l  #3,d0
        !           313:        bgt.b   op0_xi
        !           314:        beq.b   op0_fp3
        !           315:        cmpi.l  #1,d0
        !           316:        blt.b   op0_fp0
        !           317:        beq.b   op0_fp1
        !           318: op0_fp2:
        !           319:        fmovem.x fp2,USER_FP2(a6)
        !           320:        bra.b   op0_xi
        !           321: op0_fp1:
        !           322:        fmovem.x fp1,USER_FP1(a6)
        !           323:        bra.b   op0_xi
        !           324: op0_fp0:
        !           325:        fmovem.x fp0,USER_FP0(a6)
        !           326:        bra.b   op0_xi
        !           327: op0_fp3:
        !           328:        fmovem.x fp3,USER_FP3(a6)
        !           329: *
        !           330: * The frame returned is idle.  We must build a busy frame to hold
        !           331: * the cu state information and setup etemp.
        !           332: *
        !           333: op0_xi:
        !           334:        move.l  #22,d0          ;clear 23 lwords
        !           335:        clr.l   (a7)
        !           336: op0_loop:
        !           337:        clr.l   -(a7)
        !           338:        dbf     d0,op0_loop
        !           339:        move.l  #$40600000,-(a7)
        !           340:        move.l  L_SCR1(a6),STAG(a6)
        !           341:        move.l  L_SCR2(a6),CMDREG1B(a6)
        !           342:        move.l  L_SCR3(a6),DTAG(a6)
        !           343:        move.b  #$6,CU_SAVEPC(a6)
        !           344:        move.l  d1,-(a7)                ;return bsr return address
        !           345:        bfextu  CMDREG1B(a6){3:3},d0    ;get source register no
        !           346:        move.l  #7,d1
        !           347:        sub.l   d0,d1
        !           348:        clr.l   d0
        !           349:        bset.l  d1,d0
        !           350:        fmovem.x d0,ETEMP(a6)           ;load source to ETEMP
        !           351:
        !           352:        move.b  #$12,d0
        !           353:        bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, extended
        !           354: *
        !           355: *      Set ETEMP exponent bit 15 as the opposite of ete14
        !           356: *
        !           357:        btst    #6,ETEMP_EX(a6)         ;check etemp exponent bit 14
        !           358:        beq     op0_sete15
        !           359:        bclr    #etemp15_bit,STAG(a6)
        !           360:        bra     finish
        !           361: op0_sete15:
        !           362:        bset    #etemp15_bit,STAG(a6)
        !           363:        bra     finish
        !           364:
        !           365: *
        !           366: * The frame returned is busy.  It is not possible to reconstruct
        !           367: * the code sequence to allow completion.  We will jump to
        !           368: * fpsp_fmt_error and allow the kernel to kill the process.
        !           369: *
        !           370: op0_xb:
        !           371:        jmp     fpsp_fmt_error
        !           372:
        !           373: *
        !           374: * Check for opclass 2 and single size.  If not both, exit.
        !           375: *
        !           376: op2sgl:
        !           377:        move.w  CMDREG1B(a6),d0
        !           378:        andi.w  #$FC00,d0               ;strip all but opclass and size
        !           379:        cmpi.w  #$4400,d0               ;test for opclass 2 and size=sgl
        !           380:        bne     fix_done                ;if not, it is not bug 1238
        !           381: *
        !           382: * Check for cu dest equal to nu dest or equal to xu dest, with
        !           383: * a cu and nu conflict taking priority an nu conflict.  If either,
        !           384: * go and fix the bug condition.  Otherwise, exit.
        !           385: *
        !           386:        bfextu  CMDREG1B(a6){6:3},d0    ;get 1st dest
        !           387:        bfextu  CMDREG3B(a6){6:3},d1    ;get 3rd dest
        !           388:        cmp.b   d0,d1                   ;cmp 1st dest with 3rd dest
        !           389:        beq     op2_com                 ;if equal, continue bugfix
        !           390:        bfextu  CMDREG2B(a6){6:3},d1    ;get 2nd dest
        !           391:        cmp.b   d0,d1                   ;cmp 1st dest with 2nd dest
        !           392:        bne     fix_done                ;if the reg checks fail, exit
        !           393: *
        !           394: * We have the case in which a conflict exists between the cu src or
        !           395: * dest and the dest of the xu.  We must clear the instruction in
        !           396: * the cu and restore the state, allowing the instruction in the
        !           397: * xu to complete.  Remember, the instruction in the nu
        !           398: * was exceptional, and was completed by the appropriate handler.
        !           399: * If the result of the xu instruction is not exceptional, we can
        !           400: * restore the instruction from the cu to the frame and continue
        !           401: * processing the original exception.  If the result is also
        !           402: * exceptional, we choose to kill the process.
        !           403: *
        !           404: *      Items saved from the stack:
        !           405: *
        !           406: *              $3c stag     - L_SCR1
        !           407: *              $40 cmdreg1b - L_SCR2
        !           408: *              $44 dtag     - L_SCR3
        !           409: *              etemp        - FP_SCR2
        !           410: *
        !           411: * The cu savepc is set to zero, and the frame is restored to the
        !           412: * fpu.
        !           413: *
        !           414: op2_xu:
        !           415:        move.l  STAG(a6),L_SCR1(a6)
        !           416:        move.l  CMDREG1B(a6),L_SCR2(a6)
        !           417:        move.l  DTAG(a6),L_SCR3(a6)
        !           418:        andi.l  #$e0000000,L_SCR3(a6)
        !           419:        clr.b   CU_SAVEPC(a6)
        !           420:        move.l  ETEMP(a6),FP_SCR2(a6)
        !           421:        move.l  ETEMP_HI(a6),FP_SCR2+4(a6)
        !           422:        move.l  ETEMP_LO(a6),FP_SCR2+8(a6)
        !           423:        move.l  (a7)+,d1                ;save return address from bsr
        !           424:        frestore (a7)+
        !           425:        fsave   -(a7)
        !           426: *
        !           427: * Check if the instruction which just completed was exceptional.
        !           428: *
        !           429:        cmp.w   #$4060,(a7)
        !           430:        beq     op2_xb
        !           431: *
        !           432: * It is necessary to isolate the result of the instruction in the
        !           433: * xu if it is to fp0 - fp3 and write that value to the USER_FPn
        !           434: * locations on the stack.  The correct destination register is in
        !           435: * cmdreg2b.
        !           436: *
        !           437:        bfextu  CMDREG2B(a6){6:3},d0    ;get dest register no
        !           438:        cmpi.l  #3,d0
        !           439:        bgt.b   op2_xi
        !           440:        beq.b   op2_fp3
        !           441:        cmpi.l  #1,d0
        !           442:        blt.b   op2_fp0
        !           443:        beq.b   op2_fp1
        !           444: op2_fp2:
        !           445:        fmovem.x fp2,USER_FP2(a6)
        !           446:        bra.b   op2_xi
        !           447: op2_fp1:
        !           448:        fmovem.x fp1,USER_FP1(a6)
        !           449:        bra.b   op2_xi
        !           450: op2_fp0:
        !           451:        fmovem.x fp0,USER_FP0(a6)
        !           452:        bra.b   op2_xi
        !           453: op2_fp3:
        !           454:        fmovem.x fp3,USER_FP3(a6)
        !           455: *
        !           456: * The frame returned is idle.  We must build a busy frame to hold
        !           457: * the cu state information and fix up etemp.
        !           458: *
        !           459: op2_xi:
        !           460:        move.l  #22,d0          ;clear 23 lwords
        !           461:        clr.l   (a7)
        !           462: op2_loop:
        !           463:        clr.l   -(a7)
        !           464:        dbf     d0,op2_loop
        !           465:        move.l  #$40600000,-(a7)
        !           466:        move.l  L_SCR1(a6),STAG(a6)
        !           467:        move.l  L_SCR2(a6),CMDREG1B(a6)
        !           468:        move.l  L_SCR3(a6),DTAG(a6)
        !           469:        move.b  #$6,CU_SAVEPC(a6)
        !           470:        move.l  FP_SCR2(a6),ETEMP(a6)
        !           471:        move.l  FP_SCR2+4(a6),ETEMP_HI(a6)
        !           472:        move.l  FP_SCR2+8(a6),ETEMP_LO(a6)
        !           473:        move.l  d1,-(a7)
        !           474:        bra     op2_com
        !           475:
        !           476: *
        !           477: * We have the opclass 2 single source situation.
        !           478: *
        !           479: op2_com:
        !           480:        move.b  #$15,d0
        !           481:        bfins   d0,CMDREG1B(a6){0:6}    ;opclass 2, double
        !           482:
        !           483:        cmp.w   #$407F,ETEMP_EX(a6)     ;single +max
        !           484:        bne.b   case2
        !           485:        move.w  #$43FF,ETEMP_EX(a6)     ;to double +max
        !           486:        bra     finish
        !           487: case2:
        !           488:        cmp.w   #$C07F,ETEMP_EX(a6)     ;single -max
        !           489:        bne.b   case3
        !           490:        move.w  #$C3FF,ETEMP_EX(a6)     ;to double -max
        !           491:        bra     finish
        !           492: case3:
        !           493:        cmp.w   #$3F80,ETEMP_EX(a6)     ;single +min
        !           494:        bne.b   case4
        !           495:        move.w  #$3C00,ETEMP_EX(a6)     ;to double +min
        !           496:        bra     finish
        !           497: case4:
        !           498:        cmp.w   #$BF80,ETEMP_EX(a6)     ;single -min
        !           499:        bne     fix_done
        !           500:        move.w  #$BC00,ETEMP_EX(a6)     ;to double -min
        !           501:        bra     finish
        !           502: *
        !           503: * The frame returned is busy.  It is not possible to reconstruct
        !           504: * the code sequence to allow completion.  fpsp_fmt_error causes
        !           505: * an fline illegal instruction to be executed.
        !           506: *
        !           507: * You should replace the jump to fpsp_fmt_error with a jump
        !           508: * to the entry point used to kill a process.
        !           509: *
        !           510: op2_xb:
        !           511:        jmp     fpsp_fmt_error
        !           512:
        !           513: *
        !           514: * Enter here if the case is not of the situations affected by
        !           515: * bug #1238, or if the fix is completed, and exit.
        !           516: *
        !           517: finish:
        !           518: fix_done:
        !           519:        rts
        !           520:
        !           521:        end

CVSweb