diff --git a/src/rp2040/pico_platform/include/pico/platform.h b/src/rp2040/pico_platform/include/pico/platform.h index 437ff31f4..8f746713d 100644 --- a/src/rp2040/pico_platform/include/pico/platform.h +++ b/src/rp2040/pico_platform/include/pico/platform.h @@ -183,9 +183,7 @@ return a; * \param b the second operand * \return a * b */ -#define __fast_mul(a, b) __builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \ - (__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \ - (a)*(b)) +#define __fast_mul(a, b) (__builtin_constant_p(b) && !__builtin_constant_p(a) && __builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)) #ifdef __cplusplus } diff --git a/src/rp2350/pico_platform/include/pico/platform.h b/src/rp2350/pico_platform/include/pico/platform.h index 571efd8b8..67cb80ebc 100644 --- a/src/rp2350/pico_platform/include/pico/platform.h +++ b/src/rp2350/pico_platform/include/pico/platform.h @@ -244,9 +244,7 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { * \param b the second operand * \return a * b */ -#define __fast_mul(a, b) __builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \ - (__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \ - (a)*(b)) +#define __fast_mul(a, b) (__builtin_constant_p(b) && !__builtin_constant_p(a) && __builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)) #ifdef __cplusplus } diff --git a/src/rp2_common/pico_float/include/pico/float.h b/src/rp2_common/pico_float/include/pico/float.h index 958a14ad0..bf2ece7a8 100644 --- a/src/rp2_common/pico_float/include/pico/float.h +++ b/src/rp2_common/pico_float/include/pico/float.h @@ -357,8 +357,8 @@ uint64_t float2ufix64(float f, int e); // or call the original function #if PICO_FLOAT_HAS_FIX32_TO_FLOAT_CONVERSIONS // a bit of a hack to inline VFP fixed-point conversion when exponent is constant and in range 1-32 -#define fix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _fix2float_inline(m, e) : fix2 ## float(m, e), fix2 ## float(m, e)) -#define ufix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _ufix2float_inline(m, e) : ufix2 ## float(m, e), ufix2 ## float(m, e)) +#define fix2float(m, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _fix2float_inline(m, e) : fix2 ## float(m, e)) +#define ufix2float(m, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _ufix2float_inline(m, e) : ufix2 ## float(m, e)) #define _fix2float_inline(m, e) ({ \ int32_t _m = m; \ @@ -385,8 +385,8 @@ uint64_t float2ufix64(float f, int e); #endif #if PICO_FLOAT_HAS_FLOAT_TO_FIX32_Z_CONVERSIONS -#define float2fix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_z_inline(f, e) : float2 ## fix_z(f, e), float2 ## fix_z(f, e)) -#define float2ufix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_z_inline(f, e) : float2 ## ufix_z(f, e), float2 ## ufix_z(f, e)) +#define float2fix_z(f, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _float2fix_z_inline(f, e) : float2 ## fix_z(f, e)) +#define float2ufix_z(f, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _float2ufix_z_inline(f, e) : float2 ## ufix_z(f, e)) #define _float2fix_z_inline(f, e) ({ \ int32_t _m; \ @@ -413,8 +413,8 @@ uint64_t float2ufix64(float f, int e); #endif #if PICO_FLOAT_HAS_FLOAT_TO_FIX32_M_CONVERSIONS -#define float2fix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_inline(f, e) : float2 ## fix(f, e), float2 ## fix(f, e)) -#define float2ufix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_inline(f, e) : float2 ## ufix(f, e), float2 ## ufix(f, e)) +#define float2fix(f, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _float2fix_inline(f, e) : float2 ## fix(f, e)) +#define float2ufix(f, e) (__builtin_constant_p(e) && (e) >= 1 && (e) <= 32 ? _float2ufix_inline(f, e) : float2 ## ufix(f, e)) #define _float2fix_inline(f, e) ({ \ union { float _f; int32_t _i; } _u; \ diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index 81b9fee30..1faf7fe38 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -63,6 +63,42 @@ float __attribute__((noinline)) foox(float x, float b) { return x * b; } +uint __noinline const_funcs_returning_int(__unused float x, int n) { + return __fast_mul(n, 7) +#if PICO_FLOAT_HAS_FLOAT_TO_FIX32_M_CONVERSIONS + + float2fix(x, 7) + + float2ufix(x, 7) +#endif +#if PICO_FLOAT_HAS_FLOAT_TO_FIX32_Z_CONVERSIONS + + float2fix_z(x, 7) + + float2ufix_z(x, 7) +#endif + ; +} + +uint __noinline non_const_funcs_returning_int(__unused float x, int n) { + return __fast_mul(n, n) +#if PICO_FLOAT_HAS_FLOAT_TO_FIX32_M_CONVERSIONS + + float2fix(x, n) + + float2ufix(x, n) +#endif +#if PICO_FLOAT_HAS_FLOAT_TO_FIX32_Z_CONVERSIONS + + float2fix_z(x, n) + + float2ufix_z(x, n) +#endif + ; +} + +#if PICO_FLOAT_HAS_FIX32_TO_FLOAT_CONVERSIONS +float __noinline const_funcs_returning_float(int n) { + return fix2float(n, 7) + ufix2float(n, 7); +} + +float __noinline non_const_funcs_returning_float(int n) { + return fix2float(n, n) + ufix2float(n, n); +} +#endif + void svc_call(void) { puts("PASSED"); exit(0); @@ -93,6 +129,10 @@ int main(void) { hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); printf("%f\n", foox(1.3f, 2.6f)); + printf("%u %u\n", const_funcs_returning_int(3.7f, 7), non_const_funcs_returning_int(3.7f, 7)); +#if PICO_FLOAT_HAS_FIX32_TO_FLOAT_CONVERSIONS + printf("%f %f\n", const_funcs_returning_float(7), non_const_funcs_returning_float(7)); +#endif #ifdef EXTRA_DATA_SECTION extern uint32_t __extra_end_variable__; printf("__extra_end_variable__ = %p\n", (void *)&__extra_end_variable__);