Annotation of hatari/src/uae-cpu/fpp.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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