Annotation of hatari/src/uae-cpu/fpp.c, revision 1.1.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.