From e90f9974bab1f97a9c79f25e0172890e99e1a579 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Thu, 2 Mar 2023 22:50:47 -0500 Subject: [PATCH] Implement rounding mode for cvt.w.fmt instructions --- include/recomp.h | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/include/recomp.h b/include/recomp.h index e331a81..5768cb2 100644 --- a/include/recomp.h +++ b/include/recomp.h @@ -137,12 +137,43 @@ static inline gpr do_lwl(uint8_t* rdram, gpr offset, gpr reg) { #define TRUNC_L_D(val) \ ((int64_t)(val)) -// TODO rounding mode +#define DEFAULT_ROUNDING_MODE 0 + +static inline int32_t do_cvt_w_s(float val, unsigned int rounding_mode) { + switch (rounding_mode) { + case 0: // round to nearest value + return (int32_t)lroundf(val); + case 1: // round to zero (truncate) + return (int32_t)val; + case 2: // round to positive infinity (ceil) + return (int32_t)ceilf(val); + case 3: // round to negative infinity (floor) + return (int32_t)floorf(val); + } + assert(0); + return 0; +} + #define CVT_W_S(val) \ - ((int32_t)(val)) + do_cvt_w_s(val, rounding_mode) + +static inline int32_t do_cvt_w_d(double val, unsigned int rounding_mode) { + switch (rounding_mode) { + case 0: // round to nearest value + return (int32_t)lround(val); + case 1: // round to zero (truncate) + return (int32_t)val; + case 2: // round to positive infinity (ceil) + return (int32_t)ceil(val); + case 3: // round to negative infinity (floor) + return (int32_t)floor(val); + } + assert(0); + return 0; +} #define CVT_W_D(val) \ - ((int32_t)(val)) + do_cvt_w_d(val, rounding_mode) #define NAN_CHECK(val) \ assert(val == val)