1d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org/* 2d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * 4d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * Use of this source code is governed by a BSD-style license 5d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * that can be found in the LICENSE file in the root of the source 6d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * tree. An additional intellectual property rights grant can be found 7d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * in the file PATENTS. All contributing project authors may 8d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * be found in the AUTHORS file in the root of the source tree. 9d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org */ 10d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 11f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#ifndef TEST_REGISTER_STATE_CHECK_H_ 12f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#define TEST_REGISTER_STATE_CHECK_H_ 13d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "third_party/googletest/src/include/gtest/gtest.h" 1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "./vpx_config.h" 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if defined(_WIN64) 18d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 19d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#define _WIN32_LEAN_AND_MEAN 20d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include <windows.h> 21d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include <winnt.h> 22d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 23d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgnamespace testing { 24d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgnamespace internal { 25d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 26d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orginline bool operator==(const M128A& lhs, const M128A& rhs) { 27d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org return (lhs.Low == rhs.Low && lhs.High == rhs.High); 28d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 29d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 30d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} // namespace internal 31d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} // namespace testing 32d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 33d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgnamespace libvpx_test { 34d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 35d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// Compares the state of xmm[6-15] at construction with their state at 36d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// destruction. These registers should be preserved by the callee on 37d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// Windows x64. 38d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// Usage: 39d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// { 40d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// RegisterStateCheck reg_check; 41d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// FunctionToVerify(); 42d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org// } 43d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgclass RegisterStateCheck { 44d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org public: 45d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); } 46d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 47d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 48d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org private: 49d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org static bool StoreRegisters(CONTEXT* const context) { 50d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const HANDLE this_thread = GetCurrentThread(); 51d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org EXPECT_TRUE(this_thread != NULL); 52d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org context->ContextFlags = CONTEXT_FLOATING_POINT; 53d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const bool context_saved = GetThreadContext(this_thread, context) == TRUE; 54d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError(); 55d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org return context_saved; 56d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 57d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 58d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org // Compares the register state. Returns true if the states match. 59d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org bool Check() const { 60d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org if (!initialized_) return false; 61d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org CONTEXT post_context; 62d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org if (!StoreRegisters(&post_context)) return false; 63d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 64d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const M128A* xmm_pre = &pre_context_.Xmm6; 65d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const M128A* xmm_post = &post_context.Xmm6; 66d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int i = 6; i <= 15; ++i) { 67d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!"; 68d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org ++xmm_pre; 69d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org ++xmm_post; 70d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 71d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org return !testing::Test::HasNonfatalFailure(); 72d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 73d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 74d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org bool initialized_; 75d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org CONTEXT pre_context_; 76d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org}; 77d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 78d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#define REGISTER_STATE_CHECK(statement) do { \ 79d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org libvpx_test::RegisterStateCheck reg_check; \ 80d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org statement; \ 81d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} while (false) 82d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 83d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} // namespace libvpx_test 84d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 857765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \ 867765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9 8793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "vpx/vpx_integer.h" 8993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 9093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgextern "C" { 9193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Save the d8-d15 registers into store. 9293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_push_neon(int64_t *store); 9393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 9493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 9593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgnamespace libvpx_test { 9693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 9793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Compares the state of d8-d15 at construction with their state at 9893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// destruction. These registers should be preserved by the callee on 9993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// arm platform. 10093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Usage: 10193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// { 10293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// RegisterStateCheck reg_check; 10393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// FunctionToVerify(); 10493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// } 10593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgclass RegisterStateCheck { 10693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org public: 10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); } 10893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 10993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 11093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org private: 11193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org static bool StoreRegisters(int64_t store[8]) { 11293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org vp9_push_neon(store); 11393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return true; 11493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 11593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 11693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Compares the register state. Returns true if the states match. 11793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org bool Check() const { 11893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!initialized_) return false; 11993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int64_t post_store[8]; 12093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org vp9_push_neon(post_store); 12193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (int i = 0; i < 8; ++i) { 12293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EXPECT_EQ(pre_store_[i], post_store[i]) << "d" 12393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org << i + 8 << " has been modified"; 12493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 12593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return !testing::Test::HasNonfatalFailure(); 12693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 12793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 12893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org bool initialized_; 12993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int64_t pre_store_[8]; 13093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}; 13193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 13293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#define REGISTER_STATE_CHECK(statement) do { \ 13393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org libvpx_test::RegisterStateCheck reg_check; \ 13493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org statement; \ 13593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} while (false) 13693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 13793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} // namespace libvpx_test 13893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 13993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 140d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 141d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgnamespace libvpx_test { 142d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 143d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgclass RegisterStateCheck {}; 144d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#define REGISTER_STATE_CHECK(statement) statement 145d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 146d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} // namespace libvpx_test 147d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 148d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#endif // _WIN64 149d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 150f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#endif // TEST_REGISTER_STATE_CHECK_H_ 151