mirror of
https://github.com/herumi/xbyak
synced 2024-11-21 16:09:11 -07:00
use cybozu/test.hpp for test of jmp
This commit is contained in:
parent
8c3225865c
commit
a77ee9ac61
7 changed files with 551 additions and 107 deletions
|
@ -263,6 +263,10 @@ License
|
|||
modified new BSD License
|
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
The files under test/cybozu/ are copied from cybozulib(https://github.com/herumi/cybozulib/),
|
||||
which is licensed by BSD-3-Clause and are used for only tests.
|
||||
The header files under xbyak/ are independent from cybozulib.
|
||||
|
||||
History
|
||||
-------------
|
||||
* 2014/Mar/16 ver 4.50 support new Label
|
||||
|
|
|
@ -277,6 +277,11 @@ http://opensource.org/licenses/BSD-3-Clause
|
|||
sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
|
||||
いただきました。
|
||||
|
||||
test/cybozu/以下のファイルはcybozulib(https://github.com/herumi/cybozulib/)
|
||||
の一部を使っています。cybozulibはBSD-3-Clauseライセンスです。
|
||||
cybozulibは単体テストでのみ利用されていて、xbyak/ディレクトリ以下のヘッダ
|
||||
ファイルはcybozulibとは独立に利用できます。
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
◎履歴
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ all: $(TARGET)
|
|||
|
||||
CFLAGS_WARN=-Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith
|
||||
|
||||
CFLAGS=-O2 -fomit-frame-pointer -Wall -fno-operator-names -I../ $(CFLAGS_WARN) #-std=c++0x
|
||||
CFLAGS=-O2 -fomit-frame-pointer -Wall -fno-operator-names -I../ -I./ $(CFLAGS_WARN) #-std=c++0x
|
||||
make_nm:
|
||||
$(CXX) $(CFLAGS) make_nm.cpp -o $@
|
||||
normalize_prefix: normalize_prefix.cpp ../xbyak/xbyak.h
|
||||
|
|
27
test/cybozu/COPYRIGHT
Normal file
27
test/cybozu/COPYRIGHT
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
Copyright (c) 2007-2012 Cybozu Labs, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
Neither the name of the Cybozu Labs, Inc. nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
121
test/cybozu/inttype.hpp
Normal file
121
test/cybozu/inttype.hpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#pragma once
|
||||
/**
|
||||
@file
|
||||
@brief int type definition and macros
|
||||
Copyright (C) 2008 Cybozu Labs, Inc., all rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && (MSC_VER <= 1500)
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef CYBOZU_DEFINED_SSIZE_T
|
||||
#define CYBOZU_DEFINED_SSIZE_T
|
||||
#ifdef _WIN64
|
||||
typedef int64_t ssize_t;
|
||||
#else
|
||||
typedef int32_t ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#include <unistd.h> // for ssize_t
|
||||
#endif
|
||||
|
||||
#ifndef CYBOZU_ALIGN
|
||||
#ifdef _MSC_VER
|
||||
#define CYBOZU_ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define CYBOZU_ALIGN(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CYBOZU_ALLOCA
|
||||
#ifdef _MSC_VER
|
||||
#include <malloc.h>
|
||||
#define CYBOZU_ALLOCA(x) _malloca(x)
|
||||
#else
|
||||
#define CYBOZU_ALLOCA_(x) __builtin_alloca(x)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CYBOZU_FOREACH
|
||||
// std::vector<int> v; CYBOZU_FOREACH(auto x, v) {...}
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define CYBOZU_FOREACH(type_x, xs) for each (type_x in xs)
|
||||
#elif defined(__GNUC__)
|
||||
#define CYBOZU_FOREACH(type_x, xs) for (type_x : xs)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CYBOZU_NUM_OF_ARRAY
|
||||
#define CYBOZU_NUM_OF_ARRAY(x) (sizeof(x) / sizeof(*x))
|
||||
#endif
|
||||
#ifndef CYBOZU_SNPRINTF
|
||||
#ifdef _MSC_VER
|
||||
#define CYBOZU_SNPRINTF(x, len, ...) (void)_snprintf_s(x, len, len - 1, __VA_ARGS__)
|
||||
#else
|
||||
#define CYBOZU_SNPRINTF(x, len, ...) (void)snprintf(x, len, __VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CYBOZU_CPP_VERSION_CPP03 0
|
||||
#define CYBOZU_CPP_VERSION_TR1 1
|
||||
#define CYBOZU_CPP_VERSION_CPP11 2
|
||||
|
||||
#if (__cplusplus >= 201103) || (_MSC_VER >= 1500) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1600)
|
||||
#define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_TR1
|
||||
#else
|
||||
#define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP11
|
||||
#endif
|
||||
#elif (__GNUC__ >= 4 && __GNUC_MINOR__ >= 5) || (__clang_major__ >= 3)
|
||||
#define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_TR1
|
||||
#else
|
||||
#define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP03
|
||||
#endif
|
||||
|
||||
#if (CYBOZU_CPP_VERSION == CYBOZU_CPP_VERSION_TR1)
|
||||
#define CYBOZU_NAMESPACE_STD std::tr1
|
||||
#define CYBOZU_NAMESPACE_TR1_BEGIN namespace tr1 {
|
||||
#define CYBOZU_NAMESPACE_TR1_END }
|
||||
#else
|
||||
#define CYBOZU_NAMESPACE_STD std
|
||||
#define CYBOZU_NAMESPACE_TR1_BEGIN
|
||||
#define CYBOZU_NAMESPACE_TR1_END
|
||||
#endif
|
||||
|
||||
#ifndef CYBOZU_OS_BIT
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
#define CYBOZU_OS_BIT 64
|
||||
#else
|
||||
#define CYBOZU_OS_BIT 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CYBOZU_ENDIAN
|
||||
#define CYBOZU_ENDIAN_UNKNOWN 0
|
||||
#define CYBOZU_ENDIAN_LITTLE 1
|
||||
#define CYBOZU_ENDIAN_BIG 2
|
||||
#if defined(_M_IX86) || defined(_M_AMD64) || defined(__x86_64__) || defined(__i386__)
|
||||
#define CYBOZU_ENDIAN CYBOZU_ENDIAN_LITTLE
|
||||
#else
|
||||
#define CYBOZU_ENDIAN CYBOZU_ENDIAN_UNKNOWN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace cybozu {
|
||||
template<class T>
|
||||
void disable_warning_unused_variable(const T&) { }
|
||||
template<class T, class S>
|
||||
T cast(const S* ptr) { return static_cast<T>(static_cast<const void*>(ptr)); }
|
||||
template<class T, class S>
|
||||
T cast(S* ptr) { return static_cast<T>(static_cast<void*>(ptr)); }
|
||||
} // cybozu
|
345
test/cybozu/test.hpp
Normal file
345
test/cybozu/test.hpp
Normal file
|
@ -0,0 +1,345 @@
|
|||
#pragma once
|
||||
/**
|
||||
@file
|
||||
@brief unit test class
|
||||
|
||||
Copyright (C) 2008 Cybozu Labs, Inc., all rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#if defined(_MSC_VER) && (MSC_VER <= 1500)
|
||||
#include <cybozu/inttype.hpp>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
namespace cybozu { namespace test {
|
||||
|
||||
class AutoRun {
|
||||
typedef void (*Func)();
|
||||
typedef std::list<std::pair<const char*, Func> > UnitTestList;
|
||||
public:
|
||||
AutoRun()
|
||||
: init_(0)
|
||||
, term_(0)
|
||||
, okCount_(0)
|
||||
, ngCount_(0)
|
||||
, exceptionCount_(0)
|
||||
{
|
||||
}
|
||||
void setup(Func init, Func term)
|
||||
{
|
||||
init_ = init;
|
||||
term_ = term;
|
||||
}
|
||||
void append(const char *name, Func func)
|
||||
{
|
||||
list_.push_back(std::make_pair(name, func));
|
||||
}
|
||||
void set(bool isOK)
|
||||
{
|
||||
if (isOK) {
|
||||
okCount_++;
|
||||
} else {
|
||||
ngCount_++;
|
||||
}
|
||||
}
|
||||
std::string getBaseName(const std::string& name) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const char sep = '\\';
|
||||
#else
|
||||
const char sep = '/';
|
||||
#endif
|
||||
size_t pos = name.find_last_of(sep);
|
||||
std::string ret = name.substr(pos + 1);
|
||||
pos = ret.find('.');
|
||||
return ret.substr(0, pos);
|
||||
}
|
||||
int run(int, char *argv[])
|
||||
{
|
||||
std::string msg;
|
||||
try {
|
||||
if (init_) init_();
|
||||
for (UnitTestList::const_iterator i = list_.begin(), ie = list_.end(); i != ie; ++i) {
|
||||
std::cout << "ctest:module=" << i->first << std::endl;
|
||||
try {
|
||||
(i->second)();
|
||||
} catch (std::exception& e) {
|
||||
exceptionCount_++;
|
||||
std::cout << "ctest: " << i->first << " is stopped by exception " << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
exceptionCount_++;
|
||||
std::cout << "ctest: " << i->first << " is stopped by unknown exception" << std::endl;
|
||||
}
|
||||
}
|
||||
if (term_) term_();
|
||||
} catch (std::exception& e) {
|
||||
msg = std::string("ctest:err:") + e.what();
|
||||
} catch (...) {
|
||||
msg = "ctest:err: catch unknown exception";
|
||||
}
|
||||
fflush(stdout);
|
||||
if (msg.empty()) {
|
||||
std::cout << "ctest:name=" << getBaseName(*argv)
|
||||
<< ", module=" << list_.size()
|
||||
<< ", total=" << (okCount_ + ngCount_ + exceptionCount_)
|
||||
<< ", ok=" << okCount_
|
||||
<< ", ng=" << ngCount_
|
||||
<< ", exception=" << exceptionCount_ << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
std::cout << msg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static inline AutoRun& getInstance()
|
||||
{
|
||||
static AutoRun instance;
|
||||
return instance;
|
||||
}
|
||||
private:
|
||||
Func init_;
|
||||
Func term_;
|
||||
int okCount_;
|
||||
int ngCount_;
|
||||
int exceptionCount_;
|
||||
UnitTestList list_;
|
||||
};
|
||||
|
||||
static AutoRun& autoRun = AutoRun::getInstance();
|
||||
|
||||
inline void test(bool ret, const std::string& msg, const std::string& param, const char *file, int line)
|
||||
{
|
||||
autoRun.set(ret);
|
||||
if (!ret) {
|
||||
printf("%s(%d):ctest:%s(%s);\n", file, line, msg.c_str(), param.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool isEqual(const T& lhs, const U& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
inline bool isEqual(const char *lhs, const char *rhs)
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
inline bool isEqual(char *lhs, const char *rhs)
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
inline bool isEqual(const char *lhs, char *rhs)
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
inline bool isEqual(char *lhs, char *rhs)
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
// avoid to compare float directly
|
||||
inline bool isEqual(float lhs, float rhs)
|
||||
{
|
||||
union fi {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} lfi, rfi;
|
||||
lfi.f = lhs;
|
||||
rfi.f = rhs;
|
||||
return lfi.i == rfi.i;
|
||||
}
|
||||
// avoid to compare double directly
|
||||
inline bool isEqual(double lhs, double rhs)
|
||||
{
|
||||
union di {
|
||||
double d;
|
||||
uint64_t i;
|
||||
} ldi, rdi;
|
||||
ldi.d = lhs;
|
||||
rdi.d = rhs;
|
||||
return ldi.i == rdi.i;
|
||||
}
|
||||
|
||||
} } // cybozu::test
|
||||
|
||||
#ifndef CYBOZU_TEST_DISABLE_AUTO_RUN
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return cybozu::test::autoRun.run(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
alert if !x
|
||||
@param x [in]
|
||||
*/
|
||||
#define CYBOZU_TEST_ASSERT(x) cybozu::test::test(!!(x), "CYBOZU_TEST_ASSERT", #x, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
alert if x != y
|
||||
@param x [in]
|
||||
@param y [in]
|
||||
*/
|
||||
#define CYBOZU_TEST_EQUAL(x, y) { \
|
||||
bool eq = cybozu::test::isEqual(x, y); \
|
||||
cybozu::test::test(eq, "CYBOZU_TEST_EQUAL", #x ", " #y, __FILE__, __LINE__); \
|
||||
if (!eq) { \
|
||||
std::cout << "ctest: lhs=" << (x) << std::endl; \
|
||||
std::cout << "ctest: rhs=" << (y) << std::endl; \
|
||||
} \
|
||||
}
|
||||
/**
|
||||
alert if fabs(x, y) >= eps
|
||||
@param x [in]
|
||||
@param y [in]
|
||||
*/
|
||||
#define CYBOZU_TEST_NEAR(x, y, eps) { \
|
||||
bool isNear = fabs((x) - (y)) < eps; \
|
||||
cybozu::test::test(isNear, "CYBOZU_TEST_NEAR", #x ", " #y, __FILE__, __LINE__); \
|
||||
if (!isNear) { \
|
||||
std::cout << "ctest: lhs=" << (x) << std::endl; \
|
||||
std::cout << "ctest: rhs=" << (y) << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CYBOZU_TEST_EQUAL_POINTER(x, y) { \
|
||||
bool eq = x == y; \
|
||||
cybozu::test::test(eq, "CYBOZU_TEST_EQUAL_POINTER", #x ", " #y, __FILE__, __LINE__); \
|
||||
if (!eq) { \
|
||||
std::cout << "ctest: lhs=" << static_cast<const void*>(x) << std::endl; \
|
||||
std::cout << "ctest: rhs=" << static_cast<const void*>(y) << std::endl; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
always alert
|
||||
@param msg [in]
|
||||
*/
|
||||
#define CYBOZU_TEST_FAIL(msg) cybozu::test::test(false, "CYBOZU_TEST_FAIL", msg, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
verify message in exception
|
||||
*/
|
||||
#define CYBOZU_TEST_EXCEPTION_MESSAGE(statement, Exception, msg) \
|
||||
{ \
|
||||
int ret = 0; \
|
||||
std::string errMsg; \
|
||||
try { \
|
||||
statement; \
|
||||
ret = 1; \
|
||||
} catch (const Exception& e) { \
|
||||
errMsg = e.what(); \
|
||||
if (errMsg.find(msg) == std::string::npos) { \
|
||||
ret = 2; \
|
||||
} \
|
||||
} catch (...) { \
|
||||
ret = 3; \
|
||||
} \
|
||||
if (ret) { \
|
||||
cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION_MESSAGE", #statement ", " #Exception ", " #msg, __FILE__, __LINE__); \
|
||||
if (ret == 1) { \
|
||||
std::cout << "ctest: no exception" << std::endl; \
|
||||
} else if (ret == 2) { \
|
||||
std::cout << "ctest: bad exception msg:" << errMsg << std::endl; \
|
||||
} else { \
|
||||
std::cout << "ctest: unexpected exception" << std::endl; \
|
||||
} \
|
||||
} else { \
|
||||
cybozu::test::autoRun.set(true); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CYBOZU_TEST_EXCEPTION(statement, Exception) \
|
||||
{ \
|
||||
int ret = 0; \
|
||||
try { \
|
||||
statement; \
|
||||
ret = 1; \
|
||||
} catch (const Exception&) { \
|
||||
} catch (...) { \
|
||||
ret = 2; \
|
||||
} \
|
||||
if (ret) { \
|
||||
cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION", #statement ", " #Exception, __FILE__, __LINE__); \
|
||||
if (ret == 1) { \
|
||||
std::cout << "ctest: no exception" << std::endl; \
|
||||
} else { \
|
||||
std::cout << "ctest: unexpected exception" << std::endl; \
|
||||
} \
|
||||
} else { \
|
||||
cybozu::test::autoRun.set(true); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
verify statement does not throw
|
||||
*/
|
||||
#define CYBOZU_TEST_NO_EXCEPTION(statement) \
|
||||
try { \
|
||||
statement; \
|
||||
cybozu::test::autoRun.set(true); \
|
||||
} catch (...) { \
|
||||
cybozu::test::test(false, "CYBOZU_TEST_NO_EXCEPTION", #statement, __FILE__, __LINE__); \
|
||||
}
|
||||
|
||||
/**
|
||||
append auto unit test
|
||||
@param name [in] module name
|
||||
*/
|
||||
#define CYBOZU_TEST_AUTO(name) \
|
||||
void cybozu_test_ ## name(); \
|
||||
struct cybozu_test_local_ ## name { \
|
||||
cybozu_test_local_ ## name() \
|
||||
{ \
|
||||
cybozu::test::autoRun.append(#name, cybozu_test_ ## name); \
|
||||
} \
|
||||
} cybozu_test_local_instance_ ## name; \
|
||||
void cybozu_test_ ## name()
|
||||
|
||||
/**
|
||||
append auto unit test with fixture
|
||||
@param name [in] module name
|
||||
*/
|
||||
#define CYBOZU_TEST_AUTO_WITH_FIXTURE(name, Fixture) \
|
||||
void cybozu_test_ ## name(); \
|
||||
void cybozu_test_real_ ## name() \
|
||||
{ \
|
||||
Fixture f; \
|
||||
cybozu_test_ ## name(); \
|
||||
} \
|
||||
struct cybozu_test_local_ ## name { \
|
||||
cybozu_test_local_ ## name() \
|
||||
{ \
|
||||
cybozu::test::autoRun.append(#name, cybozu_test_real_ ## name); \
|
||||
} \
|
||||
} cybozu_test_local_instance_ ## name; \
|
||||
void cybozu_test_ ## name()
|
||||
|
||||
/**
|
||||
setup fixture
|
||||
@param Fixture [in] class name of fixture
|
||||
@note cstr of Fixture is called before test and dstr of Fixture is called after test
|
||||
*/
|
||||
#define CYBOZU_TEST_SETUP_FIXTURE(Fixture) \
|
||||
Fixture *cybozu_test_local_fixture; \
|
||||
void cybozu_test_local_init() \
|
||||
{ \
|
||||
cybozu_test_local_fixture = new Fixture(); \
|
||||
} \
|
||||
void cybozu_test_local_term() \
|
||||
{ \
|
||||
delete cybozu_test_local_fixture; \
|
||||
} \
|
||||
struct cybozu_test_local_fixture_setup_ { \
|
||||
cybozu_test_local_fixture_setup_() \
|
||||
{ \
|
||||
cybozu::test::autoRun.setup(cybozu_test_local_init, cybozu_test_local_term); \
|
||||
} \
|
||||
} cybozu_test_local_fixture_setup_instance_;
|
154
test/jmp.cpp
154
test/jmp.cpp
|
@ -2,7 +2,8 @@
|
|||
#include <string.h>
|
||||
#include <string>
|
||||
#include <xbyak/xbyak.h>
|
||||
#define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
||||
#include <cybozu/inttype.hpp>
|
||||
#include <cybozu/test.hpp>
|
||||
|
||||
#if !defined(_WIN64) && !defined(__x86_64__)
|
||||
#define ONLY_32BIT
|
||||
|
@ -28,9 +29,27 @@ void diff(const std::string& a, const std::string& b)
|
|||
}
|
||||
}
|
||||
|
||||
void test1()
|
||||
void dump(const std::string& m)
|
||||
{
|
||||
printf("size=%d\n ", (int)m.size());
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02x ", i);
|
||||
}
|
||||
printf("\n ");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("---");
|
||||
}
|
||||
printf("\n");
|
||||
for (size_t i = 0; i < m.size(); i++) {
|
||||
if ((i % 16) == 0) printf("%04x ", (int)(i / 16));
|
||||
printf("%02x ", (unsigned char)m[i]);
|
||||
if ((i % 16) == 15) putchar('\n');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
CYBOZU_TEST_AUTO(test1)
|
||||
{
|
||||
puts("test1");
|
||||
struct TestJmp : public Xbyak::CodeGenerator {
|
||||
/*
|
||||
4 X0:
|
||||
|
@ -113,24 +132,21 @@ void test1()
|
|||
{ 127, false, true, { 0xeb, 0x7f }, 2 },
|
||||
{ 128, false, false, { 0xe9, 0x80, 0x00, 0x00, 0x00 }, 5 },
|
||||
};
|
||||
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
|
||||
const Tbl *p = &tbl[i];
|
||||
for (int k = 0; k < 2; k++) {
|
||||
TestJmp jmp(p->offset, p->isBack, p->isShort, k == 0);
|
||||
const uint8 *q = (const uint8*)jmp.getCode();
|
||||
if (p->isBack) q += p->offset; /* skip nop */
|
||||
for (int j = 0; j < p->size; j++) {
|
||||
if (q[j] != p->result[j]) {
|
||||
printf("err (%d, %d, %d) %02x assume=%02x\n", (int)i, k, j, q[j], p->result[j]);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(q[j], p->result[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testJmpCx()
|
||||
CYBOZU_TEST_AUTO(testJmpCx)
|
||||
{
|
||||
puts("testJmpCx");
|
||||
struct TestJmpCx : public CodeGenerator {
|
||||
explicit TestJmpCx(void *p, bool useNewLabel)
|
||||
: Xbyak::CodeGenerator(16, p)
|
||||
|
@ -139,7 +155,6 @@ void testJmpCx()
|
|||
Label lp;
|
||||
L(lp);
|
||||
#ifdef XBYAK64
|
||||
puts("TestJmpCx 64bit");
|
||||
/*
|
||||
67 E3 FD ; jecxz lp
|
||||
E3 FB ; jrcxz lp
|
||||
|
@ -147,7 +162,6 @@ void testJmpCx()
|
|||
jecxz(lp);
|
||||
jrcxz(lp);
|
||||
#else
|
||||
puts("TestJmpCx 32bit");
|
||||
/*
|
||||
E3FE ; jecxz lp
|
||||
67E3FB ; jcxz lp
|
||||
|
@ -159,7 +173,6 @@ void testJmpCx()
|
|||
inLocalLabel();
|
||||
L(".lp");
|
||||
#ifdef XBYAK64
|
||||
puts("TestJmpCx 64bit");
|
||||
/*
|
||||
67 E3 FD ; jecxz lp
|
||||
E3 FB ; jrcxz lp
|
||||
|
@ -167,7 +180,6 @@ void testJmpCx()
|
|||
jecxz(".lp");
|
||||
jrcxz(".lp");
|
||||
#else
|
||||
puts("TestJmpCx 32bit");
|
||||
/*
|
||||
E3FE ; jecxz lp
|
||||
67E3FB ; jcxz lp
|
||||
|
@ -192,23 +204,15 @@ void testJmpCx()
|
|||
for (int j = 0; j < 2; j++) {
|
||||
char buf[16] = {};
|
||||
TestJmpCx code(buf, j == 0);
|
||||
if (memcmp(buf, tbl.p, tbl.len) == 0) {
|
||||
} else {
|
||||
printf("err %d\n", j);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printf("%02x ", (unsigned char)buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(memcmp(buf, tbl.p, tbl.len), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4310)
|
||||
#endif
|
||||
void test2()
|
||||
CYBOZU_TEST_AUTO(test2)
|
||||
{
|
||||
puts("test2");
|
||||
struct TestJmp2 : public CodeGenerator {
|
||||
/*
|
||||
1 00000000 90 nop
|
||||
|
@ -296,7 +300,7 @@ void test2()
|
|||
TestJmp2 c(i == 0 ? 0 : Xbyak::AutoGrow, j == 0);
|
||||
c.ready();
|
||||
std::string m((const char*)c.getCode(), c.getSize());
|
||||
diff(m, ok);
|
||||
CYBOZU_TEST_EQUAL(m, ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,9 +309,8 @@ void test2()
|
|||
int add5(int x) { return x + 5; }
|
||||
int add2(int x) { return x + 2; }
|
||||
|
||||
void test3()
|
||||
CYBOZU_TEST_AUTO(test3)
|
||||
{
|
||||
puts("test3");
|
||||
struct Grow : Xbyak::CodeGenerator {
|
||||
Grow(int dummySize)
|
||||
: Xbyak::CodeGenerator(128, Xbyak::AutoGrow)
|
||||
|
@ -332,9 +335,7 @@ void test3()
|
|||
int (*f)() = (int (*)())g.getCode();
|
||||
int x = f();
|
||||
const int ok = 107;
|
||||
if (x != ok) {
|
||||
printf("err %d assume %d\n", x, ok);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(x, ok);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -361,28 +362,8 @@ struct MyAllocator : Xbyak::Allocator {
|
|||
}
|
||||
} myAlloc;
|
||||
|
||||
void dump(const std::string& m)
|
||||
CYBOZU_TEST_AUTO(test4)
|
||||
{
|
||||
printf("size=%d\n ", (int)m.size());
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02x ", i);
|
||||
}
|
||||
printf("\n ");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("---");
|
||||
}
|
||||
printf("\n");
|
||||
for (size_t i = 0; i < m.size(); i++) {
|
||||
if ((i % 16) == 0) printf("%04x ", (int)(i / 16));
|
||||
printf("%02x ", (unsigned char)m[i]);
|
||||
if ((i % 16) == 15) putchar('\n');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void test4()
|
||||
{
|
||||
puts("test4");
|
||||
struct Test4 : Xbyak::CodeGenerator {
|
||||
Test4(int size, void *mode, bool useNewLabel)
|
||||
: CodeGenerator(size, mode)
|
||||
|
@ -411,15 +392,12 @@ void test4()
|
|||
gc.ready();
|
||||
fm.assign((const char*)fc.getCode(), fc.getSize());
|
||||
gm.assign((const char*)gc.getCode(), gc.getSize());
|
||||
// dump(fm);
|
||||
// dump(gm);
|
||||
diff(gm, gm);
|
||||
CYBOZU_TEST_EQUAL(fm, gm);
|
||||
}
|
||||
}
|
||||
|
||||
void test5()
|
||||
CYBOZU_TEST_AUTO(test5)
|
||||
{
|
||||
puts("test5");
|
||||
struct Test5 : Xbyak::CodeGenerator {
|
||||
explicit Test5(int size, int count, void *mode)
|
||||
: CodeGenerator(size, mode, &myAlloc)
|
||||
|
@ -456,18 +434,14 @@ void test5()
|
|||
int ret;
|
||||
Test5 fc(1024 * 64, count, 0);
|
||||
ret = ((int (*)())fc.getCode())();
|
||||
if (ret != count * count) {
|
||||
printf("err ret=%d, %d\n", ret, count * count);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(ret, count * count);
|
||||
fm.assign((const char*)fc.getCode(), fc.getSize());
|
||||
Test5 gc(10, count, Xbyak::AutoGrow);
|
||||
gc.ready();
|
||||
ret = ((int (*)())gc.getCode())();
|
||||
if (ret != count * count) {
|
||||
printf("err ret=%d, %d\n", ret, count * count);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(ret, count * count);
|
||||
gm.assign((const char*)gc.getCode(), gc.getSize());
|
||||
diff(fm, gm);
|
||||
CYBOZU_TEST_EQUAL(fm, gm);
|
||||
}
|
||||
|
||||
size_t getValue(const uint8* p)
|
||||
|
@ -482,13 +456,11 @@ size_t getValue(const uint8* p)
|
|||
void checkAddr(const uint8 *p, size_t offset, size_t expect)
|
||||
{
|
||||
size_t v = getValue(p + offset);
|
||||
if (v == size_t(p) + expect) return;
|
||||
printf("err p=%p, offset=%lld, v=%llx(%llx), expect=%d\n", p, (long long)offset, (long long)v, (long long)(expect + size_t(p)), (int)expect);
|
||||
CYBOZU_TEST_EQUAL(v, size_t(p) + expect);
|
||||
}
|
||||
|
||||
void testMovLabel()
|
||||
CYBOZU_TEST_AUTO(MovLabel)
|
||||
{
|
||||
puts("testMovLabel");
|
||||
struct MovLabelCode : Xbyak::CodeGenerator {
|
||||
MovLabelCode(bool grow, bool useNewLabel)
|
||||
: Xbyak::CodeGenerator(grow ? 128 : 4096, grow ? Xbyak::AutoGrow : 0)
|
||||
|
@ -564,13 +536,11 @@ void testMovLabel()
|
|||
MovLabelCode code(grow, useNewLabel);
|
||||
if (grow) code.ready();
|
||||
const uint8* const p = code.getCode();
|
||||
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
|
||||
int pos = tbl[i].pos;
|
||||
uint8 x = p[pos];
|
||||
uint8 ok = tbl[i].ok;
|
||||
if (x != ok) {
|
||||
printf("err pos=%d, x=%02x, ok=%02x\n", pos, x, ok);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(x, ok);
|
||||
}
|
||||
#ifdef XBYAK32
|
||||
checkAddr(p, 0x03, 0x001);
|
||||
|
@ -583,9 +553,8 @@ void testMovLabel()
|
|||
}
|
||||
}
|
||||
|
||||
void testMovLabel2()
|
||||
CYBOZU_TEST_AUTO(testMovLabel2)
|
||||
{
|
||||
puts("tsetMovLabel2");
|
||||
struct MovLabel2Code : Xbyak::CodeGenerator {
|
||||
MovLabel2Code()
|
||||
{
|
||||
|
@ -617,10 +586,10 @@ void testMovLabel2()
|
|||
};
|
||||
MovLabel2Code code;
|
||||
int ret = code.getCode<int (*)()>()();
|
||||
if (ret != 7) printf("ERR=%d\n", ret);
|
||||
CYBOZU_TEST_EQUAL(ret, 7);
|
||||
}
|
||||
|
||||
void test6()
|
||||
CYBOZU_TEST_AUTO(test6)
|
||||
{
|
||||
struct TestLocal : public Xbyak::CodeGenerator {
|
||||
TestLocal(bool grow)
|
||||
|
@ -694,13 +663,11 @@ void test6()
|
|||
if (grow) code.ready();
|
||||
int (*f)() = code.getCode<int (*)()>();
|
||||
int a = f();
|
||||
if (a != 15) {
|
||||
printf("ERR a=%d\n", a);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(a, 15);
|
||||
}
|
||||
}
|
||||
|
||||
void testNewLabel()
|
||||
CYBOZU_TEST_AUTO(testNewLabel)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code(bool grow)
|
||||
|
@ -788,13 +755,11 @@ void testNewLabel()
|
|||
if (grow) code.ready();
|
||||
int (*f)() = code.getCode<int (*)()>();
|
||||
int r = f();
|
||||
if (r != 16) {
|
||||
printf("err %d %d\n", i, r);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(r, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void testAssign()
|
||||
CYBOZU_TEST_AUTO(testAssign)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code(bool grow)
|
||||
|
@ -821,29 +786,6 @@ void testAssign()
|
|||
if (grow) code.ready();
|
||||
int (*f)() = code.getCode<int (*)()>();
|
||||
int ret = f();
|
||||
if (ret != 5) {
|
||||
printf("err %d\n", ret);
|
||||
}
|
||||
CYBOZU_TEST_EQUAL(ret, 5);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
try {
|
||||
test1();
|
||||
test2();
|
||||
#ifdef ONLY_32BIT
|
||||
test3();
|
||||
#endif
|
||||
test4();
|
||||
test5();
|
||||
test6();
|
||||
testJmpCx();
|
||||
testMovLabel();
|
||||
testMovLabel2();
|
||||
testNewLabel();
|
||||
testAssign();
|
||||
} catch (std::exception& e) {
|
||||
printf("ERR:%s\n", e.what());
|
||||
} catch (...) {
|
||||
printf("unknown error\n");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue