Annotation of hatari/src/uae-cpu/fpp.c, revision 1.1

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

unix.superglobalmegacorp.com

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