Add dr prediction test
[aom.git] / test / register_state_check.h
blobef1f775e52479919d12b7e570ee661a664fa0791
1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
12 #ifndef TEST_REGISTER_STATE_CHECK_H_
13 #define TEST_REGISTER_STATE_CHECK_H_
15 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
17 #include "config/aom_config.h"
19 #include "aom/aom_integer.h"
21 // ASM_REGISTER_STATE_CHECK(asm_function)
22 // Minimally validates the environment pre & post function execution. This
23 // variant should be used with assembly functions which are not expected to
24 // fully restore the system state. See platform implementations of
25 // RegisterStateCheck for details.
27 // API_REGISTER_STATE_CHECK(api_function)
28 // Performs all the checks done by ASM_REGISTER_STATE_CHECK() and any
29 // additional checks to ensure the environment is in a consistent state pre &
30 // post function execution. This variant should be used with API functions.
31 // See platform implementations of RegisterStateCheckXXX for details.
34 #if defined(_WIN64) && ARCH_X86_64
36 #undef NOMINMAX
37 #define NOMINMAX
38 #define WIN32_LEAN_AND_MEAN
39 #include <windows.h>
40 #include <winnt.h>
42 inline bool operator==(const M128A &lhs, const M128A &rhs) {
43 return (lhs.Low == rhs.Low && lhs.High == rhs.High);
46 namespace libaom_test {
48 // Compares the state of xmm[6-15] at construction with their state at
49 // destruction. These registers should be preserved by the callee on
50 // Windows x64.
51 class RegisterStateCheck {
52 public:
53 RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
54 ~RegisterStateCheck() { Check(); }
56 private:
57 static bool StoreRegisters(CONTEXT *const context) {
58 const HANDLE this_thread = GetCurrentThread();
59 EXPECT_TRUE(this_thread != NULL);
60 context->ContextFlags = CONTEXT_FLOATING_POINT;
61 const bool context_saved = GetThreadContext(this_thread, context) == TRUE;
62 EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError();
63 return context_saved;
66 // Compares the register state. Returns true if the states match.
67 void Check() const {
68 ASSERT_TRUE(initialized_);
69 CONTEXT post_context;
70 ASSERT_TRUE(StoreRegisters(&post_context));
72 const M128A *xmm_pre = &pre_context_.Xmm6;
73 const M128A *xmm_post = &post_context.Xmm6;
74 for (int i = 6; i <= 15; ++i) {
75 EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!";
76 ++xmm_pre;
77 ++xmm_post;
81 bool initialized_;
82 CONTEXT pre_context_;
85 #define ASM_REGISTER_STATE_CHECK(statement) \
86 do { \
87 libaom_test::RegisterStateCheck reg_check; \
88 statement; \
89 } while (false)
91 } // namespace libaom_test
93 #else
95 namespace libaom_test {
97 class RegisterStateCheck {};
98 #define ASM_REGISTER_STATE_CHECK(statement) statement
100 } // namespace libaom_test
102 #endif // _WIN64 && ARCH_X86_64
104 #if ARCH_X86 || ARCH_X86_64
105 #if defined(__GNUC__)
107 namespace libaom_test {
109 // Checks the FPU tag word pre/post execution to ensure emms has been called.
110 class RegisterStateCheckMMX {
111 public:
112 RegisterStateCheckMMX() {
113 __asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
115 ~RegisterStateCheckMMX() { Check(); }
117 private:
118 // Checks the FPU tag word pre/post execution, returning false if not cleared
119 // to 0xffff.
120 void Check() const {
121 EXPECT_EQ(0xffff, pre_fpu_env_[4])
122 << "FPU was in an inconsistent state prior to call";
124 uint16_t post_fpu_env[14];
125 __asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
126 EXPECT_EQ(0xffff, post_fpu_env[4])
127 << "FPU was left in an inconsistent state after call";
130 uint16_t pre_fpu_env_[14];
133 #define API_REGISTER_STATE_CHECK(statement) \
134 do { \
135 libaom_test::RegisterStateCheckMMX reg_check; \
136 ASM_REGISTER_STATE_CHECK(statement); \
137 } while (false)
139 } // namespace libaom_test
141 #endif // __GNUC__
142 #endif // ARCH_X86 || ARCH_X86_64
144 #ifndef API_REGISTER_STATE_CHECK
145 #define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
146 #endif
148 #endif // TEST_REGISTER_STATE_CHECK_H_