Skip to content

Commit

Permalink
feat: Implement _MM_GET_ROUNDING_MODE
Browse files Browse the repository at this point in the history
  • Loading branch information
marktwtn committed May 5, 2021
1 parent d55a36a commit 73b8e95
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
29 changes: 29 additions & 0 deletions sse2neon.h
Expand Up @@ -6238,6 +6238,7 @@ FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask)
#endif
}

// The bit field mapping to the FPCR(floating-point control register)
typedef struct {
uint16_t res0;
uint8_t res1 : 6;
Expand All @@ -6249,6 +6250,34 @@ typedef struct {
#endif
} fpcr_bitfield;

// Macro: Get the rounding mode bits from the MXCSR control and status register.
// The rounding mode may contain any of the following flags: _MM_ROUND_NEAREST,
// _MM_ROUND_DOWN, _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_ROUNDING_MODE
FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE()
{
union {
fpcr_bitfield field;
#if defined(__aarch64__)
uint64_t value;
#else
uint32_t value;
#endif
} r;

#if defined(__aarch64__)
asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */
#else
asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */
#endif

if (r.field.bit22) {
return r.field.bit23 ? _MM_ROUND_TOWARD_ZERO : _MM_ROUND_UP;
} else {
return r.field.bit23 ? _MM_ROUND_DOWN : _MM_ROUND_NEAREST;
}
}

// Macro: Set the rounding mode bits of the MXCSR control and status register to
// the value in unsigned 32-bit integer a. The rounding mode may contain any of
// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP,
Expand Down
19 changes: 19 additions & 0 deletions tests/impl.cpp
Expand Up @@ -1688,6 +1688,25 @@ result_t test_mm_free(const SSE2NEONTestImpl &impl, uint32_t i)
return TEST_UNIMPL;
}

result_t test_mm_get_rounding_mode(const SSE2NEONTestImpl &impl, uint32_t i)
{
int res_toward_zero, res_to_neg_inf, res_to_pos_inf, res_nearest;
_MM_SET_ROUNDING_MODE(_MM_ROUND_TOWARD_ZERO);
res_toward_zero = _MM_GET_ROUNDING_MODE() == _MM_ROUND_TOWARD_ZERO ? 1 : 0;
_MM_SET_ROUNDING_MODE(_MM_ROUND_DOWN);
res_to_neg_inf = _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN ? 1 : 0;
_MM_SET_ROUNDING_MODE(_MM_ROUND_UP);
res_to_pos_inf = _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP ? 1 : 0;
_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
res_nearest = _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST ? 1 : 0;

if (res_toward_zero && res_to_neg_inf && res_to_pos_inf && res_nearest) {
return TEST_SUCCESS;
} else {
return TEST_FAIL;
}
}

result_t test_mm_getcsr(const SSE2NEONTestImpl &impl, uint32_t i)
{
return TEST_UNIMPL;
Expand Down
1 change: 1 addition & 0 deletions tests/impl.h
Expand Up @@ -72,6 +72,7 @@
TYPE(mm_div_ss) \
TYPE(mm_extract_pi16) \
TYPE(mm_free) \
TYPE(mm_get_rounding_mode) \
TYPE(mm_getcsr) \
TYPE(mm_insert_pi16) \
TYPE(mm_load_ps) \
Expand Down

0 comments on commit 73b8e95

Please sign in to comment.