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

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

unix.superglobalmegacorp.com

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