Annotation of uae/src/fpp.c, revision 1.1.1.3

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * MC68881 emulation
                      5:   *
                      6:   * Copyright 1996 Herman ten Brugge
                      7:   */
                      8: 
                      9: #include <math.h>
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: 
                     14: #include "config.h"
                     15: #include "options.h"
                     16: #include "memory.h"
                     17: #include "custom.h"
1.1.1.2   root       18: #include "readcpu.h"
1.1       root       19: #include "newcpu.h"
                     20: #include "ersatz.h"
                     21: 
1.1.1.3 ! root       22: #if 1
1.1       root       23: 
                     24: #define        DEBUG_FPP       0
                     25: 
                     26: /* single   : S  8*E 23*F */
                     27: /* double   : S 11*E 52*F */
                     28: /* extended : S 15*E 64*F */
                     29: /* E = 0 & F = 0 -> 0 */
                     30: /* E = MAX & F = 0 -> Infin */
                     31: /* E = MAX & F # 0 -> NotANumber */
                     32: /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */
                     33: 
1.1.1.3 ! root       34: static __inline__ double to_single (uae_u32 value)
1.1       root       35: {
1.1.1.3 ! root       36:     double frac;
1.1       root       37: 
1.1.1.3 ! root       38:     if ((value & 0x7fffffff) == 0)
        !            39:        return (0.0);
        !            40:     frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0;
        !            41:     if (value & 0x80000000)
        !            42:        frac = -frac;
        !            43:     return (ldexp (frac, ((value >> 23) & 0xff) - 127));
1.1       root       44: }
                     45: 
1.1.1.3 ! root       46: static __inline__ uae_u32 from_single (double src)
1.1       root       47: {
1.1.1.3 ! root       48:     int expon;
        !            49:     uae_u32 tmp;
        !            50:     double frac;
        !            51: 
        !            52:     if (src == 0.0)
        !            53:        return 0;
        !            54:     if (src < 0) {
        !            55:        tmp = 0x80000000;
        !            56:        src = -src;
        !            57:     } else {
        !            58:        tmp = 0;
        !            59:     }
        !            60:     frac = frexp (src, &expon);
        !            61:     frac += 0.5 / 16777216.0;
        !            62:     if (frac >= 1.0) {
        !            63:        frac /= 2.0;
        !            64:        expon++;
        !            65:     }
        !            66:     return (tmp | (((expon + 127 - 1) & 0xff) << 23) |
        !            67:            (((int) (frac * 16777216.0)) & 0x7fffff));
1.1       root       68: }
                     69: 
1.1.1.3 ! root       70: static __inline__ double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1       root       71: {
1.1.1.3 ! root       72:     double frac;
1.1       root       73: 
1.1.1.3 ! root       74:     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
        !            75:        return 0.0;
        !            76:     frac = (double) wrd2 / 2147483648.0 +
        !            77:        (double) wrd3 / 9223372036854775808.0;
        !            78:     if (wrd1 & 0x80000000)
        !            79:        frac = -frac;
        !            80:     return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
1.1       root       81: }
                     82: 
1.1.1.3 ! root       83: static __inline__ void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1       root       84: {
1.1.1.3 ! root       85:     int expon;
        !            86:     double frac;
1.1       root       87: 
1.1.1.3 ! root       88:     if (src == 0.0) {
        !            89:        *wrd1 = 0;
        !            90:        *wrd2 = 0;
        !            91:        *wrd3 = 0;
        !            92:        return;
        !            93:     }
        !            94:     if (src < 0) {
        !            95:        *wrd1 = 0x80000000;
        !            96:        src = -src;
        !            97:     } else {
        !            98:        *wrd1 = 0;
        !            99:     }
        !           100:     frac = frexp (src, &expon);
        !           101:     frac += 0.5 / 18446744073709551616.0;
        !           102:     if (frac >= 1.0) {
        !           103:        frac /= 2.0;
        !           104:        expon++;
        !           105:     }
        !           106:     *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
        !           107:     *wrd2 = (uae_u32) (frac * 4294967296.0);
        !           108:     *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0);
1.1       root      109: }
                    110: 
1.1.1.3 ! root      111: static __inline__ double to_double(uae_u32 wrd1, uae_u32 wrd2)
1.1       root      112: {
1.1.1.3 ! root      113:     double frac;
1.1       root      114: 
1.1.1.3 ! root      115:     if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
        !           116:        return 0.0;
        !           117:     frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 +
        !           118:        (double) wrd2 / 4503599627370496.0;
        !           119:     if (wrd1 & 0x80000000)
        !           120:        frac = -frac;
        !           121:     return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023);
1.1       root      122: }
                    123: 
1.1.1.3 ! root      124: static __inline__ void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
1.1       root      125: {
1.1.1.3 ! root      126:     int expon;
        !           127:     int tmp;
        !           128:     double frac;
        !           129: 
        !           130:     if (src == 0.0) {
        !           131:        *wrd1 = 0;
        !           132:        *wrd2 = 0;
        !           133:        return;
        !           134:     }
        !           135:     if (src < 0) {
        !           136:        *wrd1 = 0x80000000;
        !           137:        src = -src;
        !           138:     } else {
        !           139:        *wrd1 = 0;
        !           140:     }
        !           141:     frac = frexp (src, &expon);
        !           142:     frac += 0.5 / 9007199254740992.0;
        !           143:     if (frac >= 1.0) {
        !           144:        frac /= 2.0;
        !           145:        expon++;
        !           146:     }
        !           147:     tmp = (uae_u32) (frac * 2097152.0);
        !           148:     *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff);
        !           149:     *wrd2 = (uae_u32) (frac * 9007199254740992.0 - tmp * 4294967296.0);
1.1       root      150: }
                    151: 
1.1.1.3 ! root      152: static __inline__ double to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1       root      153: {
1.1.1.3 ! root      154:     double d;
        !           155:     char *cp;
        !           156:     char str[100];
        !           157: 
        !           158:     cp = str;
        !           159:     if (wrd1 & 0x80000000)
        !           160:        *cp++ = '-';
        !           161:     *cp++ = (wrd1 & 0xf) + '0';
        !           162:     *cp++ = '.';
        !           163:     *cp++ = ((wrd2 >> 28) & 0xf) + '0';
        !           164:     *cp++ = ((wrd2 >> 24) & 0xf) + '0';
        !           165:     *cp++ = ((wrd2 >> 20) & 0xf) + '0';
        !           166:     *cp++ = ((wrd2 >> 16) & 0xf) + '0';
        !           167:     *cp++ = ((wrd2 >> 12) & 0xf) + '0';
        !           168:     *cp++ = ((wrd2 >> 8) & 0xf) + '0';
        !           169:     *cp++ = ((wrd2 >> 4) & 0xf) + '0';
        !           170:     *cp++ = ((wrd2 >> 0) & 0xf) + '0';
        !           171:     *cp++ = ((wrd3 >> 28) & 0xf) + '0';
        !           172:     *cp++ = ((wrd3 >> 24) & 0xf) + '0';
        !           173:     *cp++ = ((wrd3 >> 20) & 0xf) + '0';
        !           174:     *cp++ = ((wrd3 >> 16) & 0xf) + '0';
        !           175:     *cp++ = ((wrd3 >> 12) & 0xf) + '0';
        !           176:     *cp++ = ((wrd3 >> 8) & 0xf) + '0';
        !           177:     *cp++ = ((wrd3 >> 4) & 0xf) + '0';
        !           178:     *cp++ = ((wrd3 >> 0) & 0xf) + '0';
        !           179:     *cp++ = 'E';
        !           180:     if (wrd1 & 0x40000000)
        !           181:        *cp++ = '-';
        !           182:     *cp++ = ((wrd1 >> 24) & 0xf) + '0';
        !           183:     *cp++ = ((wrd1 >> 20) & 0xf) + '0';
        !           184:     *cp++ = ((wrd1 >> 16) & 0xf) + '0';
        !           185:     *cp = 0;
        !           186:     sscanf(str, "%le", &d);
        !           187:     return d;
1.1       root      188: }
                    189: 
1.1.1.3 ! root      190: static __inline__ void from_pack(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1       root      191: {
1.1.1.3 ! root      192:     int i;
        !           193:     int t;
        !           194:     char *cp;
        !           195:     char str[100];
        !           196: 
        !           197:     sprintf(str, "%.16e", src);
        !           198:     cp = str;
        !           199:     *wrd1 = *wrd2 = *wrd3 = 0;
        !           200:     if (*cp == '-') {
        !           201:        cp++;
        !           202:        *wrd1 = 0x80000000;
        !           203:     }
        !           204:     if (*cp == '+')
        !           205:        cp++;
        !           206:     *wrd1 |= (*cp++ - '0');
        !           207:     if (*cp == '.')
        !           208:        cp++;
        !           209:     for (i = 0; i < 8; i++) {
        !           210:        *wrd2 <<= 4;
        !           211:        if (*cp >= '0' && *cp <= '9')
        !           212:            *wrd2 |= *cp++ - '0';
        !           213:     }
        !           214:     for (i = 0; i < 8; i++) {
        !           215:        *wrd3 <<= 4;
        !           216:        if (*cp >= '0' && *cp <= '9')
        !           217:            *wrd3 |= *cp++ - '0';
        !           218:     }
        !           219:     if (*cp == 'e' || *cp == 'E') {
        !           220:        cp++;
        !           221:        if (*cp == '-') {
        !           222:            cp++;
        !           223:            *wrd1 |= 0x40000000;
        !           224:        }
        !           225:        if (*cp == '+')
        !           226:            cp++;
        !           227:        t = 0;
        !           228:        for (i = 0; i < 3; i++) {
        !           229:            if (*cp >= '0' && *cp <= '9')
        !           230:                t = (t << 4) | (*cp++ - '0');
1.1       root      231:        }
1.1.1.3 ! root      232:        *wrd1 |= t << 16;
        !           233:     }
1.1       root      234: }
                    235: 
1.1.1.3 ! root      236: static __inline__ int get_fp_value (uae_u32 opcode, uae_u16 extra, double *src)
1.1       root      237: {
1.1.1.3 ! root      238:     uaecptr tmppc;
        !           239:     uae_u16 tmp;
        !           240:     int size;
        !           241:     int mode;
        !           242:     int reg;
        !           243:     uae_u32 ad = 0;
        !           244:     static int sz1[8] =
        !           245:     {4, 4, 12, 12, 2, 8, 1, 0};
        !           246:     static int sz2[8] =
        !           247:     {4, 4, 12, 12, 2, 8, 2, 0};
        !           248: 
        !           249:     if ((extra & 0x4000) == 0) {
        !           250:        *src = regs.fp[(extra >> 10) & 7];
        !           251:        return 1;
        !           252:     }
        !           253:     mode = (opcode >> 3) & 7;
        !           254:     reg = opcode & 7;
        !           255:     size = (extra >> 10) & 7;
        !           256:     switch (mode) {
        !           257:     case 0:
        !           258:        switch (size) {
        !           259:        case 6:
        !           260:            *src = (double) (uae_s8) m68k_dreg (regs, reg);
        !           261:            break;
        !           262:        case 4:
        !           263:            *src = (double) (uae_s16) m68k_dreg (regs, reg);
        !           264:            break;
1.1       root      265:        case 0:
1.1.1.3 ! root      266:            *src = (double) (uae_s32) m68k_dreg (regs, reg);
        !           267:            break;
        !           268:        case 1:
        !           269:            *src = to_single(m68k_dreg (regs, reg));
        !           270:            break;
        !           271:        default:
        !           272:            return 0;
        !           273:        }
        !           274:        return 1;
        !           275:     case 1:
        !           276:        return 0;
        !           277:     case 2:
        !           278:        ad = m68k_areg (regs, reg);
        !           279:        break;
        !           280:     case 3:
        !           281:        ad = m68k_areg (regs, reg);
        !           282:        m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
        !           283:        break;
        !           284:     case 4:
        !           285:        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
        !           286:        ad = m68k_areg (regs, reg);
        !           287:        break;
        !           288:     case 5:
        !           289:        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
        !           290:        break;
        !           291:     case 6:
        !           292:        ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
        !           293:        break;
        !           294:     case 7:
        !           295:        switch (reg) {
        !           296:        case 0:
        !           297:            ad = (uae_s32) (uae_s16) next_iword();
        !           298:            break;
1.1       root      299:        case 1:
1.1.1.3 ! root      300:            ad = next_ilong();
        !           301:            break;
1.1       root      302:        case 2:
1.1.1.3 ! root      303:            ad = m68k_getpc ();
        !           304:            ad += (uae_s32) (uae_s16) next_iword();
        !           305:            break;
1.1       root      306:        case 3:
1.1.1.3 ! root      307:            tmppc = m68k_getpc ();
        !           308:            tmp = next_iword();
        !           309:            ad = get_disp_ea_020 (tmppc, tmp);
        !           310:            break;
1.1       root      311:        case 4:
1.1.1.3 ! root      312:            ad = m68k_getpc ();
        !           313:            m68k_setpc (ad + sz2[size]);
        !           314:            break;
1.1       root      315:        default:
1.1.1.3 ! root      316:            return 0;
1.1       root      317:        }
1.1.1.3 ! root      318:     }
        !           319:     switch (size) {
        !           320:     case 0:
        !           321:        *src = (double) (uae_s32) get_long (ad);
        !           322:        break;
        !           323:     case 1:
        !           324:        *src = to_single(get_long (ad));
        !           325:        break;
        !           326:     case 2:{
        !           327:            uae_u32 wrd1, wrd2, wrd3;
        !           328:            wrd1 = get_long (ad);
        !           329:            ad += 4;
        !           330:            wrd2 = get_long (ad);
        !           331:            ad += 4;
        !           332:            wrd3 = get_long (ad);
        !           333:            *src = to_exten(wrd1, wrd2, wrd3);
        !           334:        }
        !           335:        break;
        !           336:     case 3:{
        !           337:            uae_u32 wrd1, wrd2, wrd3;
        !           338:            wrd1 = get_long (ad);
        !           339:            ad += 4;
        !           340:            wrd2 = get_long (ad);
        !           341:            ad += 4;
        !           342:            wrd3 = get_long (ad);
        !           343:            *src = to_pack(wrd1, wrd2, wrd3);
        !           344:        }
        !           345:        break;
        !           346:     case 4:
        !           347:        *src = (double) (uae_s16) get_word(ad);
        !           348:        break;
        !           349:     case 5:{
        !           350:            uae_u32 wrd1, wrd2;
        !           351:            wrd1 = get_long (ad);
        !           352:            ad += 4;
        !           353:            wrd2 = get_long (ad);
        !           354:            *src = to_double(wrd1, wrd2);
        !           355:        }
        !           356:        break;
        !           357:     case 6:
        !           358:        *src = (double) (uae_s8) get_byte(ad);
        !           359:        break;
        !           360:     default:
        !           361:        return 0;
        !           362:     }
        !           363:     return 1;
1.1       root      364: }
                    365: 
1.1.1.3 ! root      366: static __inline__ int put_fp_value (double value, uae_u32 opcode, uae_u16 extra)
1.1       root      367: {
1.1.1.3 ! root      368:     uae_u16 tmp;
        !           369:     uaecptr tmppc;
        !           370:     int size;
        !           371:     int mode;
        !           372:     int reg;
        !           373:     uae_u32 ad;
        !           374:     static int sz1[8] =
        !           375:     {4, 4, 12, 12, 2, 8, 1, 0};
        !           376:     static int sz2[8] =
        !           377:     {4, 4, 12, 12, 2, 8, 2, 0};
        !           378: 
        !           379:     if ((extra & 0x4000) == 0) {
        !           380:        regs.fp[(extra >> 10) & 7] = value;
        !           381:        return 1;
        !           382:     }
        !           383:     mode = (opcode >> 3) & 7;
        !           384:     reg = opcode & 7;
        !           385:     size = (extra >> 10) & 7;
        !           386:     ad = -1;
        !           387:     switch (mode) {
        !           388:     case 0:
        !           389:        switch (size) {
        !           390:        case 6:
        !           391:            m68k_dreg (regs, reg) = (((int) value & 0xff)
        !           392:                                    | (m68k_dreg (regs, reg) & ~0xff));
        !           393:            break;
        !           394:        case 4:
        !           395:            m68k_dreg (regs, reg) = (((int) value & 0xffff)
        !           396:                                    | (m68k_dreg (regs, reg) & ~0xffff));
        !           397:            break;
1.1       root      398:        case 0:
1.1.1.3 ! root      399:            m68k_dreg (regs, reg) = (int) value;
        !           400:            break;
1.1       root      401:        case 1:
1.1.1.3 ! root      402:            m68k_dreg (regs, reg) = from_single(value);
        !           403:            break;
        !           404:        default:
        !           405:            return 0;
        !           406:        }
        !           407:        return 1;
        !           408:     case 1:
        !           409:        return 0;
        !           410:     case 2:
        !           411:        ad = m68k_areg (regs, reg);
        !           412:        break;
        !           413:     case 3:
        !           414:        ad = m68k_areg (regs, reg);
        !           415:        m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
        !           416:        break;
        !           417:     case 4:
        !           418:        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
        !           419:        ad = m68k_areg (regs, reg);
        !           420:        break;
        !           421:     case 5:
        !           422:        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
        !           423:        break;
        !           424:     case 6:
        !           425:        ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
        !           426:        break;
        !           427:     case 7:
        !           428:        switch (reg) {
        !           429:        case 0:
        !           430:            ad = (uae_s32) (uae_s16) next_iword();
        !           431:            break;
        !           432:        case 1:
        !           433:            ad = next_ilong();
        !           434:            break;
1.1       root      435:        case 2:
1.1.1.3 ! root      436:            ad = m68k_getpc ();
        !           437:            ad += (uae_s32) (uae_s16) next_iword();
        !           438:            break;
1.1       root      439:        case 3:
1.1.1.3 ! root      440:            tmppc = m68k_getpc ();
        !           441:            tmp = next_iword();
        !           442:            ad = get_disp_ea_020 (tmppc, tmp);
        !           443:            break;
1.1       root      444:        case 4:
1.1.1.3 ! root      445:            ad = m68k_getpc ();
        !           446:            m68k_setpc (ad + sz2[size]);
        !           447:            break;
1.1       root      448:        default:
1.1.1.3 ! root      449:            return 0;
1.1       root      450:        }
1.1.1.3 ! root      451:     }
        !           452:     switch (size) {
        !           453:     case 0:
        !           454:        put_long (ad, (uae_s32) value);
        !           455:        break;
        !           456:     case 1:
        !           457:        put_long (ad, from_single(value));
        !           458:        break;
        !           459:     case 2:
        !           460:        {
        !           461:            uae_u32 wrd1, wrd2, wrd3;
        !           462:            from_exten(value, &wrd1, &wrd2, &wrd3);
        !           463:            put_long (ad, wrd1);
        !           464:            ad += 4;
        !           465:            put_long (ad, wrd2);
        !           466:            ad += 4;
        !           467:            put_long (ad, wrd3);
        !           468:        }
        !           469:        break;
        !           470:     case 3:
        !           471:        {
        !           472:            uae_u32 wrd1, wrd2, wrd3;
        !           473:            from_pack(value, &wrd1, &wrd2, &wrd3);
        !           474:            put_long (ad, wrd1);
        !           475:            ad += 4;
        !           476:            put_long (ad, wrd2);
        !           477:            ad += 4;
        !           478:            put_long (ad, wrd3);
        !           479:        }
        !           480:        break;
        !           481:     case 4:
        !           482:        put_word(ad, (uae_s16) value);
        !           483:        break;
        !           484:     case 5:{
        !           485:            uae_u32 wrd1, wrd2;
        !           486:            from_double(value, &wrd1, &wrd2);
        !           487:            put_long (ad, wrd1);
        !           488:            ad += 4;
        !           489:            put_long (ad, wrd2);
        !           490:        }
        !           491:        break;
        !           492:     case 6:
        !           493:        put_byte(ad, (uae_s8) value);
        !           494:        break;
        !           495:     default:
        !           496:        return 0;
        !           497:     }
        !           498:     return 1;
1.1       root      499: }
                    500: 
1.1.1.3 ! root      501: static __inline__ int get_fp_ad(uae_u32 opcode, uae_u32 * ad)
1.1       root      502: {
1.1.1.3 ! root      503:     uae_u16 tmp;
        !           504:     uaecptr tmppc;
        !           505:     int mode;
        !           506:     int reg;
        !           507: 
        !           508:     mode = (opcode >> 3) & 7;
        !           509:     reg = opcode & 7;
        !           510:     switch (mode) {
        !           511:     case 0:
        !           512:     case 1:
        !           513:        return 0;
        !           514:     case 2:
        !           515:        *ad = m68k_areg (regs, reg);
        !           516:        break;
        !           517:     case 3:
        !           518:        *ad = m68k_areg (regs, reg);
        !           519:        break;
        !           520:     case 4:
        !           521:        *ad = m68k_areg (regs, reg);
        !           522:        break;
        !           523:     case 5:
        !           524:        *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
        !           525:        break;
        !           526:     case 6:
        !           527:        *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
        !           528:        break;
        !           529:     case 7:
        !           530:        switch (reg) {
1.1       root      531:        case 0:
1.1.1.3 ! root      532:            *ad = (uae_s32) (uae_s16) next_iword();
        !           533:            break;
1.1       root      534:        case 1:
1.1.1.3 ! root      535:            *ad = next_ilong();
        !           536:            break;
1.1       root      537:        case 2:
1.1.1.3 ! root      538:            *ad = m68k_getpc ();
        !           539:            *ad += (uae_s32) (uae_s16) next_iword();
        !           540:            break;
1.1       root      541:        case 3:
1.1.1.3 ! root      542:            tmppc = m68k_getpc ();
        !           543:            tmp = next_iword();
        !           544:            *ad = get_disp_ea_020 (tmppc, tmp);
        !           545:            break;
        !           546:        default:
        !           547:            return 0;
1.1       root      548:        }
1.1.1.3 ! root      549:     }
        !           550:     return 1;
1.1       root      551: }
                    552: 
1.1.1.3 ! root      553: static __inline__ int fpp_cond(uae_u32 opcode, int contition)
1.1       root      554: {
1.1.1.3 ! root      555:     int N = (regs.fpsr & 0x8000000) != 0;
        !           556:     int Z = (regs.fpsr & 0x4000000) != 0;
        !           557:     /* int I = (regs.fpsr & 0x2000000) != 0; */
        !           558:     int NotANumber = (regs.fpsr & 0x1000000) != 0;
        !           559: 
        !           560:     switch (contition) {
        !           561:     case 0x00:
        !           562:        return 0;
        !           563:     case 0x01:
        !           564:        return Z;
        !           565:     case 0x02:
        !           566:        return !(NotANumber || Z || N);
        !           567:     case 0x03:
        !           568:        return Z || !(NotANumber || N);
        !           569:     case 0x04:
        !           570:        return N && !(NotANumber || Z);
        !           571:     case 0x05:
        !           572:        return Z || (N && !NotANumber);
        !           573:     case 0x06:
        !           574:        return !(NotANumber || Z);
        !           575:     case 0x07:
        !           576:        return !NotANumber;
        !           577:     case 0x08:
        !           578:        return NotANumber;
        !           579:     case 0x09:
        !           580:        return NotANumber || Z;
        !           581:     case 0x0a:
        !           582:        return NotANumber || !(N || Z);
        !           583:     case 0x0b:
        !           584:        return NotANumber || Z || !N;
        !           585:     case 0x0c:
        !           586:        return NotANumber || (N && !Z);
        !           587:     case 0x0d:
        !           588:        return NotANumber || Z || N;
        !           589:     case 0x0e:
        !           590:        return !Z;
        !           591:     case 0x0f:
        !           592:        return 1;
        !           593:     case 0x10:
        !           594:        return 0;
        !           595:     case 0x11:
        !           596:        return Z;
        !           597:     case 0x12:
        !           598:        return !(NotANumber || Z || N);
        !           599:     case 0x13:
        !           600:        return Z || !(NotANumber || N);
        !           601:     case 0x14:
        !           602:        return N && !(NotANumber || Z);
        !           603:     case 0x15:
        !           604:        return Z || (N && !NotANumber);
        !           605:     case 0x16:
        !           606:        return !(NotANumber || Z);
        !           607:     case 0x17:
        !           608:        return !NotANumber;
        !           609:     case 0x18:
        !           610:        return NotANumber;
        !           611:     case 0x19:
        !           612:        return NotANumber || Z;
        !           613:     case 0x1a:
        !           614:        return NotANumber || !(N || Z);
        !           615:     case 0x1b:
        !           616:        return NotANumber || Z || !N;
        !           617:     case 0x1c:
        !           618:        return NotANumber || (Z && N);
        !           619:     case 0x1d:
        !           620:        return NotANumber || Z || N;
        !           621:     case 0x1e:
        !           622:        return !Z;
        !           623:     case 0x1f:
        !           624:        return 1;
        !           625:     }
        !           626:     return -1;
1.1       root      627: }
                    628: 
1.1.1.3 ! root      629: void fdbcc_opp(uae_u32 opcode, uae_u16 extra)
1.1       root      630: {
1.1.1.3 ! root      631:     uaecptr pc = (uae_u32) m68k_getpc ();
        !           632:     uae_s32 disp = (uae_s32) (uae_s16) next_iword();
        !           633:     int cc;
1.1       root      634: 
                    635: #if DEBUG_FPP
1.1.1.3 ! root      636:     printf("fdbcc_opp at %08lx\n", m68k_getpc ());
        !           637:     fflush(stdout);
1.1       root      638: #endif
1.1.1.3 ! root      639:     cc = fpp_cond(opcode, extra & 0x3f);
        !           640:     if (cc == -1) {
        !           641:        m68k_setpc (pc - 4);
        !           642:        op_illg (opcode);
        !           643:     } else if (!cc) {
        !           644:        int reg = opcode & 0x7;
        !           645: 
        !           646:        m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff)
        !           647:                                | ((m68k_dreg (regs, reg) - 1) & 0xffff));
        !           648:        if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff)
        !           649:            m68k_setpc (pc + disp);
        !           650:     }
1.1       root      651: }
                    652: 
1.1.1.3 ! root      653: void fscc_opp(uae_u32 opcode, uae_u16 extra)
1.1       root      654: {
1.1.1.3 ! root      655:     uae_u32 ad;
        !           656:     int cc;
1.1       root      657: 
                    658: #if DEBUG_FPP
1.1.1.3 ! root      659:     printf("fscc_opp at %08lx\n", m68k_getpc ());
        !           660:     fflush(stdout);
1.1       root      661: #endif
1.1.1.3 ! root      662:     cc = fpp_cond(opcode, extra & 0x3f);
        !           663:     if (cc == -1) {
        !           664:        m68k_setpc (m68k_getpc () - 4);
        !           665:        op_illg (opcode);
        !           666:     } else if ((opcode & 0x38) == 0) {
        !           667:        m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) |
        !           668:            (cc ? 0xff : 0x00);
        !           669:     } else {
        !           670:        if (get_fp_ad(opcode, &ad) == 0) {
        !           671:            m68k_setpc (m68k_getpc () - 4);
        !           672:            op_illg (opcode);
        !           673:        } else
        !           674:            put_byte(ad, cc ? 0xff : 0x00);
        !           675:     }
1.1       root      676: }
                    677: 
1.1.1.3 ! root      678: void ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
1.1       root      679: {
1.1.1.3 ! root      680:     int cc;
1.1       root      681: 
                    682: #if DEBUG_FPP
1.1.1.3 ! root      683:     printf("ftrapcc_opp at %08lx\n", m68k_getpc ());
        !           684:     fflush(stdout);
1.1       root      685: #endif
1.1.1.3 ! root      686:     cc = fpp_cond(opcode, opcode & 0x3f);
        !           687:     if (cc == -1) {
        !           688:        m68k_setpc (oldpc);
        !           689:        op_illg (opcode);
        !           690:     }
        !           691:     if (cc)
        !           692:        Exception(7, oldpc - 2);
1.1       root      693: }
                    694: 
1.1.1.3 ! root      695: void fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
1.1       root      696: {
1.1.1.3 ! root      697:     int cc;
1.1       root      698: 
                    699: #if DEBUG_FPP
1.1.1.3 ! root      700:     printf("fbcc_opp at %08lx\n", m68k_getpc ());
        !           701:     fflush(stdout);
1.1       root      702: #endif
1.1.1.3 ! root      703:     cc = fpp_cond(opcode, opcode & 0x3f);
        !           704:     if (cc == -1) {
        !           705:        m68k_setpc (pc);
        !           706:        op_illg (opcode);
        !           707:     } else if (cc) {
        !           708:        if ((opcode & 0x40) == 0)
        !           709:            extra = (uae_s32) (uae_s16) extra;
        !           710:        m68k_setpc (pc + extra);
        !           711:     }
1.1       root      712: }
                    713: 
1.1.1.3 ! root      714: void fsave_opp(uae_u32 opcode)
1.1       root      715: {
1.1.1.3 ! root      716:     uae_u32 ad;
        !           717:     int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
        !           718:     int i;
        !           719: 
1.1       root      720: #if DEBUG_FPP
1.1.1.3 ! root      721:     printf("fsave_opp at %08lx\n", m68k_getpc ());
        !           722:     fflush(stdout);
1.1       root      723: #endif
1.1.1.3 ! root      724:     if (get_fp_ad(opcode, &ad) == 0) {
        !           725:        m68k_setpc (m68k_getpc () - 2);
        !           726:        op_illg (opcode);
        !           727:        return;
        !           728:     }
        !           729:     if (incr < 0) {
        !           730:        ad -= 4;
        !           731:        put_long (ad, 0x70000000);
        !           732:        for (i = 0; i < 5; i++) {
        !           733:            ad -= 4;
        !           734:            put_long (ad, 0x00000000);
        !           735:        }
        !           736:        ad -= 4;
        !           737:        put_long (ad, 0x1f180000);
        !           738:     } else {
        !           739:        put_long (ad, 0x1f180000);
        !           740:        ad += 4;
        !           741:        for (i = 0; i < 5; i++) {
        !           742:            put_long (ad, 0x00000000);
        !           743:            ad += 4;
        !           744:        }
        !           745:        put_long (ad, 0x70000000);
        !           746:        ad += 4;
        !           747:     }
        !           748:     if ((opcode & 0x38) == 0x18)
        !           749:        m68k_areg (regs, opcode & 7) = ad;
        !           750:     if ((opcode & 0x38) == 0x20)
        !           751:        m68k_areg (regs, opcode & 7) = ad;
1.1       root      752: }
                    753: 
1.1.1.3 ! root      754: void frestore_opp(uae_u32 opcode)
1.1       root      755: {
1.1.1.3 ! root      756:     uae_u32 ad;
        !           757:     uae_u32 d;
        !           758:     int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
        !           759: 
1.1       root      760: #if DEBUG_FPP
1.1.1.3 ! root      761:     printf("frestore_opp at %08lx\n", m68k_getpc ());
        !           762:     fflush(stdout);
1.1       root      763: #endif
1.1.1.3 ! root      764:     if (get_fp_ad(opcode, &ad) == 0) {
        !           765:        m68k_setpc (m68k_getpc () - 2);
        !           766:        op_illg (opcode);
        !           767:        return;
        !           768:     }
        !           769:     if (incr < 0) {
        !           770:        ad -= 4;
        !           771:        d = get_long (ad);
        !           772:        if ((d & 0xff000000) != 0) {
        !           773:            if ((d & 0x00ff0000) == 0x00180000)
        !           774:                ad -= 6 * 4;
        !           775:            else if ((d & 0x00ff0000) == 0x00380000)
        !           776:                ad -= 14 * 4;
        !           777:            else if ((d & 0x00ff0000) == 0x00b40000)
        !           778:                ad -= 45 * 4;
        !           779:        }
        !           780:     } else {
        !           781:        d = get_long (ad);
        !           782:        ad += 4;
        !           783:        if ((d & 0xff000000) != 0) {
        !           784:            if ((d & 0x00ff0000) == 0x00180000)
        !           785:                ad += 6 * 4;
        !           786:            else if ((d & 0x00ff0000) == 0x00380000)
        !           787:                ad += 14 * 4;
        !           788:            else if ((d & 0x00ff0000) == 0x00b40000)
        !           789:                ad += 45 * 4;
        !           790:        }
        !           791:     }
        !           792:     if ((opcode & 0x38) == 0x18)
        !           793:        m68k_areg (regs, opcode & 7) = ad;
        !           794:     if ((opcode & 0x38) == 0x20)
        !           795:        m68k_areg (regs, opcode & 7) = ad;
1.1       root      796: }
                    797: 
1.1.1.3 ! root      798: void fpp_opp(uae_u32 opcode, uae_u16 extra)
1.1       root      799: {
1.1.1.3 ! root      800:     int reg;
        !           801:     double src;
1.1       root      802: 
                    803: #if DEBUG_FPP
1.1.1.3 ! root      804:     printf("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff,
        !           805:           m68k_getpc () - 4);
        !           806:     fflush(stdout);
1.1       root      807: #endif
1.1.1.3 ! root      808:     switch ((extra >> 13) & 0x7) {
        !           809:     case 3:
        !           810:        if (put_fp_value (regs.fp[(extra >> 7) & 7], opcode, extra) == 0) {
        !           811:            m68k_setpc (m68k_getpc () - 4);
        !           812:            op_illg (opcode);
        !           813:        }
        !           814:        return;
        !           815:     case 4:
        !           816:     case 5:
        !           817:        if ((opcode & 0x38) == 0) {
        !           818:            if (extra & 0x2000) {
        !           819:                if (extra & 0x1000)
        !           820:                    m68k_dreg (regs, opcode & 7) = regs.fpcr;
        !           821:                if (extra & 0x0800)
        !           822:                    m68k_dreg (regs, opcode & 7) = regs.fpsr;
        !           823:                if (extra & 0x0400)
        !           824:                    m68k_dreg (regs, opcode & 7) = regs.fpiar;
        !           825:            } else {
        !           826:                if (extra & 0x1000)
        !           827:                    regs.fpcr = m68k_dreg (regs, opcode & 7);
        !           828:                if (extra & 0x0800)
        !           829:                    regs.fpsr = m68k_dreg (regs, opcode & 7);
        !           830:                if (extra & 0x0400)
        !           831:                    regs.fpiar = m68k_dreg (regs, opcode & 7);
        !           832:            }
        !           833:        } else if ((opcode & 0x38) == 1) {
        !           834:            if (extra & 0x2000) {
        !           835:                if (extra & 0x1000)
        !           836:                    m68k_areg (regs, opcode & 7) = regs.fpcr;
        !           837:                if (extra & 0x0800)
        !           838:                    m68k_areg (regs, opcode & 7) = regs.fpsr;
        !           839:                if (extra & 0x0400)
        !           840:                    m68k_areg (regs, opcode & 7) = regs.fpiar;
        !           841:            } else {
        !           842:                if (extra & 0x1000)
        !           843:                    regs.fpcr = m68k_areg (regs, opcode & 7);
        !           844:                if (extra & 0x0800)
        !           845:                    regs.fpsr = m68k_areg (regs, opcode & 7);
        !           846:                if (extra & 0x0400)
        !           847:                    regs.fpiar = m68k_areg (regs, opcode & 7);
        !           848:            }
        !           849:        } else if ((opcode & 0x3f) == 0x3c) {
        !           850:            if ((extra & 0x2000) == 0) {
        !           851:                if (extra & 0x1000)
        !           852:                    regs.fpcr = next_ilong();
        !           853:                if (extra & 0x0800)
        !           854:                    regs.fpsr = next_ilong();
        !           855:                if (extra & 0x0400)
        !           856:                    regs.fpiar = next_ilong();
        !           857:            }
        !           858:        } else if (extra & 0x2000) {
        !           859:            /* FMOVEM FPP->memory */
        !           860:            uae_u32 ad;
        !           861:            int incr = 0;
        !           862: 
        !           863:            if (get_fp_ad(opcode, &ad) == 0) {
        !           864:                m68k_setpc (m68k_getpc () - 4);
        !           865:                op_illg (opcode);
1.1       root      866:                return;
1.1.1.3 ! root      867:            }
        !           868:            if ((opcode & 0x38) == 0x20) {
        !           869:                if (extra & 0x1000)
        !           870:                    incr += 4;
        !           871:                if (extra & 0x0800)
        !           872:                    incr += 4;
        !           873:                if (extra & 0x0400)
        !           874:                    incr += 4;
        !           875:            }
        !           876:            ad -= incr;
        !           877:            if (extra & 0x1000) {
        !           878:                put_long (ad, regs.fpcr);
        !           879:                ad += 4;
        !           880:            }
        !           881:            if (extra & 0x0800) {
        !           882:                put_long (ad, regs.fpsr);
        !           883:                ad += 4;
        !           884:            }
        !           885:            if (extra & 0x0400) {
        !           886:                put_long (ad, regs.fpiar);
        !           887:                ad += 4;
        !           888:            }
        !           889:            ad -= incr;
        !           890:            if ((opcode & 0x38) == 0x18)
        !           891:                m68k_areg (regs, opcode & 7) = ad;
        !           892:            if ((opcode & 0x38) == 0x20)
        !           893:                m68k_areg (regs, opcode & 7) = ad;
        !           894:        } else {
        !           895:            /* FMOVEM memory->FPP */
        !           896:            uae_u32 ad;
        !           897: 
        !           898:            if (get_fp_ad(opcode, &ad) == 0) {
        !           899:                m68k_setpc (m68k_getpc () - 4);
        !           900:                op_illg (opcode);
1.1       root      901:                return;
1.1.1.3 ! root      902:            }
        !           903:            ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad;
        !           904:            if (extra & 0x1000) {
        !           905:                regs.fpcr = get_long (ad);
        !           906:                ad += 4;
        !           907:            }
        !           908:            if (extra & 0x0800) {
        !           909:                regs.fpsr = get_long (ad);
        !           910:                ad += 4;
        !           911:            }
        !           912:            if (extra & 0x0400) {
        !           913:                regs.fpiar = get_long (ad);
        !           914:                ad += 4;
        !           915:            }
        !           916:            if ((opcode & 0x38) == 0x18)
        !           917:                m68k_areg (regs, opcode & 7) = ad;
        !           918:            if ((opcode & 0x38) == 0x20)
        !           919:                m68k_areg (regs, opcode & 7) = ad - 12;
        !           920:        }
        !           921:        return;
        !           922:     case 6:
        !           923:     case 7:
        !           924:        {
        !           925:            uae_u32 ad, list = 0;
        !           926:            int incr = 0;
        !           927:            if (extra & 0x2000) {
        !           928:                /* FMOVEM FPP->memory */
        !           929:                if (get_fp_ad(opcode, &ad) == 0) {
        !           930:                    m68k_setpc (m68k_getpc () - 4);
        !           931:                    op_illg (opcode);
        !           932:                    return;
        !           933:                }
        !           934:                switch ((extra >> 11) & 3) {
        !           935:                case 0: /* static pred */
        !           936:                    list = extra & 0xff;
        !           937:                    incr = -1;
        !           938:                    break;
        !           939:                case 1: /* dynamic pred */
        !           940:                    list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
        !           941:                    incr = -1;
        !           942:                    break;
        !           943:                case 2: /* static postinc */
        !           944:                    list = extra & 0xff;
        !           945:                    incr = 1;
        !           946:                    break;
        !           947:                case 3: /* dynamic postinc */
        !           948:                    list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
        !           949:                    incr = 1;
        !           950:                    break;
        !           951:                }
        !           952:                while (list) {
        !           953:                    uae_u32 wrd1, wrd2, wrd3;
        !           954:                    if (incr < 0) {
        !           955:                        from_exten(regs.fp[fpp_movem_index2[list]],
        !           956:                                   &wrd1, &wrd2, &wrd3);
        !           957:                        ad -= 4;
        !           958:                        put_long (ad, wrd3);
        !           959:                        ad -= 4;
        !           960:                        put_long (ad, wrd2);
        !           961:                        ad -= 4;
        !           962:                        put_long (ad, wrd1);
        !           963:                    } else {
        !           964:                        from_exten(regs.fp[fpp_movem_index1[list]],
        !           965:                                   &wrd1, &wrd2, &wrd3);
        !           966:                        put_long (ad, wrd1);
        !           967:                        ad += 4;
        !           968:                        put_long (ad, wrd2);
        !           969:                        ad += 4;
        !           970:                        put_long (ad, wrd3);
        !           971:                        ad += 4;
1.1       root      972:                    }
1.1.1.3 ! root      973:                    list = fpp_movem_next[list];
        !           974:                }
        !           975:                if ((opcode & 0x38) == 0x18)
        !           976:                    m68k_areg (regs, opcode & 7) = ad;
        !           977:                if ((opcode & 0x38) == 0x20)
        !           978:                    m68k_areg (regs, opcode & 7) = ad;
        !           979:            } else {
        !           980:                /* FMOVEM memory->FPP */
        !           981:                if (get_fp_ad(opcode, &ad) == 0) {
        !           982:                    m68k_setpc (m68k_getpc () - 4);
        !           983:                    op_illg (opcode);
        !           984:                    return;
        !           985:                }
        !           986:                switch ((extra >> 11) & 3) {
        !           987:                case 0: /* static pred */
        !           988:                    list = extra & 0xff;
        !           989:                    incr = -1;
        !           990:                    break;
        !           991:                case 1: /* dynamic pred */
        !           992:                    list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
        !           993:                    incr = -1;
        !           994:                    break;
        !           995:                case 2: /* static postinc */
        !           996:                    list = extra & 0xff;
        !           997:                    incr = 1;
        !           998:                    break;
        !           999:                case 3: /* dynamic postinc */
        !          1000:                    list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
        !          1001:                    incr = 1;
        !          1002:                    break;
        !          1003:                }
        !          1004:                while (list) {
        !          1005:                    uae_u32 wrd1, wrd2, wrd3;
        !          1006:                    if (incr < 0) {
        !          1007:                        ad -= 4;
        !          1008:                        wrd3 = get_long (ad);
        !          1009:                        ad -= 4;
        !          1010:                        wrd2 = get_long (ad);
        !          1011:                        ad -= 4;
        !          1012:                        wrd1 = get_long (ad);
        !          1013:                        regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
        !          1014:                    } else {
        !          1015:                        wrd1 = get_long (ad);
        !          1016:                        ad += 4;
        !          1017:                        wrd2 = get_long (ad);
        !          1018:                        ad += 4;
        !          1019:                        wrd3 = get_long (ad);
        !          1020:                        ad += 4;
        !          1021:                        regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
1.1       root     1022:                    }
1.1.1.3 ! root     1023:                    list = fpp_movem_next[list];
1.1       root     1024:                }
1.1.1.3 ! root     1025:                if ((opcode & 0x38) == 0x18)
        !          1026:                    m68k_areg (regs, opcode & 7) = ad;
        !          1027:                if ((opcode & 0x38) == 0x20)
        !          1028:                    m68k_areg (regs, opcode & 7) = ad;
        !          1029:            }
        !          1030:        }
        !          1031:        return;
        !          1032:     case 0:
        !          1033:     case 2:
        !          1034:        reg = (extra >> 7) & 7;
        !          1035:        if ((extra & 0xfc00) == 0x5c00) {
        !          1036:            switch (extra & 0x7f) {
        !          1037:            case 0x00:
        !          1038:                regs.fp[reg] = 4.0 * atan(1.0);
        !          1039:                break;
        !          1040:            case 0x0b:
        !          1041:                regs.fp[reg] = log10 (2.0);
        !          1042:                break;
        !          1043:            case 0x0c:
        !          1044:                regs.fp[reg] = exp (1.0);
        !          1045:                break;
        !          1046:            case 0x0d:
        !          1047:                regs.fp[reg] = log (exp (1.0)) / log (2.0);
        !          1048:                break;
        !          1049:            case 0x0e:
        !          1050:                regs.fp[reg] = log (exp (1.0)) / log (10.0);
        !          1051:                break;
        !          1052:            case 0x0f:
        !          1053:                regs.fp[reg] = 0.0;
        !          1054:                break;
        !          1055:            case 0x30:
        !          1056:                regs.fp[reg] = log (2.0);
        !          1057:                break;
        !          1058:            case 0x31:
        !          1059:                regs.fp[reg] = log (10.0);
        !          1060:                break;
        !          1061:            case 0x32:
        !          1062:                regs.fp[reg] = 1.0e0;
        !          1063:                break;
        !          1064:            case 0x33:
        !          1065:                regs.fp[reg] = 1.0e1;
        !          1066:                break;
        !          1067:            case 0x34:
        !          1068:                regs.fp[reg] = 1.0e2;
        !          1069:                break;
        !          1070:            case 0x35:
        !          1071:                regs.fp[reg] = 1.0e4;
        !          1072:                break;
        !          1073:            case 0x36:
        !          1074:                regs.fp[reg] = 1.0e8;
        !          1075:                break;
        !          1076:            case 0x37:
        !          1077:                regs.fp[reg] = 1.0e16;
        !          1078:                break;
        !          1079:            case 0x38:
        !          1080:                regs.fp[reg] = 1.0e32;
        !          1081:                break;
        !          1082:            case 0x39:
        !          1083:                regs.fp[reg] = 1.0e64;
        !          1084:                break;
        !          1085:            case 0x3a:
        !          1086:                regs.fp[reg] = 1.0e128;
        !          1087:                break;
        !          1088:            case 0x3b:
        !          1089:                regs.fp[reg] = 1.0e256;
        !          1090:                break;
1.1       root     1091: #if 0
1.1.1.3 ! root     1092:            case 0x3c:
        !          1093:                regs.fp[reg] = 1.0e512;
        !          1094:                break;
        !          1095:            case 0x3d:
        !          1096:                regs.fp[reg] = 1.0e1024;
        !          1097:                break;
        !          1098:            case 0x3e:
        !          1099:                regs.fp[reg] = 1.0e2048;
        !          1100:                break;
        !          1101:            case 0x3f:
        !          1102:                regs.fp[reg] = 1.0e4096;
        !          1103:                break;
1.1       root     1104: #endif
1.1.1.3 ! root     1105:            default:
        !          1106:                m68k_setpc (m68k_getpc () - 4);
        !          1107:                op_illg (opcode);
        !          1108:                break;
        !          1109:            }
        !          1110:            return;
        !          1111:        }
        !          1112:        if (get_fp_value (opcode, extra, &src) == 0) {
        !          1113:            m68k_setpc (m68k_getpc () - 4);
        !          1114:            op_illg (opcode);
        !          1115:            return;
        !          1116:        }
        !          1117:        switch (extra & 0x7f) {
        !          1118:        case 0x00:              /* FMOVE */
        !          1119:            regs.fp[reg] = src;
        !          1120:            break;
        !          1121:        case 0x01:              /* FINT */
        !          1122:            regs.fp[reg] = (int) (src + 0.5);
        !          1123:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1124:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1125:            break;
        !          1126:        case 0x02:              /* FSINH */
        !          1127:            regs.fp[reg] = sinh (src);
        !          1128:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1129:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1130:            break;
        !          1131:        case 0x03:              /* FINTRZ */
        !          1132:            regs.fp[reg] = (int) src;
        !          1133:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1134:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1135:            break;
        !          1136:        case 0x04:              /* FSQRT */
        !          1137:            regs.fp[reg] = sqrt (src);
        !          1138:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1139:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1140:            break;
        !          1141:        case 0x06:              /* FLOGNP1 */
        !          1142:            regs.fp[reg] = log (src + 1.0);
        !          1143:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1144:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1145:            break;
        !          1146:        case 0x08:              /* FETOXM1 */
        !          1147:            regs.fp[reg] = exp (src) - 1.0;
        !          1148:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1149:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1150:            break;
        !          1151:        case 0x09:              /* FTANH */
        !          1152:            regs.fp[reg] = tanh (src);
        !          1153:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1154:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1155:            break;
        !          1156:        case 0x0a:              /* FATAN */
        !          1157:            regs.fp[reg] = atan (src);
        !          1158:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1159:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1160:            break;
        !          1161:        case 0x0c:              /* FASIN */
        !          1162:            regs.fp[reg] = asin (src);
        !          1163:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1164:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1165:            break;
        !          1166:        case 0x0d:              /* FATANH */
        !          1167: #if 1                          /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */
        !          1168:            regs.fp[reg] = log ((1 + src) / (1 - src)) / 2;
1.1       root     1169: #else
1.1.1.3 ! root     1170:            regs.fp[reg] = atanh (src);
1.1       root     1171: #endif
1.1.1.3 ! root     1172:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1173:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1174:            break;
        !          1175:        case 0x0e:              /* FSIN */
        !          1176:            regs.fp[reg] = sin (src);
        !          1177:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1178:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1179:            break;
        !          1180:        case 0x0f:              /* FTAN */
        !          1181:            regs.fp[reg] = tan (src);
        !          1182:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1183:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1184:            break;
        !          1185:        case 0x10:              /* FETOX */
        !          1186:            regs.fp[reg] = exp (src);
        !          1187:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1188:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1189:            break;
        !          1190:        case 0x11:              /* FTWOTOX */
        !          1191:            regs.fp[reg] = pow(2.0, src);
        !          1192:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1193:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1194:            break;
        !          1195:        case 0x12:              /* FTENTOX */
        !          1196:            regs.fp[reg] = pow(10.0, src);
        !          1197:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1198:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1199:            break;
        !          1200:        case 0x14:              /* FLOGN */
        !          1201:            regs.fp[reg] = log (src);
        !          1202:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1203:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1204:            break;
        !          1205:        case 0x15:              /* FLOG10 */
        !          1206:            regs.fp[reg] = log10 (src);
        !          1207:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1208:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1209:            break;
        !          1210:        case 0x16:              /* FLOG2 */
        !          1211:            regs.fp[reg] = log (src) / log (2.0);
        !          1212:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1213:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1214:            break;
        !          1215:        case 0x18:              /* FABS */
        !          1216:            regs.fp[reg] = src < 0 ? -src : src;
        !          1217:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1218:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1219:            break;
        !          1220:        case 0x19:              /* FCOSH */
        !          1221:            regs.fp[reg] = cosh(src);
        !          1222:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1223:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1224:            break;
        !          1225:        case 0x1a:              /* FNEG */
        !          1226:            regs.fp[reg] = -src;
        !          1227:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1228:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1229:            break;
        !          1230:        case 0x1c:              /* FACOS */
        !          1231:            regs.fp[reg] = acos(src);
        !          1232:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1233:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1234:            break;
        !          1235:        case 0x1d:              /* FCOS */
        !          1236:            regs.fp[reg] = cos(src);
        !          1237:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1238:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1239:            break;
        !          1240:        case 0x1e:              /* FGETEXP */
        !          1241:            {
        !          1242:                int expon;
        !          1243:                frexp (src, &expon);
        !          1244:                regs.fp[reg] = (double) (expon - 1);
        !          1245:                regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1246:                    (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1247:            }
        !          1248:            break;
        !          1249:        case 0x1f:              /* FGETMAN */
        !          1250:            {
        !          1251:                int expon;
        !          1252:                regs.fp[reg] = frexp (src, &expon) * 2.0;
        !          1253:                regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1254:                    (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1255:            }
        !          1256:            break;
        !          1257:        case 0x20:              /* FDIV */
        !          1258:            regs.fp[reg] /= src;
        !          1259:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1260:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1261:            break;
        !          1262:        case 0x21:              /* FMOD */
        !          1263:            regs.fp[reg] = regs.fp[reg] -
        !          1264:                (double) ((int) (regs.fp[reg] / src)) * src;
        !          1265:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1266:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1267:            break;
        !          1268:        case 0x22:              /* FADD */
        !          1269:            regs.fp[reg] += src;
        !          1270:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1271:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1272:            break;
        !          1273:        case 0x23:              /* FMUL */
        !          1274:            regs.fp[reg] *= src;
        !          1275:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1276:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1277:            break;
        !          1278:        case 0x24:              /* FSGLDIV */
        !          1279:            regs.fp[reg] /= src;
        !          1280:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1281:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1282:            break;
        !          1283:        case 0x25:              /* FREM */
        !          1284:            regs.fp[reg] = regs.fp[reg] -
        !          1285:                (double) ((int) (regs.fp[reg] / src + 0.5)) * src;
        !          1286:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1287:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1288:            break;
        !          1289:        case 0x26:              /* FSCALE */
        !          1290:            regs.fp[reg] *= exp (log (2.0) * src);
        !          1291:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1292:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1293:            break;
        !          1294:        case 0x27:              /* FSGLMUL */
        !          1295:            regs.fp[reg] *= src;
        !          1296:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1297:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1298:            break;
        !          1299:        case 0x28:              /* FSUB */
        !          1300:            regs.fp[reg] -= src;
        !          1301:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1302:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1303:            break;
        !          1304:        case 0x30:              /* FSINCOS */
        !          1305:        case 0x31:
        !          1306:        case 0x32:
        !          1307:        case 0x33:
        !          1308:        case 0x34:
        !          1309:        case 0x35:
        !          1310:        case 0x36:
        !          1311:        case 0x37:
        !          1312:            regs.fp[reg] = sin (src);
        !          1313:            regs.fp[extra & 7] = cos(src);
        !          1314:            regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
        !          1315:                (regs.fp[reg] < 0 ? 0x8000000 : 0);
        !          1316:            break;
        !          1317:        case 0x38:              /* FCMP */
        !          1318:            {
        !          1319:                double tmp = regs.fp[reg] - src;
        !          1320:                regs.fpsr = (tmp == 0 ? 0x4000000 : 0) |
        !          1321:                    (tmp < 0 ? 0x8000000 : 0);
        !          1322:            }
        !          1323:            break;
        !          1324:        case 0x3a:              /* FTST */
        !          1325:            regs.fpsr = (src == 0 ? 0x4000000 : 0) |
        !          1326:                (src < 0 ? 0x8000000 : 0);
        !          1327:            break;
        !          1328:        default:
        !          1329:            m68k_setpc (m68k_getpc () - 4);
        !          1330:            op_illg (opcode);
        !          1331:            break;
        !          1332:        }
        !          1333:        return;
        !          1334:     }
        !          1335:     m68k_setpc (m68k_getpc () - 4);
        !          1336:     op_illg (opcode);
1.1       root     1337: }
                   1338: 
                   1339: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.