Index: source/libvpx/test/register_state_check.h |
=================================================================== |
--- source/libvpx/test/register_state_check.h (revision 282873) |
+++ source/libvpx/test/register_state_check.h (working copy) |
@@ -13,7 +13,21 @@ |
#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) |
#define _WIN32_LEAN_AND_MEAN |
@@ -35,11 +49,6 @@ |
// 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 @@ |
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 @@ |
#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 @@ |
// 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 @@ |
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 @@ |
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_ |