1 /* 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef TEST_REGISTER_STATE_CHECK_H_ 12 #define TEST_REGISTER_STATE_CHECK_H_ 13 14 #include "third_party/googletest/src/include/gtest/gtest.h" 15 #include "./vpx_config.h" 16 17 #if defined(_WIN64) 18 19 #define _WIN32_LEAN_AND_MEAN 20 #include <windows.h> 21 #include <winnt.h> 22 23 namespace testing { 24 namespace internal { 25 26 inline bool operator==(const M128A& lhs, const M128A& rhs) { 27 return (lhs.Low == rhs.Low && lhs.High == rhs.High); 28 } 29 30 } // namespace internal 31 } // namespace testing 32 33 namespace libvpx_test { 34 35 // Compares the state of xmm[6-15] at construction with their state at 36 // destruction. These registers should be preserved by the callee on 37 // Windows x64. 38 // Usage: 39 // { 40 // RegisterStateCheck reg_check; 41 // FunctionToVerify(); 42 // } 43 class RegisterStateCheck { 44 public: 45 RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); } 46 ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 47 48 private: 49 static bool StoreRegisters(CONTEXT* const context) { 50 const HANDLE this_thread = GetCurrentThread(); 51 EXPECT_TRUE(this_thread != NULL); 52 context->ContextFlags = CONTEXT_FLOATING_POINT; 53 const bool context_saved = GetThreadContext(this_thread, context) == TRUE; 54 EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError(); 55 return context_saved; 56 } 57 58 // Compares the register state. Returns true if the states match. 59 bool Check() const { 60 if (!initialized_) return false; 61 CONTEXT post_context; 62 if (!StoreRegisters(&post_context)) return false; 63 64 const M128A* xmm_pre = &pre_context_.Xmm6; 65 const M128A* xmm_post = &post_context.Xmm6; 66 for (int i = 6; i <= 15; ++i) { 67 EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!"; 68 ++xmm_pre; 69 ++xmm_post; 70 } 71 return !testing::Test::HasNonfatalFailure(); 72 } 73 74 bool initialized_; 75 CONTEXT pre_context_; 76 }; 77 78 #define REGISTER_STATE_CHECK(statement) do { \ 79 libvpx_test::RegisterStateCheck reg_check; \ 80 statement; \ 81 } while (false) 82 83 } // namespace libvpx_test 84 85 #elif defined(CONFIG_SHARED) && defined(HAVE_NEON) \ 86 && !CONFIG_SHARED && HAVE_NEON 87 88 #include "vpx/vpx_integer.h" 89 90 extern "C" { 91 // Save the d8-d15 registers into store. 92 void vp9_push_neon(int64_t *store); 93 } 94 95 namespace libvpx_test { 96 97 // Compares the state of d8-d15 at construction with their state at 98 // destruction. These registers should be preserved by the callee on 99 // arm platform. 100 // Usage: 101 // { 102 // RegisterStateCheck reg_check; 103 // FunctionToVerify(); 104 // } 105 class RegisterStateCheck { 106 public: 107 RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); } 108 ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 109 110 private: 111 static bool StoreRegisters(int64_t store[8]) { 112 vp9_push_neon(store); 113 return true; 114 } 115 116 // Compares the register state. Returns true if the states match. 117 bool Check() const { 118 if (!initialized_) return false; 119 int64_t post_store[8]; 120 vp9_push_neon(post_store); 121 for (int i = 0; i < 8; ++i) { 122 EXPECT_EQ(pre_store_[i], post_store[i]) << "d" 123 << i + 8 << " has been modified"; 124 } 125 return !testing::Test::HasNonfatalFailure(); 126 } 127 128 bool initialized_; 129 int64_t pre_store_[8]; 130 }; 131 132 #define REGISTER_STATE_CHECK(statement) do { \ 133 libvpx_test::RegisterStateCheck reg_check; \ 134 statement; \ 135 } while (false) 136 137 } // namespace libvpx_test 138 139 #else 140 141 namespace libvpx_test { 142 143 class RegisterStateCheck {}; 144 #define REGISTER_STATE_CHECK(statement) statement 145 146 } // namespace libvpx_test 147 148 #endif // _WIN64 149 150 #endif // TEST_REGISTER_STATE_CHECK_H_ 151