1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef TEST_REGISTER_STATE_CHECK_H_ 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TEST_REGISTER_STATE_CHECK_H_ 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/googletest/src/include/gtest/gtest.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if defined(_WIN64) 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define _WIN32_LEAN_AND_MEAN 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <windows.h> 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <winnt.h> 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan 23233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace testing { 24233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace internal { 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan 26233d2500723e5594f3e7c70896ffeeef32b9c950ywaninline bool operator==(const M128A& lhs, const M128A& rhs) { 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan return (lhs.Low == rhs.Low && lhs.High == rhs.High); 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace internal 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace testing 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan 33233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace libvpx_test { 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Compares the state of xmm[6-15] at construction with their state at 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan// destruction. These registers should be preserved by the callee on 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Windows x64. 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Usage: 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan// { 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan// RegisterStateCheck reg_check; 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan// FunctionToVerify(); 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan// } 43233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass RegisterStateCheck { 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); } 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan static bool StoreRegisters(CONTEXT* const context) { 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan const HANDLE this_thread = GetCurrentThread(); 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(this_thread != NULL); 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan context->ContextFlags = CONTEXT_FLOATING_POINT; 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan const bool context_saved = GetThreadContext(this_thread, context) == TRUE; 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError(); 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan return context_saved; 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Compares the register state. Returns true if the states match. 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool Check() const { 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!initialized_) return false; 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan CONTEXT post_context; 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!StoreRegisters(&post_context)) return false; 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan const M128A* xmm_pre = &pre_context_.Xmm6; 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan const M128A* xmm_post = &post_context.Xmm6; 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (int i = 6; i <= 15; ++i) { 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!"; 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++xmm_pre; 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++xmm_post; 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan return !testing::Test::HasNonfatalFailure(); 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool initialized_; 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan CONTEXT pre_context_; 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define REGISTER_STATE_CHECK(statement) do { \ 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::RegisterStateCheck reg_check; \ 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan statement; \ 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan} while (false) 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace libvpx_test 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan#elif defined(CONFIG_SHARED) && defined(HAVE_NEON) \ 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan && !CONFIG_SHARED && HAVE_NEON 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_integer.h" 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan 90233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern "C" { 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Save the d8-d15 registers into store. 92233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_push_neon(int64_t *store); 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan 95233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace libvpx_test { 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Compares the state of d8-d15 at construction with their state at 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan// destruction. These registers should be preserved by the callee on 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan// arm platform. 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Usage: 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan// { 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan// RegisterStateCheck reg_check; 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan// FunctionToVerify(); 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan// } 105233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass RegisterStateCheck { 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); } 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan ~RegisterStateCheck() { EXPECT_TRUE(Check()); } 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan static bool StoreRegisters(int64_t store[8]) { 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_push_neon(store); 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan return true; 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Compares the register state. Returns true if the states match. 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool Check() const { 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!initialized_) return false; 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t post_store[8]; 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_push_neon(post_store); 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (int i = 0; i < 8; ++i) { 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan EXPECT_EQ(pre_store_[i], post_store[i]) << "d" 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan << i + 8 << " has been modified"; 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan return !testing::Test::HasNonfatalFailure(); 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool initialized_; 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t pre_store_[8]; 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define REGISTER_STATE_CHECK(statement) do { \ 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan libvpx_test::RegisterStateCheck reg_check; \ 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan statement; \ 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan} while (false) 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace libvpx_test 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 141233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace libvpx_test { 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan 143233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass RegisterStateCheck {}; 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define REGISTER_STATE_CHECK(statement) statement 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace libvpx_test 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // _WIN64 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // TEST_REGISTER_STATE_CHECK_H_ 151