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 23namespace testing { 24namespace internal { 25 26inline 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 33namespace 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// } 43class 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 90extern "C" { 91// Save the d8-d15 registers into store. 92void vp9_push_neon(int64_t *store); 93} 94 95namespace 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// } 105class 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 141namespace libvpx_test { 142 143class 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