From: quzar <qu...@us...> - 2024-05-16 16:50:19
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 5ff6cd01cd9d1d47472e45c0f29d955bfe864eec (commit) from c3ce8d43582762f5224631319e7350168d88f416 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5ff6cd01cd9d1d47472e45c0f29d955bfe864eec Author: Falco Girgis <gyr...@gm...> Date: Thu May 16 11:46:36 2024 -0500 Updated the FPU exception example. (#572) - There's no need for inline assembly anymore, thanks to the compiler intrinsic for fpscr implemented by Oleg endo. - Show off how to reproduce even more different exception types. - Tested for both -m4-single-only and -m4-single ----------------------------------------------------------------------- Summary of changes: examples/dreamcast/basic/fpu/exc/fpu_exc.c | 138 +++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 19 deletions(-) diff --git a/examples/dreamcast/basic/fpu/exc/fpu_exc.c b/examples/dreamcast/basic/fpu/exc/fpu_exc.c index 5cc5256f..718d5e0d 100644 --- a/examples/dreamcast/basic/fpu/exc/fpu_exc.c +++ b/examples/dreamcast/basic/fpu/exc/fpu_exc.c @@ -1,39 +1,139 @@ /* KallistiOS ##version## fpu_exc.c - (c)2002 Megan Potter + Copyright (C) 2002 Megan Potter + Copyright (C) 2024 Falco Girgis +*/ + +/* + This file serves as both an example of and an automatable test case for + working with the SH4's FPU state and exceptions. */ #include <kos.h> +#include <stdio.h> +#include <stdlib.h> +#include <float.h> -asm( - " .text\n" - " .align 2\n" - "__get_fpscr:\n" - " rts\n" - " sts fpscr,r0\n" -); +#ifdef __SH4_SINGLE_ONLY__ +# define SH4_FPU_CONFIG_NAME "-m4-single-only" +#elif defined(__SH4_SINGLE__) +# define SH4_FPU_CONFIG_NAME "-m4-single" +#else +# define SH4_FPU_CONFIG_NAME "unknown" +#endif -extern uint32 _get_fpscr(); +static const char* +fpscr_stringify(unsigned int value, char* buffer, size_t bytes) { -int main(int argc, char **argv) { - uint32 fpscr; - double d = 1.0; + snprintf(buffer, bytes, + "\tFPSCR [%x]:\n" + "\t\tFR = %d\n" + "\t\tSZ = %d\n" + "\t\tPR = %d\n" + "\t\tDN = %d\n" + "\t\tCause = %x\n" + "\t\tEnable = %x\n" + "\t\tFlag = %x\n" + "\t\tRM = %x\n", + value, + !!(value & (1 << 21)), + !!(value & (1 << 20)), + !!(value & (1 << 19)), + !!(value & (1 << 18)), + (value >> 12) & 0x3f, + (value >> 7) & 0x3f, + (value >> 2) & 0x3f, + value & 0x3); - /* Exit parachute */ - cont_btn_callback(0, CONT_START, (cont_btn_callback_t)arch_exit); + return buffer; +} + +static bool fpscr_test(const char *name, unsigned mask, void (*test)(void)) { + char buffer[512]; + bool success = true; + + const unsigned begin_fpscr = __builtin_sh_get_fpscr(); + + printf("Beginning %s test!\n", name); - fpscr = _get_fpscr(); - printf("fpscr is %08x\n", (unsigned int)fpscr); + test(); + unsigned fpscr = __builtin_sh_get_fpscr(); + printf("%s", fpscr_stringify(fpscr, buffer, sizeof(buffer))); + + if(!(fpscr & mask)) { + fprintf(stderr, "\tFAILURE: %s flag not asserted!\n", name); + success = false; + } + else { + printf("\tSUCCESS!\n"); + } + + __builtin_sh_set_fpscr(begin_fpscr); + + return success; +} + +static void fpscr_underflow(void) { + volatile double d = 1.0; while(d > 0.0) { - printf("%f\n", d); +// printf("\t%.15lf\n", d); d *= 0.01; } +} + +static void fpscr_overflow(void) { + volatile double d = 1.0; + while(d < DBL_MAX) { +// printf("\t%.15lf\n", d); + d *= 1.1; + } +} + +static void fpscr_nan(void) { + volatile double d = 0.0; + volatile double c = 0.0; + volatile double e = d / c; + (void)e; +} + +static void fpscr_div_zero(void) { + volatile double d = 1.0; + volatile double c = 0.0; + volatile double e = d / c; + (void)e; +} + +int main(int argc, char **argv) { + char buffer[512]; + bool success = true; - printf("Underflow occurred, no exceptions!\n"); + /* Exit parachute */ + cont_btn_callback(0, CONT_START, (cont_btn_callback_t)arch_exit); + + printf("Beginning the FPU exception test!\n"); + printf("\tFPU Config: %s\n", SH4_FPU_CONFIG_NAME); + printf("\tsizeof(float): %zu\n", sizeof(float)); + printf("\tsizeof(double): %zu\n", sizeof(double)); + + unsigned fpscr_start = __builtin_sh_get_fpscr(); + printf("Original Value:\n%s", fpscr_stringify(fpscr_start, buffer, sizeof(buffer))); + + success &= fpscr_test("underflow", (1 << 3), fpscr_underflow); + success &= fpscr_test("overflow", (1 << 4), fpscr_overflow); + success &= fpscr_test("divde-by-zero", (1 << 5), fpscr_div_zero); + success &= fpscr_test("NAN", (1 << 6), fpscr_nan); + + if(success) { + printf("\nTEST SUCCEEDED!\n"); + return EXIT_SUCCESS; + } + else { + fprintf(stderr, "\nTEST FAILED!\n"); + return EXIT_FAILURE; + } - return 0; } hooks/post-receive -- A pseudo Operating System for the Dreamcast. |