Skip to content

Commit

Permalink
Softfloat FPU updates. New undocumented features emulated.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonioni committed Jul 23, 2018
1 parent 6657aa4 commit f29b784
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 155 deletions.
32 changes: 7 additions & 25 deletions fpp.cpp
Expand Up @@ -431,9 +431,10 @@ static void fpsr_check_arithmetic_exception(uae_u32 mask, fpdata *src, uae_u32 o
uae_u32 exception;
// Any exception status bit and matching exception enable bits set?
exception = regs.fpsr & regs.fpcr & 0xff00;
// Add 68040/68060 nonmaskable exceptions
if (currprefs.cpu_model >= 68040 && currprefs.fpu_model)
// Add 68040/68060 nonmaskable exceptions. Only if no unimplemented instruction emulation.
if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) {
exception |= regs.fpsr & (FPSR_OVFL | FPSR_UNFL | mask);
}

if (exception) {
regs.fp_exp_pend = fpsr_get_vector(exception);
Expand Down Expand Up @@ -614,7 +615,7 @@ static uae_u32 fpsr_make_status(void)

// return exceptions that interrupt calculation
exception = regs.fpsr & regs.fpcr & (FPSR_SNAN | FPSR_OPERR | FPSR_DZ);
if (currprefs.cpu_model >= 68040 && currprefs.fpu_model)
if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented)
exception |= regs.fpsr & (FPSR_OVFL | FPSR_UNFL);

return exception;
Expand Down Expand Up @@ -1000,7 +1001,7 @@ static void fp_unimp_datatype(uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaecptr
}
if (warned > 0) {
write_log (_T("FPU unimplemented datatype (%s): OP=%04X-%04X SRC=%08X-%08X-%08X EA=%08X PC=%08X\n"),
packed ? "packed" : "denormal", opcode, extra,
packed ? _T("packed") : _T("denormal"), opcode, extra,
packed ? fsave_data.fpt[2] : fsave_data.et[0], fsave_data.et[1], fsave_data.et[2], ea, oldpc);
#if EXCEPTION_FPP == 0
warned--;
Expand Down Expand Up @@ -1306,18 +1307,6 @@ static bool fault_if_68040_integer_nonmaskable(uae_u16 opcode, uae_u16 extra, ua
return false;
}

#if 0
// 68040/060 automatically converts infinity
static void check_and_fix_infinity(fpdata *value)
{
if (fpp_fix_infinity && (currprefs.fpu_model == 68040 || currprefs.fpu_model == 68060)) {
if (fpp_is_infinity(value)) {
fpp_fix_infinity(value);
}
}
}
#endif

static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr oldpc, uae_u32 *adp)
{
int size, mode, reg;
Expand All @@ -1331,9 +1320,6 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
if (fault_if_no_fpu (opcode, extra, 0, oldpc))
return -1;
*src = regs.fp[(extra >> 10) & 7];
#if 0
check_and_fix_infinity(src);
#endif
normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, src);
return 1;
}
Expand Down Expand Up @@ -3112,10 +3098,6 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)

v = fp_arithmetic(&src, &dst, extra);

#if 0
check_and_fix_infinity(&dst);
#endif

fpsr_check_arithmetic_exception(0, &src, opcode, extra, ad);

if (v)
Expand Down Expand Up @@ -3163,7 +3145,7 @@ void fpu_modechange(void)
fpp_from_exten_fmovem(&regs.fp[i], &temp_ext[i][0], &temp_ext[i][1], &temp_ext[i][2]);
}
if (currprefs.fpu_mode > 0) {
fp_init_softfloat();
fp_init_softfloat(currprefs.fpu_model);
#ifdef MSVC_LONG_DOUBLE
use_long_double = false;
} else if (currprefs.fpu_mode < 0) {
Expand Down Expand Up @@ -3201,7 +3183,7 @@ static void fpu_test(void)
void fpu_reset (void)
{
if (currprefs.fpu_mode > 0) {
fp_init_softfloat();
fp_init_softfloat(currprefs.fpu_model);
#ifdef MSVC_LONG_DOUBLE
use_long_double = false;
} else if (currprefs.fpu_mode < 0) {
Expand Down
16 changes: 8 additions & 8 deletions fpp_softfloat.cpp
Expand Up @@ -733,15 +733,15 @@ static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor)
}
}

void fp_init_softfloat(void)
void fp_init_softfloat(int fpu_model)
{
float_status fsx = { 0 };

fsx.fpu_model = currprefs.fpu_model;
fs.fpu_model = currprefs.fpu_model;

set_floatx80_rounding_precision(80, &fsx);
set_float_rounding_mode(float_round_to_zero, &fsx);
if (fpu_model == 68040) {
set_special_flags(cmp_signed_nan, &fs);
} else if (fpu_model == 68060) {
set_special_flags(infinity_clear_intbit, &fs);
} else {
set_special_flags(addsub_swap_inf, &fs);
}

fpp_print = fp_print;
fpp_unset_snan = fp_unset_snan;
Expand Down
2 changes: 1 addition & 1 deletion include/fpp.h
Expand Up @@ -20,7 +20,7 @@ extern void fp_init_native(void);
#ifdef MSVC_LONG_DOUBLE
extern void fp_init_native_80(void);
#endif
extern void fp_init_softfloat(void);
extern void fp_init_softfloat(int);
extern void fpsr_set_exception(uae_u32 exception);
extern void fpu_modechange(void);
extern void fpu_clearstatus(void);
Expand Down

0 comments on commit f29b784

Please sign in to comment.