--- uae/src/fpp.c 2018/04/24 16:39:11 1.1.1.2 +++ uae/src/fpp.c 2018/04/24 16:40:04 1.1.1.3 @@ -13,15 +13,13 @@ #include "config.h" #include "options.h" -#include "events.h" -#include "gui.h" #include "memory.h" #include "custom.h" #include "readcpu.h" #include "newcpu.h" #include "ersatz.h" -#if CPU_LEVEL >= 3 +#if 1 #define DEBUG_FPP 0 @@ -33,1106 +31,1309 @@ /* E = MAX & F # 0 -> NotANumber */ /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */ -static __inline__ double -to_single(ULONG value) +static __inline__ double to_single (uae_u32 value) { - double frac; + double frac; - if ((value & 0x7fffffff) == 0) return(0.0); - frac = (double)((value & 0x7fffff) | 0x800000) / 8388608.0; - if (value & 0x80000000) frac = -frac; - return(ldexp(frac, ((value >> 23) & 0xff) - 127)); + if ((value & 0x7fffffff) == 0) + return (0.0); + frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0; + if (value & 0x80000000) + frac = -frac; + return (ldexp (frac, ((value >> 23) & 0xff) - 127)); } -static __inline__ ULONG -from_single(double src) +static __inline__ uae_u32 from_single (double src) { - int expon; - ULONG tmp; - double frac; - - if (src == 0.0) return 0; - if (src < 0) { tmp = 0x80000000 ; src = -src; } - else { tmp = 0; } - frac = frexp(src,&expon); - frac += 0.5 / 16777216.0; - if (frac >= 1.0) { frac /= 2.0; expon++; } - return (tmp | (((expon + 127 - 1) & 0xff) << 23) | - (((int)(frac * 16777216.0)) & 0x7fffff)); + int expon; + uae_u32 tmp; + double frac; + + if (src == 0.0) + return 0; + if (src < 0) { + tmp = 0x80000000; + src = -src; + } else { + tmp = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 16777216.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + return (tmp | (((expon + 127 - 1) & 0xff) << 23) | + (((int) (frac * 16777216.0)) & 0x7fffff)); } -static __inline__ double -to_exten(ULONG wrd1,ULONG wrd2,ULONG wrd3) +static __inline__ double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) { - double frac; + double frac; - if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) return 0.0; - frac = (double)wrd2 / 2147483648.0 + - (double)wrd3 / 9223372036854775808.0; - if (wrd1 & 0x80000000) frac = -frac; - return ldexp(frac, ((wrd1 >> 16) & 0x7fff) - 16383); + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) + return 0.0; + frac = (double) wrd2 / 2147483648.0 + + (double) wrd3 / 9223372036854775808.0; + if (wrd1 & 0x80000000) + frac = -frac; + return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); } -static __inline__ void -from_exten(double src,ULONG *wrd1, ULONG *wrd2, ULONG * wrd3) +static __inline__ void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) { - int expon; - double frac; + int expon; + double frac; - if (src == 0.0) { *wrd1 = 0; *wrd2 = 0; *wrd3 = 0; return; } - if (src < 0) { *wrd1 = 0x80000000 ; src = -src; } - else { *wrd1 = 0; } - frac = frexp(src,&expon); - frac += 0.5 / 18446744073709551616.0; - if (frac >= 1.0) { frac /= 2.0; expon++; } - *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); - *wrd2 = (ULONG)(frac * 4294967296.0); - *wrd3 = (ULONG)(frac * 18446744073709551616.0 - *wrd2 * 4294967296.0); + if (src == 0.0) { + *wrd1 = 0; + *wrd2 = 0; + *wrd3 = 0; + return; + } + if (src < 0) { + *wrd1 = 0x80000000; + src = -src; + } else { + *wrd1 = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 18446744073709551616.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); + *wrd2 = (uae_u32) (frac * 4294967296.0); + *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0); } -static __inline__ double -to_double(ULONG wrd1,ULONG wrd2) +static __inline__ double to_double(uae_u32 wrd1, uae_u32 wrd2) { - double frac; + double frac; - if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) return 0.0; - frac = (double)((wrd1 & 0xfffff) | 0x100000) / 1048576.0 + - (double)wrd2 / 4503599627370496.0; - if (wrd1 & 0x80000000) frac = -frac; - return ldexp(frac, ((wrd1 >> 20) & 0x7ff) - 1023); + if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) + return 0.0; + frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 + + (double) wrd2 / 4503599627370496.0; + if (wrd1 & 0x80000000) + frac = -frac; + return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023); } -static __inline__ void -from_double(double src,ULONG *wrd1, ULONG *wrd2) +static __inline__ void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) { - int expon; - int tmp; - double frac; - - if (src == 0.0) { *wrd1 = 0; *wrd2 = 0; return; } - if (src < 0) { *wrd1 = 0x80000000 ; src = -src; } - else { *wrd1 = 0; } - frac = frexp(src,&expon); - frac += 0.5 / 9007199254740992.0; - if (frac >= 1.0) { frac /= 2.0; expon++; } - tmp = (ULONG)(frac * 2097152.0); - *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff); - *wrd2 = (ULONG)(frac * 9007199254740992.0 - tmp * 4294967296.0); + int expon; + int tmp; + double frac; + + if (src == 0.0) { + *wrd1 = 0; + *wrd2 = 0; + return; + } + if (src < 0) { + *wrd1 = 0x80000000; + src = -src; + } else { + *wrd1 = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 9007199254740992.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + tmp = (uae_u32) (frac * 2097152.0); + *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff); + *wrd2 = (uae_u32) (frac * 9007199254740992.0 - tmp * 4294967296.0); } -static __inline__ double -to_pack(ULONG wrd1,ULONG wrd2,ULONG wrd3) +static __inline__ double to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) { - double d; - char *cp; - char str[100]; - - cp = str; - if (wrd1 & 0x80000000) *cp++ = '-'; - *cp++ = (wrd1 & 0xf) + '0'; - *cp++ = '.'; - *cp++ = ((wrd2 >> 28) & 0xf) + '0'; - *cp++ = ((wrd2 >> 24) & 0xf) + '0'; - *cp++ = ((wrd2 >> 20) & 0xf) + '0'; - *cp++ = ((wrd2 >> 16) & 0xf) + '0'; - *cp++ = ((wrd2 >> 12) & 0xf) + '0'; - *cp++ = ((wrd2 >> 8) & 0xf) + '0'; - *cp++ = ((wrd2 >> 4) & 0xf) + '0'; - *cp++ = ((wrd2 >> 0) & 0xf) + '0'; - *cp++ = ((wrd3 >> 28) & 0xf) + '0'; - *cp++ = ((wrd3 >> 24) & 0xf) + '0'; - *cp++ = ((wrd3 >> 20) & 0xf) + '0'; - *cp++ = ((wrd3 >> 16) & 0xf) + '0'; - *cp++ = ((wrd3 >> 12) & 0xf) + '0'; - *cp++ = ((wrd3 >> 8) & 0xf) + '0'; - *cp++ = ((wrd3 >> 4) & 0xf) + '0'; - *cp++ = ((wrd3 >> 0) & 0xf) + '0'; - *cp++ = 'E'; - if (wrd1 & 0x40000000) *cp++ = '-'; - *cp++ = ((wrd1 >> 24) & 0xf) + '0'; - *cp++ = ((wrd1 >> 20) & 0xf) + '0'; - *cp++ = ((wrd1 >> 16) & 0xf) + '0'; - *cp = 0; - sscanf(str,"%le",&d); - return d; + double d; + char *cp; + char str[100]; + + cp = str; + if (wrd1 & 0x80000000) + *cp++ = '-'; + *cp++ = (wrd1 & 0xf) + '0'; + *cp++ = '.'; + *cp++ = ((wrd2 >> 28) & 0xf) + '0'; + *cp++ = ((wrd2 >> 24) & 0xf) + '0'; + *cp++ = ((wrd2 >> 20) & 0xf) + '0'; + *cp++ = ((wrd2 >> 16) & 0xf) + '0'; + *cp++ = ((wrd2 >> 12) & 0xf) + '0'; + *cp++ = ((wrd2 >> 8) & 0xf) + '0'; + *cp++ = ((wrd2 >> 4) & 0xf) + '0'; + *cp++ = ((wrd2 >> 0) & 0xf) + '0'; + *cp++ = ((wrd3 >> 28) & 0xf) + '0'; + *cp++ = ((wrd3 >> 24) & 0xf) + '0'; + *cp++ = ((wrd3 >> 20) & 0xf) + '0'; + *cp++ = ((wrd3 >> 16) & 0xf) + '0'; + *cp++ = ((wrd3 >> 12) & 0xf) + '0'; + *cp++ = ((wrd3 >> 8) & 0xf) + '0'; + *cp++ = ((wrd3 >> 4) & 0xf) + '0'; + *cp++ = ((wrd3 >> 0) & 0xf) + '0'; + *cp++ = 'E'; + if (wrd1 & 0x40000000) + *cp++ = '-'; + *cp++ = ((wrd1 >> 24) & 0xf) + '0'; + *cp++ = ((wrd1 >> 20) & 0xf) + '0'; + *cp++ = ((wrd1 >> 16) & 0xf) + '0'; + *cp = 0; + sscanf(str, "%le", &d); + return d; } -static __inline__ void -from_pack(double src,ULONG *wrd1, ULONG *wrd2, ULONG * wrd3) +static __inline__ void from_pack(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) { - int i; - int t; - char *cp; - char str[100]; - - sprintf(str,"%.16e",src); - cp = str; - *wrd1 = *wrd2 = *wrd3 = 0; - if (*cp == '-') { cp++ ; *wrd1 = 0x80000000; } - if (*cp == '+') cp++; - *wrd1 |= (*cp++ - '0'); - if (*cp == '.') cp++; - for (i = 0 ; i < 8 ; i++) { - *wrd2 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd2 |= *cp++ - '0'; - } - for (i = 0 ; i < 8 ; i++) { - *wrd3 <<= 4; - if (*cp >= '0' && *cp <= '9') - *wrd3 |= *cp++ - '0'; - } - if (*cp == 'e' || *cp == 'E') { - cp++; - if (*cp == '-') { cp++; *wrd1 |= 0x40000000; } - if (*cp == '+') cp++; - t = 0; - for (i = 0 ; i < 3 ; i++) { - if (*cp >= '0' && *cp <= '9') - t = (t << 4) | (*cp++ - '0'); - } - *wrd1 |= t << 16; + int i; + int t; + char *cp; + char str[100]; + + sprintf(str, "%.16e", src); + cp = str; + *wrd1 = *wrd2 = *wrd3 = 0; + if (*cp == '-') { + cp++; + *wrd1 = 0x80000000; + } + if (*cp == '+') + cp++; + *wrd1 |= (*cp++ - '0'); + if (*cp == '.') + cp++; + for (i = 0; i < 8; i++) { + *wrd2 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd2 |= *cp++ - '0'; + } + for (i = 0; i < 8; i++) { + *wrd3 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd3 |= *cp++ - '0'; + } + if (*cp == 'e' || *cp == 'E') { + cp++; + if (*cp == '-') { + cp++; + *wrd1 |= 0x40000000; + } + if (*cp == '+') + cp++; + t = 0; + for (i = 0; i < 3; i++) { + if (*cp >= '0' && *cp <= '9') + t = (t << 4) | (*cp++ - '0'); } + *wrd1 |= t << 16; + } } -static __inline__ int -get_fp_value(ULONG opcode, UWORD extra,double *src) +static __inline__ int get_fp_value (uae_u32 opcode, uae_u16 extra, double *src) { - int size; - int mode; - int reg; - ULONG ad = 0; - static int sz1[8] = { 4,4,12,12,2,8,1,0 }; - static int sz2[8] = { 4,4,12,12,2,8,2,0 }; - - if ((extra & 0x4000) == 0) { - *src = regs.fp[(extra >> 10) & 7]; - return 1; - } - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - switch (mode) { + uaecptr tmppc; + uae_u16 tmp; + int size; + int mode; + int reg; + uae_u32 ad = 0; + static int sz1[8] = + {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = + {4, 4, 12, 12, 2, 8, 2, 0}; + + if ((extra & 0x4000) == 0) { + *src = regs.fp[(extra >> 10) & 7]; + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + switch (mode) { + case 0: + switch (size) { + case 6: + *src = (double) (uae_s8) m68k_dreg (regs, reg); + break; + case 4: + *src = (double) (uae_s16) m68k_dreg (regs, reg); + break; case 0: - switch (size) { - case 6: *src = (double)(BYTE)m68k_dreg(regs, reg); - break; - case 4: *src = (double)(WORD)m68k_dreg(regs, reg); - break; - case 0: *src = (double)(LONG)m68k_dreg(regs, reg); - break; - case 1: *src = to_single(m68k_dreg(regs, reg)); - break; - default: - return 0; - } - return 1; + *src = (double) (uae_s32) m68k_dreg (regs, reg); + break; + case 1: + *src = to_single(m68k_dreg (regs, reg)); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + ad = m68k_areg (regs, reg); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; case 1: - return 0; + ad = next_ilong(); + break; case 2: - ad = m68k_areg(regs, reg); - break; + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; case 3: - ad = m68k_areg(regs, reg); - m68k_areg(regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; + tmppc = m68k_getpc (); + tmp = next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; case 4: - m68k_areg(regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg(regs, reg); - break; - case 5: - ad = m68k_areg(regs, reg) + (LONG)(WORD)nextiword(); - break; - case 6: - ad = get_disp_ea(m68k_areg(regs, reg)); - break; - case 7: - switch (reg) { - case 0: ad = (LONG)(WORD)nextiword(); - break; - case 1: ad = nextilong(); - break; - case 2: ad = m68k_getpc(); - ad += (LONG)(WORD)nextiword(); - break; - case 3: ad = get_disp_ea(m68k_getpc()); - break; - case 4: ad = m68k_getpc(); - m68k_setpc(ad + sz2[size]); - break; - default: - return 0; - } - } - switch (size) { - case 0: *src = (double)(LONG)get_long(ad); - break; - case 1: *src = to_single(get_long(ad)); - break; - case 2: { ULONG wrd1,wrd2,wrd3; - wrd1 = get_long(ad);ad+=4; - wrd2 = get_long(ad);ad+=4; - wrd3 = get_long(ad); - *src = to_exten(wrd1,wrd2,wrd3); - } - break; - case 3: { ULONG wrd1,wrd2,wrd3; - wrd1 = get_long(ad);ad+=4; - wrd2 = get_long(ad);ad+=4; - wrd3 = get_long(ad); - *src = to_pack(wrd1,wrd2,wrd3); - } - break; - case 4: *src = (double)(WORD)get_word(ad); - break; - case 5: { ULONG wrd1,wrd2; - wrd1 = get_long(ad);ad+=4; - wrd2 = get_long(ad); - *src = to_double(wrd1,wrd2); - } - break; - case 6: *src = (double)(BYTE)get_byte(ad); - break; + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + break; default: - return 0; + return 0; } - return 1; + } + switch (size) { + case 0: + *src = (double) (uae_s32) get_long (ad); + break; + case 1: + *src = to_single(get_long (ad)); + break; + case 2:{ + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + *src = to_exten(wrd1, wrd2, wrd3); + } + break; + case 3:{ + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + *src = to_pack(wrd1, wrd2, wrd3); + } + break; + case 4: + *src = (double) (uae_s16) get_word(ad); + break; + case 5:{ + uae_u32 wrd1, wrd2; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + *src = to_double(wrd1, wrd2); + } + break; + case 6: + *src = (double) (uae_s8) get_byte(ad); + break; + default: + return 0; + } + return 1; } -static __inline__ int -put_fp_value(double value, ULONG opcode, UWORD extra) +static __inline__ int put_fp_value (double value, uae_u32 opcode, uae_u16 extra) { - int size; - int mode; - int reg; - ULONG ad; - static int sz1[8] = { 4,4,12,12,2,8,1,0 }; - static int sz2[8] = { 4,4,12,12,2,8,2,0 }; - - if ((extra & 0x4000) == 0) { - regs.fp[(extra >> 10) & 7] = value; - return 1; - } - mode = (opcode >> 3) & 7; - reg = opcode & 7; - size = (extra >> 10) & 7; - ad = -1; - switch (mode) { + uae_u16 tmp; + uaecptr tmppc; + int size; + int mode; + int reg; + uae_u32 ad; + static int sz1[8] = + {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = + {4, 4, 12, 12, 2, 8, 2, 0}; + + if ((extra & 0x4000) == 0) { + regs.fp[(extra >> 10) & 7] = value; + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + ad = -1; + switch (mode) { + case 0: + switch (size) { + case 6: + m68k_dreg (regs, reg) = (((int) value & 0xff) + | (m68k_dreg (regs, reg) & ~0xff)); + break; + case 4: + m68k_dreg (regs, reg) = (((int) value & 0xffff) + | (m68k_dreg (regs, reg) & ~0xffff)); + break; case 0: - switch (size) { - case 6: m68k_dreg(regs, reg) = ((int)value & 0xff) | - (m68k_dreg(regs, reg) & ~0xff); - break; - case 4: m68k_dreg(regs, reg) = ((int)value & 0xffff) | - (m68k_dreg(regs, reg) & ~0xffff); - break; - case 0: m68k_dreg(regs, reg) = (int)value; - break; - case 1: m68k_dreg(regs, reg) = from_single(value); - break; - default: - return 0; - } - return 1; + m68k_dreg (regs, reg) = (int) value; + break; case 1: - return 0; + m68k_dreg (regs, reg) = from_single(value); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + ad = m68k_areg (regs, reg); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; case 2: - ad = m68k_areg(regs, reg); - break; + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; case 3: - ad = m68k_areg(regs, reg); - m68k_areg(regs, reg) += reg == 7 ? sz2[size] : sz1[size]; - break; + tmppc = m68k_getpc (); + tmp = next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; case 4: - m68k_areg(regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; - ad = m68k_areg(regs, reg); - break; - case 5: - ad = m68k_areg(regs, reg) + (LONG)(WORD)nextiword(); - break; - case 6: - ad = get_disp_ea(m68k_areg(regs, reg)); - break; - case 7: - switch (reg) { - case 0: ad = (LONG)(WORD)nextiword(); - break; - case 1: ad = nextilong(); - break; - case 2: ad = m68k_getpc(); - ad += (LONG)(WORD)nextiword(); - break; - case 3: ad = get_disp_ea(m68k_getpc()); - break; - case 4: ad = m68k_getpc(); - m68k_setpc(ad + sz2[size]); - break; - default: - return 0; - } - } - switch (size) { - case 0: put_long(ad,(LONG)value); - break; - case 1: put_long(ad,from_single(value)); - break; - case 2: { ULONG wrd1,wrd2,wrd3; - from_exten(value,&wrd1,&wrd2,&wrd3); - put_long(ad,wrd1);ad+=4; - put_long(ad,wrd2);ad+=4; - put_long(ad,wrd3); - } - break; - case 3: { ULONG wrd1,wrd2,wrd3; - from_pack(value,&wrd1,&wrd2,&wrd3); - put_long(ad,wrd1);ad+=4; - put_long(ad,wrd2);ad+=4; - put_long(ad,wrd3); - } - break; - case 4: put_word(ad,(WORD)value); - break; - case 5: { ULONG wrd1,wrd2; - from_double(value,&wrd1,&wrd2); - put_long(ad,wrd1);ad+=4; - put_long(ad,wrd2); - } - break; - case 6: put_byte(ad,(BYTE)value); - break; + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + break; default: - return 0; + return 0; } - return 1; + } + switch (size) { + case 0: + put_long (ad, (uae_s32) value); + break; + case 1: + put_long (ad, from_single(value)); + break; + case 2: + { + uae_u32 wrd1, wrd2, wrd3; + from_exten(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 3: + { + uae_u32 wrd1, wrd2, wrd3; + from_pack(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 4: + put_word(ad, (uae_s16) value); + break; + case 5:{ + uae_u32 wrd1, wrd2; + from_double(value, &wrd1, &wrd2); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + } + break; + case 6: + put_byte(ad, (uae_s8) value); + break; + default: + return 0; + } + return 1; } -static __inline__ int -get_fp_ad(ULONG opcode,ULONG *ad) +static __inline__ int get_fp_ad(uae_u32 opcode, uae_u32 * ad) { - int mode; - int reg; - - mode = (opcode >> 3) & 7; - reg = opcode & 7; - switch (mode) { + uae_u16 tmp; + uaecptr tmppc; + int mode; + int reg; + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) { + case 0: + case 1: + return 0; + case 2: + *ad = m68k_areg (regs, reg); + break; + case 3: + *ad = m68k_areg (regs, reg); + break; + case 4: + *ad = m68k_areg (regs, reg); + break; + case 5: + *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { case 0: + *ad = (uae_s32) (uae_s16) next_iword(); + break; case 1: - return 0; + *ad = next_ilong(); + break; case 2: - *ad = m68k_areg(regs, reg); - break; + *ad = m68k_getpc (); + *ad += (uae_s32) (uae_s16) next_iword(); + break; case 3: - *ad = m68k_areg(regs, reg); - break; - case 4: - *ad = m68k_areg(regs, reg); - break; - case 5: - *ad = m68k_areg(regs, reg) + (LONG)(WORD)nextiword(); - break; - case 6: - *ad = get_disp_ea(m68k_areg(regs, reg)); - break; - case 7: - switch (reg) { - case 0: *ad = (LONG)(WORD)nextiword(); - break; - case 1: *ad = nextilong(); - break; - case 2: *ad = m68k_getpc(); - *ad += (LONG)(WORD)nextiword(); - break; - case 3: *ad = get_disp_ea(m68k_getpc()); - break; - default: - return 0; - } + tmppc = m68k_getpc (); + tmp = next_iword(); + *ad = get_disp_ea_020 (tmppc, tmp); + break; + default: + return 0; } - return 1; + } + return 1; } -static __inline__ int -fpp_cond(ULONG opcode, int contition) +static __inline__ int fpp_cond(uae_u32 opcode, int contition) { - int N = (regs.fpsr & 0x8000000) != 0; - int Z = (regs.fpsr & 0x4000000) != 0; - /* int I = (regs.fpsr & 0x2000000) != 0; */ - int NotANumber = (regs.fpsr & 0x1000000) != 0; - - switch (contition) { - case 0x00: return 0; - case 0x01: return Z; - case 0x02: return !(NotANumber || Z || N); - case 0x03: return Z || !(NotANumber || N); - case 0x04: return N && !(NotANumber || Z); - case 0x05: return Z || (N && !NotANumber); - case 0x06: return !(NotANumber || Z); - case 0x07: return !NotANumber; - case 0x08: return NotANumber; - case 0x09: return NotANumber || Z; - case 0x0a: return NotANumber || !(N || Z); - case 0x0b: return NotANumber || Z || !N; - case 0x0c: return NotANumber || (N && !Z); - case 0x0d: return NotANumber || Z || N; - case 0x0e: return !Z; - case 0x0f: return 1; - case 0x10: return 0; - case 0x11: return Z; - case 0x12: return !(NotANumber || Z || N); - case 0x13: return Z || !(NotANumber || N); - case 0x14: return N && !(NotANumber || Z); - case 0x15: return Z || (N && !NotANumber); - case 0x16: return !(NotANumber || Z); - case 0x17: return !NotANumber; - case 0x18: return NotANumber; - case 0x19: return NotANumber || Z; - case 0x1a: return NotANumber || !(N || Z); - case 0x1b: return NotANumber || Z || !N; - case 0x1c: return NotANumber || (Z && N); - case 0x1d: return NotANumber || Z || N; - case 0x1e: return !Z; - case 0x1f: return 1; - } - return -1; + int N = (regs.fpsr & 0x8000000) != 0; + int Z = (regs.fpsr & 0x4000000) != 0; + /* int I = (regs.fpsr & 0x2000000) != 0; */ + int NotANumber = (regs.fpsr & 0x1000000) != 0; + + switch (contition) { + case 0x00: + return 0; + case 0x01: + return Z; + case 0x02: + return !(NotANumber || Z || N); + case 0x03: + return Z || !(NotANumber || N); + case 0x04: + return N && !(NotANumber || Z); + case 0x05: + return Z || (N && !NotANumber); + case 0x06: + return !(NotANumber || Z); + case 0x07: + return !NotANumber; + case 0x08: + return NotANumber; + case 0x09: + return NotANumber || Z; + case 0x0a: + return NotANumber || !(N || Z); + case 0x0b: + return NotANumber || Z || !N; + case 0x0c: + return NotANumber || (N && !Z); + case 0x0d: + return NotANumber || Z || N; + case 0x0e: + return !Z; + case 0x0f: + return 1; + case 0x10: + return 0; + case 0x11: + return Z; + case 0x12: + return !(NotANumber || Z || N); + case 0x13: + return Z || !(NotANumber || N); + case 0x14: + return N && !(NotANumber || Z); + case 0x15: + return Z || (N && !NotANumber); + case 0x16: + return !(NotANumber || Z); + case 0x17: + return !NotANumber; + case 0x18: + return NotANumber; + case 0x19: + return NotANumber || Z; + case 0x1a: + return NotANumber || !(N || Z); + case 0x1b: + return NotANumber || Z || !N; + case 0x1c: + return NotANumber || (Z && N); + case 0x1d: + return NotANumber || Z || N; + case 0x1e: + return !Z; + case 0x1f: + return 1; + } + return -1; } -void -fdbcc_opp(ULONG opcode, UWORD extra) +void fdbcc_opp(uae_u32 opcode, uae_u16 extra) { - CPTR pc = (ULONG)m68k_getpc(); - LONG disp = (LONG)(WORD)nextiword(); - int cc; + uaecptr pc = (uae_u32) m68k_getpc (); + uae_s32 disp = (uae_s32) (uae_s16) next_iword(); + int cc; #if DEBUG_FPP - printf("fdbcc_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("fdbcc_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - cc = fpp_cond(opcode, extra & 0x3f); - if (cc == -1) { - m68k_setpc(pc-2); - op_illg(opcode); - } else if (!cc) { - int reg = opcode & 0x7; - - m68k_dreg(regs, reg) = ((m68k_dreg(regs, reg) & ~0xffff) - | ((m68k_dreg(regs, reg)-1) & 0xffff)); - if ((m68k_dreg(regs, reg) & 0xffff) == 0xffff) - m68k_setpc(pc + disp); - } + cc = fpp_cond(opcode, extra & 0x3f); + if (cc == -1) { + m68k_setpc (pc - 4); + op_illg (opcode); + } else if (!cc) { + int reg = opcode & 0x7; + + m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff) + | ((m68k_dreg (regs, reg) - 1) & 0xffff)); + if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff) + m68k_setpc (pc + disp); + } } -void -fscc_opp(ULONG opcode, UWORD extra) +void fscc_opp(uae_u32 opcode, uae_u16 extra) { - ULONG ad; - int cc; + uae_u32 ad; + int cc; #if DEBUG_FPP - printf("fscc_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("fscc_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - cc = fpp_cond(opcode, extra & 0x3f); - if (cc == -1) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - } - else if ((opcode & 0x38) == 0) { - m68k_dreg(regs, opcode & 7) = (m68k_dreg(regs, opcode & 7) & ~0xff) | - (cc ? 0xff : 0x00); - } - else { - if (get_fp_ad(opcode,&ad) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - } - else - put_byte(ad,cc ? 0xff : 0x00); - } + cc = fpp_cond(opcode, extra & 0x3f); + if (cc == -1) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } else if ((opcode & 0x38) == 0) { + m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | + (cc ? 0xff : 0x00); + } else { + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } else + put_byte(ad, cc ? 0xff : 0x00); + } } -void -ftrapcc_opp(ULONG opcode, CPTR oldpc) +void ftrapcc_opp(uae_u32 opcode, uaecptr oldpc) { - int cc; + int cc; #if DEBUG_FPP - printf("ftrapcc_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("ftrapcc_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - cc = fpp_cond(opcode, opcode & 0x3f); - if (cc == -1) { - m68k_setpc(oldpc); - op_illg(opcode); - } - if (cc) - Exception(7,oldpc-2); + cc = fpp_cond(opcode, opcode & 0x3f); + if (cc == -1) { + m68k_setpc (oldpc); + op_illg (opcode); + } + if (cc) + Exception(7, oldpc - 2); } -void -fbcc_opp(ULONG opcode, CPTR pc, ULONG extra) +void fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra) { - int cc; + int cc; #if DEBUG_FPP - printf("fbcc_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("fbcc_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - cc = fpp_cond(opcode, opcode & 0x3f); - if (cc == -1) { - m68k_setpc(pc); - op_illg(opcode); - } - else if (cc) { - if ((opcode & 0x40) == 0) - extra = (LONG)(WORD)extra; - m68k_setpc(pc + extra); - } + cc = fpp_cond(opcode, opcode & 0x3f); + if (cc == -1) { + m68k_setpc (pc); + op_illg (opcode); + } else if (cc) { + if ((opcode & 0x40) == 0) + extra = (uae_s32) (uae_s16) extra; + m68k_setpc (pc + extra); + } } -void -fsave_opp(ULONG opcode) +void fsave_opp(uae_u32 opcode) { - ULONG ad; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - int i; - + uae_u32 ad; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + int i; + #if DEBUG_FPP - printf("fsave_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("fsave_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - if (get_fp_ad(opcode,&ad) == 0) { - op_illg(opcode); - return; - } - if (incr < 0) { - ad -= 4;put_long(ad,0x70000000); - for (i = 0 ; i < 5 ; i++) { - ad -= 4;put_long(ad,0x00000000); - } - ad -= 4;put_long(ad,0x1f180000); - } - else { - put_long(ad,0x1f180000); ad += 4; - for (i = 0 ; i < 5 ; i++) { - put_long(ad,0x00000000); ad += 4; - } - put_long(ad,0x70000000); ad += 4; - } - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad; + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + if (incr < 0) { + ad -= 4; + put_long (ad, 0x70000000); + for (i = 0; i < 5; i++) { + ad -= 4; + put_long (ad, 0x00000000); + } + ad -= 4; + put_long (ad, 0x1f180000); + } else { + put_long (ad, 0x1f180000); + ad += 4; + for (i = 0; i < 5; i++) { + put_long (ad, 0x00000000); + ad += 4; + } + put_long (ad, 0x70000000); + ad += 4; + } + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad; } -void -frestore_opp(ULONG opcode) +void frestore_opp(uae_u32 opcode) { - ULONG ad; - ULONG d; - int incr = (opcode & 0x38) == 0x20 ? -1 : 1; - + uae_u32 ad; + uae_u32 d; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + #if DEBUG_FPP - printf("frestore_opp at %08lx\n",m68k_getpc());fflush(stdout); + printf("frestore_opp at %08lx\n", m68k_getpc ()); + fflush(stdout); #endif - if (get_fp_ad(opcode,&ad) == 0) { - op_illg(opcode); - return; - } - if (incr < 0) { - ad -= 4; d = get_long(ad); - if ((d & 0xff000000) != 0) { - if ((d & 0x00ff0000) == 0x00180000) - ad -= 6 * 4; - else if ((d & 0x00ff0000) == 0x00380000) - ad -= 14 * 4; - else if ((d & 0x00ff0000) == 0x00b40000) - ad -= 45 * 4; - } - } - else { - d = get_long(ad); ad += 4; - if ((d & 0xff000000) != 0) { - if ((d & 0x00ff0000) == 0x00180000) - ad += 6 * 4; - else if ((d & 0x00ff0000) == 0x00380000) - ad += 14 * 4; - else if ((d & 0x00ff0000) == 0x00b40000) - ad += 45 * 4; - } - } - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad; + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + if (incr < 0) { + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) != 0) { + if ((d & 0x00ff0000) == 0x00180000) + ad -= 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad -= 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad -= 45 * 4; + } + } else { + d = get_long (ad); + ad += 4; + if ((d & 0xff000000) != 0) { + if ((d & 0x00ff0000) == 0x00180000) + ad += 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad += 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad += 45 * 4; + } + } + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad; } -void -fpp_opp(ULONG opcode, UWORD extra) +void fpp_opp(uae_u32 opcode, uae_u16 extra) { - int reg; - double src; + int reg; + double src; #if DEBUG_FPP - printf("FPP %04lx %04x at %08lx\n",opcode & 0xffff,extra & 0xffff, - m68k_getpc()-4);fflush(stdout); + printf("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, + m68k_getpc () - 4); + fflush(stdout); #endif - switch ((extra >> 13) & 0x7) { - case 3: - if (put_fp_value(regs.fp[(extra >> 7) & 7], opcode, extra)== 0){ - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - } + switch ((extra >> 13) & 0x7) { + case 3: + if (put_fp_value (regs.fp[(extra >> 7) & 7], opcode, extra) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + return; + case 4: + case 5: + if ((opcode & 0x38) == 0) { + if (extra & 0x2000) { + if (extra & 0x1000) + m68k_dreg (regs, opcode & 7) = regs.fpcr; + if (extra & 0x0800) + m68k_dreg (regs, opcode & 7) = regs.fpsr; + if (extra & 0x0400) + m68k_dreg (regs, opcode & 7) = regs.fpiar; + } else { + if (extra & 0x1000) + regs.fpcr = m68k_dreg (regs, opcode & 7); + if (extra & 0x0800) + regs.fpsr = m68k_dreg (regs, opcode & 7); + if (extra & 0x0400) + regs.fpiar = m68k_dreg (regs, opcode & 7); + } + } else if ((opcode & 0x38) == 1) { + if (extra & 0x2000) { + if (extra & 0x1000) + m68k_areg (regs, opcode & 7) = regs.fpcr; + if (extra & 0x0800) + m68k_areg (regs, opcode & 7) = regs.fpsr; + if (extra & 0x0400) + m68k_areg (regs, opcode & 7) = regs.fpiar; + } else { + if (extra & 0x1000) + regs.fpcr = m68k_areg (regs, opcode & 7); + if (extra & 0x0800) + regs.fpsr = m68k_areg (regs, opcode & 7); + if (extra & 0x0400) + regs.fpiar = m68k_areg (regs, opcode & 7); + } + } else if ((opcode & 0x3f) == 0x3c) { + if ((extra & 0x2000) == 0) { + if (extra & 0x1000) + regs.fpcr = next_ilong(); + if (extra & 0x0800) + regs.fpsr = next_ilong(); + if (extra & 0x0400) + regs.fpiar = next_ilong(); + } + } else if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + uae_u32 ad; + int incr = 0; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); return; - case 4: - case 5: - if ((opcode & 0x38) == 0) { - if (extra & 0x2000) { - if (extra & 0x1000) - m68k_dreg(regs, opcode & 7) = regs.fpcr; - if (extra & 0x0800) - m68k_dreg(regs, opcode & 7) = regs.fpsr; - if (extra & 0x0400) - m68k_dreg(regs, opcode & 7) = regs.fpiar; - } - else { - if (extra & 0x1000) - regs.fpcr = m68k_dreg(regs, opcode & 7); - if (extra & 0x0800) - regs.fpsr = m68k_dreg(regs, opcode & 7); - if (extra & 0x0400) - regs.fpiar = m68k_dreg(regs, opcode & 7); - } - } - else if ((opcode & 0x38) == 1) { - if (extra & 0x2000) { - if (extra & 0x1000) - m68k_areg(regs, opcode & 7) = regs.fpcr; - if (extra & 0x0800) - m68k_areg(regs, opcode & 7) = regs.fpsr; - if (extra & 0x0400) - m68k_areg(regs, opcode & 7) = regs.fpiar; - } - else { - if (extra & 0x1000) - regs.fpcr = m68k_areg(regs, opcode & 7); - if (extra & 0x0800) - regs.fpsr = m68k_areg(regs, opcode & 7); - if (extra & 0x0400) - regs.fpiar = m68k_areg(regs, opcode & 7); - } - } - else if ((opcode & 0x3f) == 0x3c) { - if ((extra & 0x2000) == 0) { - if (extra & 0x1000) - regs.fpcr = nextilong(); - if (extra & 0x0800) - regs.fpsr = nextilong(); - if (extra & 0x0400) - regs.fpiar = nextilong(); - } - } - else if (extra & 0x2000) { - /* FMOVEM FPP->memory */ - ULONG ad; - int incr = 0; - - if (get_fp_ad(opcode,&ad) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - return; - } - if ((opcode & 0x38) == 0x20) { - if (extra & 0x1000) incr += 4; - if (extra & 0x0800) incr += 4; - if (extra & 0x0400) incr += 4; - } - ad -= incr; - if (extra & 0x1000) { - put_long(ad,regs.fpcr);ad+=4; - } - if (extra & 0x0800) { - put_long(ad,regs.fpsr);ad+=4; - } - if (extra & 0x0400) { - put_long(ad,regs.fpiar);ad+=4; - } - ad -= incr; - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad; - } - else { - /* FMOVEM memory->FPP */ - ULONG ad; - - if (get_fp_ad(opcode,&ad) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - return; - } - ad = (opcode & 0x38) == 0x20 ? ad-12 : ad; - if (extra & 0x1000) { - regs.fpcr = get_long(ad);ad+=4; - } - if (extra & 0x0800) { - regs.fpsr = get_long(ad);ad+=4; - } - if (extra & 0x0400) { - regs.fpiar = get_long(ad);ad+=4; - } - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad-12; - } + } + if ((opcode & 0x38) == 0x20) { + if (extra & 0x1000) + incr += 4; + if (extra & 0x0800) + incr += 4; + if (extra & 0x0400) + incr += 4; + } + ad -= incr; + if (extra & 0x1000) { + put_long (ad, regs.fpcr); + ad += 4; + } + if (extra & 0x0800) { + put_long (ad, regs.fpsr); + ad += 4; + } + if (extra & 0x0400) { + put_long (ad, regs.fpiar); + ad += 4; + } + ad -= incr; + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad; + } else { + /* FMOVEM memory->FPP */ + uae_u32 ad; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); return; - case 6: - case 7: - { - ULONG ad,list = 0; - int incr = 0; - if (extra & 0x2000) { - /* FMOVEM FPP->memory */ - if (get_fp_ad(opcode,&ad) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - list = extra & 0xff; - incr = -1; - break; - case 1: /* dynamic pred */ - list = m68k_dreg(regs, (extra >> 4) & 3) & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 3: /* dynamic postinc */ - list = m68k_dreg(regs, (extra >> 4) & 3) & 0xff; - incr = 1; - break; - } - while (list) { - ULONG wrd1,wrd2,wrd3; - if (incr < 0) { - from_exten( - regs.fp[fpp_movem_index2[list]], - &wrd1,&wrd2,&wrd3); - ad-=4;put_long(ad,wrd3); - ad-=4;put_long(ad,wrd2); - ad-=4;put_long(ad,wrd1); - } - else { - from_exten( - regs.fp[fpp_movem_index1[list]], - &wrd1,&wrd2,&wrd3); - put_long(ad,wrd1);ad+=4; - put_long(ad,wrd2);ad+=4; - put_long(ad,wrd3);ad+=4; - } - list = fpp_movem_next[list]; - } - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad; + } + ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad; + if (extra & 0x1000) { + regs.fpcr = get_long (ad); + ad += 4; + } + if (extra & 0x0800) { + regs.fpsr = get_long (ad); + ad += 4; + } + if (extra & 0x0400) { + regs.fpiar = get_long (ad); + ad += 4; + } + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad - 12; + } + return; + case 6: + case 7: + { + uae_u32 ad, list = 0; + int incr = 0; + if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + while (list) { + uae_u32 wrd1, wrd2, wrd3; + if (incr < 0) { + from_exten(regs.fp[fpp_movem_index2[list]], + &wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } else { + from_exten(regs.fp[fpp_movem_index1[list]], + &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; } - else { - /* FMOVEM memory->FPP */ - if (get_fp_ad(opcode,&ad) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - return; - } - switch ((extra >> 11) & 3) { - case 0: /* static pred */ - list = extra & 0xff; - incr = -1; - break; - case 1: /* dynamic pred */ - list = m68k_dreg(regs, (extra >> 4) & 3) & 0xff; - incr = -1; - break; - case 2: /* static postinc */ - list = extra & 0xff; - incr = 1; - break; - case 3: /* dynamic postinc */ - list = m68k_dreg(regs, (extra >> 4) & 3) & 0xff; - incr = 1; - break; - } - while (list) { - ULONG wrd1,wrd2,wrd3; - if (incr < 0) { - ad-=4;wrd3 = get_long(ad); - ad-=4;wrd2 = get_long(ad); - ad-=4;wrd1 = get_long(ad); - regs.fp[fpp_movem_index2[list]] = - to_exten(wrd1,wrd2,wrd3); - } - else { - wrd1 = get_long(ad);ad+=4; - wrd2 = get_long(ad);ad+=4; - wrd3 = get_long(ad);ad+=4; - regs.fp[fpp_movem_index1[list]] = - to_exten(wrd1,wrd2,wrd3); - } - list = fpp_movem_next[list]; - } - if ((opcode & 0x38) == 0x18) m68k_areg(regs, opcode & 7) = ad; - if ((opcode & 0x38) == 0x20) m68k_areg(regs, opcode & 7) = ad; + list = fpp_movem_next[list]; + } + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad; + } else { + /* FMOVEM memory->FPP */ + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + while (list) { + uae_u32 wrd1, wrd2, wrd3; + if (incr < 0) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3); + } else { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3); } + list = fpp_movem_next[list]; } - return; - case 0: - case 2: - reg = (extra >> 7) & 7; - if ((extra & 0xfc00) == 0x5c00) { - switch (extra & 0x7f) { - case 0x00: regs.fp[reg] = 4.0*atan(1.0); break; - case 0x0b: regs.fp[reg] = log10(2.0); break; - case 0x0c: regs.fp[reg] = exp(1.0); break; - case 0x0d: regs.fp[reg] = log(exp(1.0))/log(2.0); break; - case 0x0e: regs.fp[reg] = log(exp(1.0))/log(10.0); break; - case 0x0f: regs.fp[reg] = 0.0; break; - case 0x30: regs.fp[reg] = log(2.0); break; - case 0x31: regs.fp[reg] = log(10.0); break; - case 0x32: regs.fp[reg] = 1.0e0; break; - case 0x33: regs.fp[reg] = 1.0e1; break; - case 0x34: regs.fp[reg] = 1.0e2; break; - case 0x35: regs.fp[reg] = 1.0e4; break; - case 0x36: regs.fp[reg] = 1.0e8; break; - case 0x37: regs.fp[reg] = 1.0e16; break; - case 0x38: regs.fp[reg] = 1.0e32; break; - case 0x39: regs.fp[reg] = 1.0e64; break; - case 0x3a: regs.fp[reg] = 1.0e128; break; - case 0x3b: regs.fp[reg] = 1.0e256; break; + if ((opcode & 0x38) == 0x18) + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) + m68k_areg (regs, opcode & 7) = ad; + } + } + return; + case 0: + case 2: + reg = (extra >> 7) & 7; + if ((extra & 0xfc00) == 0x5c00) { + switch (extra & 0x7f) { + case 0x00: + regs.fp[reg] = 4.0 * atan(1.0); + break; + case 0x0b: + regs.fp[reg] = log10 (2.0); + break; + case 0x0c: + regs.fp[reg] = exp (1.0); + break; + case 0x0d: + regs.fp[reg] = log (exp (1.0)) / log (2.0); + break; + case 0x0e: + regs.fp[reg] = log (exp (1.0)) / log (10.0); + break; + case 0x0f: + regs.fp[reg] = 0.0; + break; + case 0x30: + regs.fp[reg] = log (2.0); + break; + case 0x31: + regs.fp[reg] = log (10.0); + break; + case 0x32: + regs.fp[reg] = 1.0e0; + break; + case 0x33: + regs.fp[reg] = 1.0e1; + break; + case 0x34: + regs.fp[reg] = 1.0e2; + break; + case 0x35: + regs.fp[reg] = 1.0e4; + break; + case 0x36: + regs.fp[reg] = 1.0e8; + break; + case 0x37: + regs.fp[reg] = 1.0e16; + break; + case 0x38: + regs.fp[reg] = 1.0e32; + break; + case 0x39: + regs.fp[reg] = 1.0e64; + break; + case 0x3a: + regs.fp[reg] = 1.0e128; + break; + case 0x3b: + regs.fp[reg] = 1.0e256; + break; #if 0 - case 0x3c: regs.fp[reg] = 1.0e512; break; - case 0x3d: regs.fp[reg] = 1.0e1024; break; - case 0x3e: regs.fp[reg] = 1.0e2048; break; - case 0x3f: regs.fp[reg] = 1.0e4096; break; + case 0x3c: + regs.fp[reg] = 1.0e512; + break; + case 0x3d: + regs.fp[reg] = 1.0e1024; + break; + case 0x3e: + regs.fp[reg] = 1.0e2048; + break; + case 0x3f: + regs.fp[reg] = 1.0e4096; + break; #endif - default: - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - break; - } - return; - } - if (get_fp_value(opcode, extra, &src) == 0) { - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - return; - } - switch (extra & 0x7f) { - case 0x00: /* FMOVE */ - regs.fp[reg] = src; - break; - case 0x01: /* FINT */ - regs.fp[reg] = (int)(src + 0.5); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x02: /* FSINH */ - regs.fp[reg] = sinh(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x03: /* FINTRZ */ - regs.fp[reg] = (int)src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x04: /* FSQRT */ - regs.fp[reg] = sqrt(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x06: /* FLOGNP1 */ - regs.fp[reg] = log(src + 1.0); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x08: /* FETOXM1 */ - regs.fp[reg] = exp(src) - 1.0; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x09: /* FTANH */ - regs.fp[reg] = tanh(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x0a: /* FATAN */ - regs.fp[reg] = atan(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x0c: /* FASIN */ - regs.fp[reg] = asin(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x0d: /* FATANH */ -#if 1 /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */ - regs.fp[reg] = log((1+src)/(1-src))/2; + default: + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + return; + } + if (get_fp_value (opcode, extra, &src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + return; + } + switch (extra & 0x7f) { + case 0x00: /* FMOVE */ + regs.fp[reg] = src; + break; + case 0x01: /* FINT */ + regs.fp[reg] = (int) (src + 0.5); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x02: /* FSINH */ + regs.fp[reg] = sinh (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x03: /* FINTRZ */ + regs.fp[reg] = (int) src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x04: /* FSQRT */ + regs.fp[reg] = sqrt (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x06: /* FLOGNP1 */ + regs.fp[reg] = log (src + 1.0); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x08: /* FETOXM1 */ + regs.fp[reg] = exp (src) - 1.0; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x09: /* FTANH */ + regs.fp[reg] = tanh (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x0a: /* FATAN */ + regs.fp[reg] = atan (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x0c: /* FASIN */ + regs.fp[reg] = asin (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x0d: /* FATANH */ +#if 1 /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */ + regs.fp[reg] = log ((1 + src) / (1 - src)) / 2; #else - regs.fp[reg] = atanh(src); + regs.fp[reg] = atanh (src); #endif - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x0e: /* FSIN */ - regs.fp[reg] = sin(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x0f: /* FTAN */ - regs.fp[reg] = tan(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x10: /* FETOX */ - regs.fp[reg] = exp(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x11: /* FTWOTOX */ - regs.fp[reg] = pow(2.0,src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x12: /* FTENTOX */ - regs.fp[reg] = pow(10.0,src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x14: /* FLOGN */ - regs.fp[reg] = log(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x15: /* FLOG10 */ - regs.fp[reg] = log10(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x16: /* FLOG2 */ - regs.fp[reg] = log(src) / log(2.0); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x18: /* FABS */ - regs.fp[reg] = src < 0 ? -src : src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x19: /* FCOSH */ - regs.fp[reg] = cosh(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x1a: /* FNEG */ - regs.fp[reg] = -src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x1c: /* FACOS */ - regs.fp[reg] = acos(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x1d: /* FCOS */ - regs.fp[reg] = cos(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x1e: /* FGETEXP */ - { int expon; - frexp(src,&expon); - regs.fp[reg] = (double)(expon-1); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - } - break; - case 0x1f: /* FGETMAN */ - { int expon; - regs.fp[reg] = frexp(src,&expon) * 2.0; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - } - break; - case 0x20: /* FDIV */ - regs.fp[reg] /= src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x21: /* FMOD */ - regs.fp[reg] = regs.fp[reg] - - (double)((int)(regs.fp[reg] / src)) * src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x22: /* FADD */ - regs.fp[reg] += src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x23: /* FMUL */ - regs.fp[reg] *= src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x24: /* FSGLDIV */ - regs.fp[reg] /= src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x25: /* FREM */ - regs.fp[reg] = regs.fp[reg] - - (double)((int)(regs.fp[reg] / src + 0.5)) * src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x26: /* FSCALE */ - regs.fp[reg] *= exp(log(2.0)*src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x27: /* FSGLMUL */ - regs.fp[reg] *= src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x28: /* FSUB */ - regs.fp[reg] -= src; - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x30: /* FSINCOS */ - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - regs.fp[reg] = sin(src); - regs.fp[extra & 7] = cos(src); - regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | - (regs.fp[reg] < 0 ? 0x8000000 : 0); - break; - case 0x38: /* FCMP */ - { double tmp = regs.fp[reg] - src; - regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | - (tmp < 0 ? 0x8000000 : 0); - } - break; - case 0x3a: /* FTST */ - regs.fpsr = (src == 0 ? 0x4000000 : 0) | - (src < 0 ? 0x8000000 : 0); - break; - default: - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); - break; - } - return; - } - m68k_setpc(m68k_getpc()-2); - op_illg(opcode); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x0e: /* FSIN */ + regs.fp[reg] = sin (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x0f: /* FTAN */ + regs.fp[reg] = tan (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x10: /* FETOX */ + regs.fp[reg] = exp (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x11: /* FTWOTOX */ + regs.fp[reg] = pow(2.0, src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x12: /* FTENTOX */ + regs.fp[reg] = pow(10.0, src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x14: /* FLOGN */ + regs.fp[reg] = log (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x15: /* FLOG10 */ + regs.fp[reg] = log10 (src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x16: /* FLOG2 */ + regs.fp[reg] = log (src) / log (2.0); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x18: /* FABS */ + regs.fp[reg] = src < 0 ? -src : src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x19: /* FCOSH */ + regs.fp[reg] = cosh(src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x1a: /* FNEG */ + regs.fp[reg] = -src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x1c: /* FACOS */ + regs.fp[reg] = acos(src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x1d: /* FCOS */ + regs.fp[reg] = cos(src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x1e: /* FGETEXP */ + { + int expon; + frexp (src, &expon); + regs.fp[reg] = (double) (expon - 1); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + } + break; + case 0x1f: /* FGETMAN */ + { + int expon; + regs.fp[reg] = frexp (src, &expon) * 2.0; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + } + break; + case 0x20: /* FDIV */ + regs.fp[reg] /= src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x21: /* FMOD */ + regs.fp[reg] = regs.fp[reg] - + (double) ((int) (regs.fp[reg] / src)) * src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x22: /* FADD */ + regs.fp[reg] += src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x23: /* FMUL */ + regs.fp[reg] *= src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x24: /* FSGLDIV */ + regs.fp[reg] /= src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x25: /* FREM */ + regs.fp[reg] = regs.fp[reg] - + (double) ((int) (regs.fp[reg] / src + 0.5)) * src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x26: /* FSCALE */ + regs.fp[reg] *= exp (log (2.0) * src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x27: /* FSGLMUL */ + regs.fp[reg] *= src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x28: /* FSUB */ + regs.fp[reg] -= src; + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x30: /* FSINCOS */ + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + regs.fp[reg] = sin (src); + regs.fp[extra & 7] = cos(src); + regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) | + (regs.fp[reg] < 0 ? 0x8000000 : 0); + break; + case 0x38: /* FCMP */ + { + double tmp = regs.fp[reg] - src; + regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | + (tmp < 0 ? 0x8000000 : 0); + } + break; + case 0x3a: /* FTST */ + regs.fpsr = (src == 0 ? 0x4000000 : 0) | + (src < 0 ? 0x8000000 : 0); + break; + default: + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + return; + } + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); } #endif