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

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

unix.superglobalmegacorp.com

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