summaryrefslogtreecommitdiff
path: root/test/register_state_check.h
diff options
context:
space:
mode:
Diffstat (limited to 'test/register_state_check.h')
-rw-r--r--test/register_state_check.h84
1 files changed, 65 insertions, 19 deletions
diff --git a/test/register_state_check.h b/test/register_state_check.h
index 1ee149b0c..8d4beea5f 100644
--- a/test/register_state_check.h
+++ b/test/register_state_check.h
@@ -13,6 +13,20 @@
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
+#include "vpx/vpx_integer.h"
+
+// ASM_REGISTER_STATE_CHECK(asm_function)
+// Minimally validates the environment pre & post function execution. This
+// variant should be used with assembly functions which are not expected to
+// fully restore the system state. See platform implementations of
+// RegisterStateCheck for details.
+//
+// API_REGISTER_STATE_CHECK(api_function)
+// Performs all the checks done by ASM_REGISTER_STATE_CHECK() and any
+// additional checks to ensure the environment is in a consistent state pre &
+// post function execution. This variant should be used with API functions.
+// See platform implementations of RegisterStateCheckXXX for details.
+//
#if defined(_WIN64)
@@ -35,11 +49,6 @@ namespace libvpx_test {
// Compares the state of xmm[6-15] at construction with their state at
// destruction. These registers should be preserved by the callee on
// Windows x64.
-// Usage:
-// {
-// RegisterStateCheck reg_check;
-// FunctionToVerify();
-// }
class RegisterStateCheck {
public:
RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
@@ -75,9 +84,9 @@ class RegisterStateCheck {
CONTEXT pre_context_;
};
-#define REGISTER_STATE_CHECK(statement) do { \
- libvpx_test::RegisterStateCheck reg_check; \
- statement; \
+#define ASM_REGISTER_STATE_CHECK(statement) do { \
+ libvpx_test::RegisterStateCheck reg_check; \
+ statement; \
} while (false)
} // namespace libvpx_test
@@ -85,8 +94,6 @@ class RegisterStateCheck {
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \
&& !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
-#include "vpx/vpx_integer.h"
-
extern "C" {
// Save the d8-d15 registers into store.
void vp9_push_neon(int64_t *store);
@@ -97,11 +104,6 @@ namespace libvpx_test {
// Compares the state of d8-d15 at construction with their state at
// destruction. These registers should be preserved by the callee on
// arm platform.
-// Usage:
-// {
-// RegisterStateCheck reg_check;
-// FunctionToVerify();
-// }
class RegisterStateCheck {
public:
RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); }
@@ -129,9 +131,9 @@ class RegisterStateCheck {
int64_t pre_store_[8];
};
-#define REGISTER_STATE_CHECK(statement) do { \
- libvpx_test::RegisterStateCheck reg_check; \
- statement; \
+#define ASM_REGISTER_STATE_CHECK(statement) do { \
+ libvpx_test::RegisterStateCheck reg_check; \
+ statement; \
} while (false)
} // namespace libvpx_test
@@ -141,10 +143,54 @@ class RegisterStateCheck {
namespace libvpx_test {
class RegisterStateCheck {};
-#define REGISTER_STATE_CHECK(statement) statement
+#define ASM_REGISTER_STATE_CHECK(statement) statement
} // namespace libvpx_test
#endif // _WIN64
+#if ARCH_X86 || ARCH_X86_64
+#if defined(__GNUC__)
+
+namespace libvpx_test {
+
+// Checks the FPU tag word pre/post execution to ensure emms has been called.
+class RegisterStateCheckMMX {
+ public:
+ RegisterStateCheckMMX() {
+ __asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
+ }
+ ~RegisterStateCheckMMX() { EXPECT_TRUE(Check()); }
+
+ private:
+ // Checks the FPU tag word pre/post execution, returning false if not cleared
+ // to 0xffff.
+ bool Check() const {
+ EXPECT_EQ(0xffff, pre_fpu_env_[4])
+ << "FPU was in an inconsistent state prior to call";
+
+ uint16_t post_fpu_env[14];
+ __asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
+ EXPECT_EQ(0xffff, post_fpu_env[4])
+ << "FPU was left in an inconsistent state after call";
+ return !testing::Test::HasNonfatalFailure();
+ }
+
+ uint16_t pre_fpu_env_[14];
+};
+
+#define API_REGISTER_STATE_CHECK(statement) do { \
+ libvpx_test::RegisterStateCheckMMX reg_check; \
+ ASM_REGISTER_STATE_CHECK(statement); \
+} while (false)
+
+} // namespace libvpx_test
+
+#endif // __GNUC__
+#endif // ARCH_X86 || ARCH_X86_64
+
+#ifndef API_REGISTER_STATE_CHECK
+#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
+#endif
+
#endif // TEST_REGISTER_STATE_CHECK_H_