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

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:            }
                    751:        } else if ((opcode & 0x38) == 1) {
                    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:
                    842:        {
                    843:            uae_u32 ad, list = 0;
                    844:            int incr = 0;
                    845:            if (extra & 0x2000) {
                    846:                /* FMOVEM FPP->memory */
1.1.1.5   root      847:                if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3   root      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) {
1.1.1.5   root      873:                        from_exten (regs.fp[fpp_movem_index2[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3   root      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 {
1.1.1.5   root      881:                        from_exten (regs.fp[fpp_movem_index1[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3   root      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       root      888:                    }
1.1.1.3   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 */
1.1.1.5   root      897:                if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3   root      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.3   root      939:                    list = fpp_movem_next[list];
1.1       root      940:                }
1.1.1.3   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;
                    945:            }
                    946:        }
                    947:        return;
                    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 */
                   1035:            regs.fp[reg] = src;
1.1.1.5   root     1036:            /* Brian King was here.  <ea> to register needs FPSR updated.
                   1037:             * See page 3-73 in Motorola 68K programmers reference manual.
                   1038:             * %%%FPU */
                   1039:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1040:            break;
1.1.1.4   root     1041:        case 0x01:              /* FINT */
1.1.1.5   root     1042:            /* need to take the current rounding mode into account */
                   1043:            switch ((regs.fpcr >> 4) & 0x3) {
1.1.1.4   root     1044:            case 0:
1.1.1.5   root     1045:                regs.fp[reg] = (int) (src + 0.5);
                   1046:                break;
1.1.1.4   root     1047:            case 1:
1.1.1.5   root     1048:                regs.fp[reg] = (int) src;
                   1049:                break;
1.1.1.4   root     1050:            case 2:
1.1.1.5   root     1051:                regs.fp[reg] = floor (src);
                   1052:                break;
1.1.1.4   root     1053:            case 3:
1.1.1.5   root     1054:                regs.fp[reg] = ceil (src);
                   1055:                break;
                   1056:            }
1.1.1.4   root     1057:            break;
1.1.1.3   root     1058:        case 0x02:              /* FSINH */
                   1059:            regs.fp[reg] = sinh (src);
1.1.1.5   root     1060:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1061:            break;
                   1062:        case 0x03:              /* FINTRZ */
                   1063:            regs.fp[reg] = (int) src;
1.1.1.5   root     1064:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1065:            break;
                   1066:        case 0x04:              /* FSQRT */
                   1067:            regs.fp[reg] = sqrt (src);
1.1.1.5   root     1068:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1069:            break;
                   1070:        case 0x06:              /* FLOGNP1 */
                   1071:            regs.fp[reg] = log (src + 1.0);
1.1.1.5   root     1072:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1073:            break;
                   1074:        case 0x08:              /* FETOXM1 */
                   1075:            regs.fp[reg] = exp (src) - 1.0;
1.1.1.5   root     1076:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1077:            break;
                   1078:        case 0x09:              /* FTANH */
                   1079:            regs.fp[reg] = tanh (src);
1.1.1.5   root     1080:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1081:            break;
                   1082:        case 0x0a:              /* FATAN */
                   1083:            regs.fp[reg] = atan (src);
1.1.1.5   root     1084:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1085:            break;
                   1086:        case 0x0c:              /* FASIN */
                   1087:            regs.fp[reg] = asin (src);
1.1.1.5   root     1088:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1089:            break;
                   1090:        case 0x0d:              /* FATANH */
                   1091: #if 1                          /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */
                   1092:            regs.fp[reg] = log ((1 + src) / (1 - src)) / 2;
1.1       root     1093: #else
1.1.1.3   root     1094:            regs.fp[reg] = atanh (src);
1.1       root     1095: #endif
1.1.1.5   root     1096:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1097:            break;
                   1098:        case 0x0e:              /* FSIN */
                   1099:            regs.fp[reg] = sin (src);
1.1.1.5   root     1100:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1101:            break;
                   1102:        case 0x0f:              /* FTAN */
                   1103:            regs.fp[reg] = tan (src);
1.1.1.5   root     1104:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1105:            break;
                   1106:        case 0x10:              /* FETOX */
                   1107:            regs.fp[reg] = exp (src);
1.1.1.5   root     1108:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1109:            break;
                   1110:        case 0x11:              /* FTWOTOX */
1.1.1.5   root     1111:            regs.fp[reg] = pow (2.0, src);
                   1112:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1113:            break;
                   1114:        case 0x12:              /* FTENTOX */
1.1.1.5   root     1115:            regs.fp[reg] = pow (10.0, src);
                   1116:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1117:            break;
                   1118:        case 0x14:              /* FLOGN */
                   1119:            regs.fp[reg] = log (src);
1.1.1.5   root     1120:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1121:            break;
                   1122:        case 0x15:              /* FLOG10 */
                   1123:            regs.fp[reg] = log10 (src);
1.1.1.5   root     1124:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1125:            break;
                   1126:        case 0x16:              /* FLOG2 */
                   1127:            regs.fp[reg] = log (src) / log (2.0);
1.1.1.5   root     1128:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1129:            break;
                   1130:        case 0x18:              /* FABS */
                   1131:            regs.fp[reg] = src < 0 ? -src : src;
1.1.1.5   root     1132:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1133:            break;
                   1134:        case 0x19:              /* FCOSH */
1.1.1.5   root     1135:            regs.fp[reg] = cosh (src);
                   1136:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1137:            break;
                   1138:        case 0x1a:              /* FNEG */
                   1139:            regs.fp[reg] = -src;
1.1.1.5   root     1140:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1141:            break;
                   1142:        case 0x1c:              /* FACOS */
1.1.1.5   root     1143:            regs.fp[reg] = acos (src);
                   1144:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1145:            break;
                   1146:        case 0x1d:              /* FCOS */
1.1.1.5   root     1147:            regs.fp[reg] = cos (src);
                   1148:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1149:            break;
                   1150:        case 0x1e:              /* FGETEXP */
                   1151:            {
                   1152:                int expon;
                   1153:                frexp (src, &expon);
                   1154:                regs.fp[reg] = (double) (expon - 1);
1.1.1.5   root     1155:                MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1156:            }
                   1157:            break;
                   1158:        case 0x1f:              /* FGETMAN */
                   1159:            {
                   1160:                int expon;
                   1161:                regs.fp[reg] = frexp (src, &expon) * 2.0;
1.1.1.5   root     1162:                MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1163:            }
                   1164:            break;
                   1165:        case 0x20:              /* FDIV */
                   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 0x21:              /* FMOD */
1.1.1.5   root     1170:            regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src)) * src;
                   1171:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1172:            break;
                   1173:        case 0x22:              /* FADD */
                   1174:            regs.fp[reg] += src;
1.1.1.5   root     1175:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1176:            break;
                   1177:        case 0x23:              /* FMUL */
                   1178:            regs.fp[reg] *= src;
1.1.1.5   root     1179:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1180:            break;
                   1181:        case 0x24:              /* FSGLDIV */
                   1182:            regs.fp[reg] /= src;
1.1.1.5   root     1183:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1184:            break;
                   1185:        case 0x25:              /* FREM */
1.1.1.5   root     1186:            regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src + 0.5)) * src;
                   1187:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1188:            break;
                   1189:        case 0x26:              /* FSCALE */
                   1190:            regs.fp[reg] *= exp (log (2.0) * src);
1.1.1.5   root     1191:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1192:            break;
                   1193:        case 0x27:              /* FSGLMUL */
                   1194:            regs.fp[reg] *= src;
1.1.1.5   root     1195:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1196:            break;
                   1197:        case 0x28:              /* FSUB */
                   1198:            regs.fp[reg] -= src;
1.1.1.5   root     1199:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1200:            break;
                   1201:        case 0x30:              /* FSINCOS */
                   1202:        case 0x31:
                   1203:        case 0x32:
                   1204:        case 0x33:
                   1205:        case 0x34:
                   1206:        case 0x35:
                   1207:        case 0x36:
                   1208:        case 0x37:
                   1209:            regs.fp[reg] = sin (src);
1.1.1.5   root     1210:            regs.fp[extra & 7] = cos (src);
                   1211:            MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3   root     1212:            break;
                   1213:        case 0x38:              /* FCMP */
                   1214:            {
                   1215:                double tmp = regs.fp[reg] - src;
1.1.1.5   root     1216:                regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
1.1.1.3   root     1217:            }
                   1218:            break;
                   1219:        case 0x3a:              /* FTST */
1.1.1.5   root     1220:            regs.fpsr = (src == 0 ? 0x4000000 : 0) | (src < 0 ? 0x8000000 : 0);
1.1.1.3   root     1221:            break;
                   1222:        default:
                   1223:            m68k_setpc (m68k_getpc () - 4);
                   1224:            op_illg (opcode);
                   1225:            break;
                   1226:        }
                   1227:        return;
                   1228:     }
                   1229:     m68k_setpc (m68k_getpc () - 4);
                   1230:     op_illg (opcode);
1.1       root     1231: }
                   1232: 
                   1233: #endif

unix.superglobalmegacorp.com

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