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

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

unix.superglobalmegacorp.com

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