mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-09 16:08:04 +01:00
Squashed 'externals/xbyak/' content from commit d512551e
git-subtree-dir: externals/xbyak git-subtree-split: d512551e914737300ba35f3c049d1b40effbe76d
This commit is contained in:
commit
4ed09fda06
79 changed files with 22734 additions and 0 deletions
8
test/6.bat
Normal file
8
test/6.bat
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
@echo off
|
||||
rm a.lst b.lst
|
||||
echo nasm
|
||||
nasm -l a.lst -f win64 test.asm
|
||||
cat a.lst
|
||||
echo yasm
|
||||
yasm -l b.lst -f win64 test.asm
|
||||
cat b.lst
|
||||
74
test/Makefile
Normal file
74
test/Makefile
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
TARGET = make_nm normalize_prefix jmp address nm_frame bad_address misc
|
||||
XBYAK_INC=../xbyak/xbyak.h
|
||||
BIT=32
|
||||
ifeq ($(shell uname -m),x86_64)
|
||||
BIT=64
|
||||
endif
|
||||
|
||||
ifeq ($(MODE_BIT),64)
|
||||
TARGET += jmp64 address64
|
||||
endif
|
||||
|
||||
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../ -I./ $(CFLAGS_WARN) #-std=c++0x
|
||||
make_nm:
|
||||
$(CXX) $(CFLAGS) make_nm.cpp -o $@
|
||||
normalize_prefix: normalize_prefix.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) normalize_prefix.cpp -o $@
|
||||
test_mmx: test_mmx.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) test_mmx.cpp -o $@ -lpthread
|
||||
jmp: jmp.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) jmp.cpp -o $@ -m32
|
||||
jmp64: jmp.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) jmp.cpp -o $@ -m64
|
||||
address: address.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) address.cpp -o $@ -m32
|
||||
address64: address.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) address.cpp -o $@ -m64
|
||||
nm_frame: nm_frame.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) nm_frame.cpp -o $@ -m32
|
||||
bad_address: bad_address.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) bad_address.cpp -o $@
|
||||
misc: misc.cpp ../xbyak/xbyak.h
|
||||
$(CXX) $(CFLAGS) misc.cpp -o $@
|
||||
|
||||
test: normalize_prefix jmp bad_address
|
||||
$(MAKE) -C ../gen
|
||||
./test_nm.sh
|
||||
./test_nm.sh Y
|
||||
./test_address.sh
|
||||
./jmp
|
||||
./bad_address
|
||||
./misc
|
||||
ifeq ($(BIT),64)
|
||||
./test_address.sh 64
|
||||
./test_nm.sh 64
|
||||
./test_nm.sh Y64
|
||||
./jmp64
|
||||
endif
|
||||
|
||||
test_avx: normalize_prefix
|
||||
./test_avx.sh
|
||||
./test_avx.sh Y
|
||||
ifeq ($(BIT),64)
|
||||
./test_address.sh 64
|
||||
./test_avx.sh 64
|
||||
./test_avx.sh Y64
|
||||
endif
|
||||
|
||||
test_avx512: normalize_prefix
|
||||
./test_avx512.sh
|
||||
ifeq ($(BIT),64)
|
||||
./test_avx512.sh 64
|
||||
endif
|
||||
clean:
|
||||
rm -rf *.o $(TARGET) lib_run
|
||||
|
||||
lib_run: lib_test.cpp lib_run.cpp lib.h
|
||||
$(CXX) $(CFLAGS) lib_run.cpp lib_test.cpp -o lib_run
|
||||
make_nm: make_nm.cpp $(XBYAK_INC)
|
||||
|
||||
|
||||
14
test/Makefile.win
Normal file
14
test/Makefile.win
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
OPT=/EHsc -I../xbyak /W4 -D_CRT_SECURE_NO_WARNINGS
|
||||
../xbyak/xbyak_mnemonic.h: ../gen/gen_code.exe ../gen/gen_avx512.exe
|
||||
../gen/gen_code.exe > $@
|
||||
../gen/gen_avx512.exe >> $@
|
||||
|
||||
../gen/gen_code.exe: ../gen/gen_code.cpp #../xbyak/xbyak.h
|
||||
cl ../gen/gen_code.cpp $(OPT) /Fe:../gen/gen_code.exe
|
||||
|
||||
../gen/gen_avx512.exe: ../gen/gen_avx512.cpp #../xbyak/xbyak.h
|
||||
cl ../gen/gen_avx512.cpp $(OPT) /Fe:../gen/gen_avx512.exe
|
||||
|
||||
SUB_HEADER=../xbyak/xbyak_mnemonic.h
|
||||
|
||||
all: $(SUB_HEADER)
|
||||
9
test/a.bat
Normal file
9
test/a.bat
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
@echo off
|
||||
echo 32bit
|
||||
rm -rf a.lst b.lst
|
||||
echo nasm
|
||||
nasm -l a.lst -f win32 -DWIN32 test.asm
|
||||
cat a.lst
|
||||
echo yasm
|
||||
yasm -l b.lst -f win32 -DWIN32 test.asm
|
||||
cat b.lst
|
||||
155
test/address.cpp
Normal file
155
test/address.cpp
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
void genVsibSub(bool isJIT, const char *name, const char *tbl[], size_t tblSize)
|
||||
{
|
||||
for (size_t i = 0; i < tblSize; i++) {
|
||||
if (isJIT) {
|
||||
printf("%s (ymm7, ptr[", name);
|
||||
} else {
|
||||
printf("%s ymm7, [", name);
|
||||
}
|
||||
printf("%s", tbl[i]);
|
||||
if (isJIT) {
|
||||
printf("], ymm4); dump();\n");
|
||||
} else {
|
||||
printf("], ymm4\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
void genVsib(bool isJIT)
|
||||
{
|
||||
if (isJIT) puts("void genVsib() {");
|
||||
const char *vm32xTbl[] = {
|
||||
"xmm0",
|
||||
"xmm0 * 1",
|
||||
"xmm0 + 4",
|
||||
"xmm0 + eax",
|
||||
"xmm0 * 4 + ecx",
|
||||
"xmm3 * 8 + edi + 123",
|
||||
"xmm2 * 2 + 5",
|
||||
"eax + xmm0",
|
||||
"esp + xmm4",
|
||||
};
|
||||
const char *vm32yTbl[] = {
|
||||
"ymm0",
|
||||
"ymm0 * 1",
|
||||
"ymm0 + 4",
|
||||
"ymm0 + eax",
|
||||
"ymm0 * 4 + ecx",
|
||||
"ymm3 * 8 + edi + 123",
|
||||
"ymm2 * 2 + 5",
|
||||
"eax + ymm0",
|
||||
"esp + ymm4",
|
||||
};
|
||||
genVsibSub(isJIT, "vgatherdpd", vm32xTbl, NUM_OF_ARRAY(vm32xTbl));
|
||||
genVsibSub(isJIT, "vgatherqpd", vm32yTbl, NUM_OF_ARRAY(vm32yTbl));
|
||||
#ifdef XBYAK64
|
||||
const char *vm32x64Tbl[] = {
|
||||
"xmm0 + r11",
|
||||
"r13 + xmm15",
|
||||
"123 + rsi + xmm2 * 4",
|
||||
};
|
||||
genVsibSub(isJIT, "vgatherdpd", vm32x64Tbl, NUM_OF_ARRAY(vm32x64Tbl));
|
||||
#endif
|
||||
if (isJIT) puts("}");
|
||||
}
|
||||
|
||||
void genAddress(bool isJIT, const char regTbl[][5], size_t regTblNum)
|
||||
{
|
||||
int count = 0;
|
||||
int funcNum = 1;
|
||||
if (isJIT) {
|
||||
puts("void gen0(){");
|
||||
}
|
||||
for (size_t i = 0; i < regTblNum + 1; i++) {
|
||||
const char *base = regTbl[i];
|
||||
for (size_t j = 0; j < regTblNum + 1; j++) {
|
||||
if (j == 4) continue; /* esp is not index register */
|
||||
const char *index = regTbl[j];
|
||||
static const int scaleTbl[] = { 0, 1, 2, 4, 8 };
|
||||
for (size_t k = 0; k < NUM_OF_ARRAY(scaleTbl); k++) {
|
||||
int scale = scaleTbl[k];
|
||||
static const int dispTbl[] = { 0, 1, 1000, -1, -1000 };
|
||||
for (size_t m = 0; m < NUM_OF_ARRAY(dispTbl); m++) {
|
||||
int disp = dispTbl[m];
|
||||
bool isFirst = true;
|
||||
if (isJIT) {
|
||||
printf("mov (ecx, ptr[");
|
||||
} else {
|
||||
printf("mov ecx, [");
|
||||
}
|
||||
if (i < regTblNum) {
|
||||
printf("%s", base);
|
||||
isFirst = false;
|
||||
}
|
||||
if (j < regTblNum) {
|
||||
if (!isFirst) putchar('+');
|
||||
printf("%s", index);
|
||||
if (scale) printf("*%d", scale);
|
||||
isFirst = false;
|
||||
}
|
||||
if (isFirst) {
|
||||
if (isJIT) printf("(void*)");
|
||||
printf("0x%08X", disp);
|
||||
} else {
|
||||
if (disp >= 0) {
|
||||
putchar('+');
|
||||
}
|
||||
printf("%d", disp);
|
||||
isFirst = false;
|
||||
}
|
||||
if (isJIT) {
|
||||
printf("]); dump();\n");
|
||||
} else {
|
||||
printf("]\n");
|
||||
}
|
||||
if (isJIT) {
|
||||
count++;
|
||||
if ((count % 100) == 0) {
|
||||
printf("}\n void gen%d(){\n", funcNum++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isJIT) puts("}");
|
||||
genVsib(isJIT);
|
||||
if (isJIT) {
|
||||
printf("void gen(){\n");
|
||||
for (int i = 0; i < funcNum; i++) {
|
||||
printf(" gen%d();\n", i);
|
||||
}
|
||||
puts("genVsib();");
|
||||
printf("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argc--, argv++;
|
||||
bool phase = argc > 0 && strcmp(*argv, "1") == 0;
|
||||
bool isJIT = (argc > 1);
|
||||
fprintf(stderr, "phase:%c %s\n", phase ? '1' : '2', isJIT ? "jit" : "asm");
|
||||
if (phase) {
|
||||
fprintf(stderr, "32bit reg\n");
|
||||
static const char reg32Tbl[][5] = {
|
||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
||||
#ifdef XBYAK64
|
||||
"r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
|
||||
#endif
|
||||
};
|
||||
genAddress(isJIT, reg32Tbl, NUM_OF_ARRAY(reg32Tbl));
|
||||
} else {
|
||||
#ifdef XBYAK64
|
||||
fprintf(stderr, "64bit reg\n");
|
||||
static const char reg64Tbl[][5] = {
|
||||
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
};
|
||||
genAddress(isJIT, reg64Tbl, NUM_OF_ARRAY(reg64Tbl));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
45
test/bad_address.cpp
Normal file
45
test/bad_address.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#include <xbyak/xbyak.h>
|
||||
|
||||
#define TEST_EXCEPTION(state) \
|
||||
{ \
|
||||
num++; \
|
||||
bool exception = false; \
|
||||
try { \
|
||||
state; \
|
||||
} catch (...) { \
|
||||
exception = true; \
|
||||
} \
|
||||
if (!exception) { \
|
||||
printf("exception should arise for %s\n", #state); \
|
||||
err++; \
|
||||
} \
|
||||
}
|
||||
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code()
|
||||
{
|
||||
int err = 0;
|
||||
int num = 0;
|
||||
TEST_EXCEPTION(mov(eax, ptr [esp + esp]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [ax])); // not support
|
||||
TEST_EXCEPTION(mov(eax, ptr [esp * 4]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [eax * 16]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [eax + eax + eax]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [eax * 2 + ecx * 4]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [eax * 2 + ecx * 4]));
|
||||
TEST_EXCEPTION(vgatherdpd(xmm0, ptr [eax * 2], ymm3));
|
||||
TEST_EXCEPTION(vgatherdpd(xmm0, ptr [xmm0 + xmm1], ymm3));
|
||||
#ifdef XBYAK64
|
||||
TEST_EXCEPTION(mov(eax, ptr [rax + eax]));
|
||||
TEST_EXCEPTION(mov(eax, ptr [xmm0 + ymm0]));
|
||||
#endif
|
||||
if (!err) {
|
||||
printf("bad_address test %d ok\n", num);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Code c;
|
||||
}
|
||||
125
test/cvt_test.cpp
Normal file
125
test/cvt_test.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include <xbyak/xbyak.h>
|
||||
|
||||
using namespace Xbyak;
|
||||
using namespace Xbyak::util;
|
||||
|
||||
#ifdef XBYAK64
|
||||
const struct Ptn {
|
||||
const Reg8 *reg8;
|
||||
Reg16 reg16;
|
||||
Reg32 reg32;
|
||||
Reg64 reg64;
|
||||
} tbl[] = {
|
||||
{ &al, ax, eax, rax },
|
||||
{ &bl, bx, ebx, rbx },
|
||||
{ &cl, cx, ecx, rcx },
|
||||
{ &dl, dx, edx, rdx },
|
||||
{ &sil, si, esi, rsi },
|
||||
{ &dil, di, edi, rdi },
|
||||
{ &bpl, bp, ebp, rbp },
|
||||
{ &spl, sp, esp, rsp },
|
||||
{ &r8b, r8w, r8d, r8 },
|
||||
{ &r9b, r9w, r9d, r9 },
|
||||
{ &r10b, r10w, r10d, r10 },
|
||||
{ &r11b, r11w, r11d, r11 },
|
||||
{ &r12b, r12w, r12d, r12 },
|
||||
{ &r13b, r13w, r13d, r13 },
|
||||
{ &r14b, r14w, r14d, r14 },
|
||||
{ &r15b, r15w, r15d, r15 },
|
||||
};
|
||||
#else
|
||||
const struct Ptn {
|
||||
const Reg8 *reg8;
|
||||
Reg16 reg16;
|
||||
Reg32 reg32;
|
||||
} tbl[] = {
|
||||
{ &al, ax, eax },
|
||||
{ &bl, bx, ebx },
|
||||
{ &cl, cx, ecx },
|
||||
{ &dl, dx, edx },
|
||||
{ 0, si, esi },
|
||||
{ 0, di, edi },
|
||||
{ 0, bp, ebp },
|
||||
{ 0, sp, esp },
|
||||
};
|
||||
#endif
|
||||
|
||||
int errNum = 0;
|
||||
int testNum = 0;
|
||||
|
||||
template<class T>
|
||||
void verify(const T& x, const T& y)
|
||||
{
|
||||
if (x != y) {
|
||||
printf("ERR %s %s\n", x.toString(), y.toString());
|
||||
errNum++;
|
||||
}
|
||||
testNum++;
|
||||
}
|
||||
|
||||
#define verifyExp(state) \
|
||||
{ \
|
||||
bool isOK = false; \
|
||||
try { \
|
||||
state; \
|
||||
} catch (const Xbyak::Error& e) { \
|
||||
if ((int)e == ERR_CANT_CONVERT) { \
|
||||
isOK = true; \
|
||||
} \
|
||||
} \
|
||||
if (!isOK) { \
|
||||
printf("ERR " #state "\n"); \
|
||||
errNum++; \
|
||||
} \
|
||||
testNum++; \
|
||||
}
|
||||
|
||||
int main()
|
||||
try
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tbl) / sizeof(tbl[0]); i++) {
|
||||
if (tbl[i].reg8) {
|
||||
verify(tbl[i].reg8->cvt8(), *tbl[i].reg8);
|
||||
verify(tbl[i].reg8->cvt16(), tbl[i].reg16);
|
||||
verify(tbl[i].reg8->cvt32(), tbl[i].reg32);
|
||||
verify(tbl[i].reg16.cvt8(), *tbl[i].reg8);
|
||||
verify(tbl[i].reg32.cvt8(), *tbl[i].reg8);
|
||||
}
|
||||
verify(tbl[i].reg16.cvt16(), tbl[i].reg16);
|
||||
verify(tbl[i].reg16.cvt32(), tbl[i].reg32);
|
||||
verify(tbl[i].reg32.cvt16(), tbl[i].reg16);
|
||||
verify(tbl[i].reg32.cvt32(), tbl[i].reg32);
|
||||
#ifdef XBYAK64
|
||||
if (tbl[i].reg8) {
|
||||
verify(tbl[i].reg64.cvt8(), *tbl[i].reg8);
|
||||
verify(tbl[i].reg8->cvt64(), tbl[i].reg64);
|
||||
}
|
||||
verify(tbl[i].reg64.cvt16(), tbl[i].reg16);
|
||||
verify(tbl[i].reg64.cvt32(), tbl[i].reg32);
|
||||
verify(tbl[i].reg64.cvt64(), tbl[i].reg64);
|
||||
verify(tbl[i].reg16.cvt64(), tbl[i].reg64);
|
||||
verify(tbl[i].reg32.cvt64(), tbl[i].reg64);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
const Reg8 errTbl[] = {
|
||||
ah, bh, ch, dh
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(errTbl) / sizeof(errTbl[0]); i++) {
|
||||
verifyExp(errTbl[i].cvt16());
|
||||
}
|
||||
}
|
||||
#ifdef XBYAK32
|
||||
{
|
||||
const Reg16 errTbl[] = {
|
||||
si, di, bp, sp
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(errTbl) / sizeof(errTbl[0]); i++) {
|
||||
verifyExp(errTbl[i].cvt8());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("test=%d(err=%d)\n", testNum, errNum);
|
||||
} catch (std::exception& e) {
|
||||
printf("ERR %s\n", e.what());
|
||||
}
|
||||
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_;
|
||||
1151
test/jmp.cpp
Normal file
1151
test/jmp.cpp
Normal file
File diff suppressed because it is too large
Load diff
20
test/jmp.sln
Normal file
20
test/jmp.sln
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
þ½Ž¿
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jmp", "jmp.vcproj", "{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
195
test/jmp.vcproj
Normal file
195
test/jmp.vcproj
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="shift_jis"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="jmp"
|
||||
ProjectGUID="{AC0B3317-E988-44F8-954A-BCBE4B3BB2BF}"
|
||||
RootNamespace="jmp"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="$(SolutionDir)/../"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="$(SolutionDir)/../"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="ソース ファイル"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\jmp.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ヘッダー ファイル"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="リソース ファイル"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
63
test/lib.h
Normal file
63
test/lib.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
|
||||
struct Reg {
|
||||
int r_;
|
||||
Reg(int r) : r_(r) {}
|
||||
};
|
||||
|
||||
inline const Reg& getReg0() { static const Reg r(0); return r; }
|
||||
inline const Reg& getReg1() { static const Reg r(1); return r; }
|
||||
inline const Reg& getReg2() { static const Reg r(2); return r; }
|
||||
|
||||
static const Reg& r0 = getReg0();
|
||||
static const Reg& r1 = getReg1();
|
||||
static const Reg& r2 = getReg2();
|
||||
|
||||
inline void putReg()
|
||||
{
|
||||
puts("putReg");
|
||||
printf("r0=%p, %d\n", &r0, r0.r_);
|
||||
printf("r0=%p, %d\n", &r0, r1.r_);
|
||||
printf("r0=%p, %d\n", &r0, r2.r_);
|
||||
}
|
||||
|
||||
struct A {
|
||||
int a;
|
||||
A()
|
||||
: a(5)
|
||||
{
|
||||
puts("A cstr");
|
||||
}
|
||||
~A()
|
||||
{
|
||||
puts("A dstr");
|
||||
}
|
||||
void put() const
|
||||
{
|
||||
printf("a=%d\n", a);
|
||||
}
|
||||
};
|
||||
|
||||
template<int dummy = 0>
|
||||
struct XT {
|
||||
static A a;
|
||||
};
|
||||
|
||||
template<int dummy>
|
||||
A XT<dummy>::a;
|
||||
|
||||
typedef XT<0> X;
|
||||
|
||||
void init();
|
||||
|
||||
struct Init {
|
||||
Init()
|
||||
{
|
||||
puts("Init");
|
||||
init();
|
||||
putReg();
|
||||
}
|
||||
};
|
||||
static Init s_init;
|
||||
|
||||
51
test/lib_min.cpp
Normal file
51
test/lib_min.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdio.h>
|
||||
|
||||
static const struct XXX {
|
||||
XXX() { puts("XXX"); }
|
||||
} s_sss;
|
||||
|
||||
struct A {
|
||||
int aaa;
|
||||
A()
|
||||
: aaa(123)
|
||||
{
|
||||
puts("A cstr");
|
||||
}
|
||||
~A()
|
||||
{
|
||||
puts("A dstr");
|
||||
}
|
||||
void put() const
|
||||
{
|
||||
printf("aaa=%d\n", aaa);
|
||||
}
|
||||
};
|
||||
|
||||
template<int dummy = 0>
|
||||
struct XT {
|
||||
static A sss;
|
||||
};
|
||||
|
||||
template<int dummy>
|
||||
A XT<dummy>::sss;
|
||||
|
||||
typedef XT<0> X;
|
||||
|
||||
static struct Init {
|
||||
Init()
|
||||
{
|
||||
puts("Init");
|
||||
X::sss.put();
|
||||
}
|
||||
} s_init;
|
||||
|
||||
int f() { puts("f"); return 4; }
|
||||
|
||||
static const int r = f();
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("main");
|
||||
printf("r=%d\n", r);
|
||||
X::sss.put();
|
||||
}
|
||||
9
test/lib_run.cpp
Normal file
9
test/lib_run.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "lib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("main");
|
||||
X::a.put();
|
||||
putReg();
|
||||
}
|
||||
|
||||
13
test/lib_test.cpp
Normal file
13
test/lib_test.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "lib.h"
|
||||
|
||||
void init()
|
||||
{
|
||||
static bool init = true;
|
||||
printf("in lib_test %d\n", init);
|
||||
if (!init) return;
|
||||
init = false;
|
||||
X::a.put();
|
||||
putReg();
|
||||
}
|
||||
|
||||
|
||||
2190
test/make_512.cpp
Normal file
2190
test/make_512.cpp
Normal file
File diff suppressed because it is too large
Load diff
3309
test/make_nm.cpp
Normal file
3309
test/make_nm.cpp
Normal file
File diff suppressed because it is too large
Load diff
105
test/misc.cpp
Normal file
105
test/misc.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <xbyak/xbyak.h>
|
||||
#include <cybozu/inttype.hpp>
|
||||
#include <cybozu/test.hpp>
|
||||
|
||||
using namespace Xbyak;
|
||||
|
||||
CYBOZU_TEST_AUTO(setSize)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code() : Xbyak::CodeGenerator(4096)
|
||||
{
|
||||
setSize(4095);
|
||||
db(1);
|
||||
size_t size = getSize();
|
||||
CYBOZU_TEST_EQUAL(size, 4096u);
|
||||
CYBOZU_TEST_NO_EXCEPTION(setSize(size));
|
||||
CYBOZU_TEST_EXCEPTION(db(1), Xbyak::Error);
|
||||
}
|
||||
} code;
|
||||
}
|
||||
|
||||
CYBOZU_TEST_AUTO(compOperand)
|
||||
{
|
||||
using namespace Xbyak::util;
|
||||
CYBOZU_TEST_ASSERT(eax == eax);
|
||||
CYBOZU_TEST_ASSERT(ecx != xmm0);
|
||||
CYBOZU_TEST_ASSERT(ptr[eax] == ptr[eax]);
|
||||
CYBOZU_TEST_ASSERT(dword[eax] != ptr[eax]);
|
||||
CYBOZU_TEST_ASSERT(ptr[eax] != ptr[eax+3]);
|
||||
}
|
||||
|
||||
CYBOZU_TEST_AUTO(mov_const)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code()
|
||||
{
|
||||
const struct {
|
||||
uint64_t v;
|
||||
int bit;
|
||||
bool error;
|
||||
} tbl[] = {
|
||||
{ uint64_t(-1), 8, false },
|
||||
{ 0x12, 8, false },
|
||||
{ 0x80, 8, false },
|
||||
{ 0xff, 8, false },
|
||||
{ 0x100, 8, true },
|
||||
|
||||
{ 1, 16, false },
|
||||
{ uint64_t(-1), 16, false },
|
||||
{ 0x7fff, 16, false },
|
||||
{ 0xffff, 16, false },
|
||||
{ 0x10000, 16, true },
|
||||
|
||||
{ uint64_t(-1), 32, false },
|
||||
{ 0x7fffffff, 32, false },
|
||||
{ uint64_t(-0x7fffffff), 32, false },
|
||||
{ 0xffffffff, 32, false },
|
||||
{ 0x100000000ull, 32, true },
|
||||
|
||||
#ifdef XBYAK64
|
||||
{ uint64_t(-1), 64, false },
|
||||
{ 0x7fffffff, 64, false },
|
||||
{ 0xffffffffffffffffull, 64, false },
|
||||
{ 0x80000000, 64, true },
|
||||
{ 0xffffffff, 64, true },
|
||||
#endif
|
||||
};
|
||||
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
|
||||
const int bit = tbl[i].bit;
|
||||
const uint64_t v = tbl[i].v;
|
||||
const Xbyak::AddressFrame& af = bit == 8 ? byte : bit == 16 ? word : bit == 32 ? dword : qword;
|
||||
if (tbl[i].error) {
|
||||
CYBOZU_TEST_EXCEPTION(mov(af[eax], v), Xbyak::Error);
|
||||
} else {
|
||||
CYBOZU_TEST_NO_EXCEPTION(mov(af[eax], v));
|
||||
}
|
||||
}
|
||||
}
|
||||
} code;
|
||||
}
|
||||
|
||||
CYBOZU_TEST_AUTO(align)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code()
|
||||
{
|
||||
const size_t alignSize = 16;
|
||||
for (int padding = 0; padding < 20; padding++) {
|
||||
for (int i = 0; i < padding; i++) {
|
||||
db(1);
|
||||
}
|
||||
align(alignSize);
|
||||
CYBOZU_TEST_EQUAL(size_t(getCurr()) % alignSize, 0u);
|
||||
}
|
||||
align(alignSize);
|
||||
const uint8 *p = getCurr();
|
||||
// do nothing if aligned
|
||||
align(alignSize);
|
||||
CYBOZU_TEST_EQUAL(p, getCurr());
|
||||
}
|
||||
} c;
|
||||
}
|
||||
37
test/mprotect_test.cpp
Normal file
37
test/mprotect_test.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code(int x)
|
||||
{
|
||||
mov(eax, x);
|
||||
ret();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
try
|
||||
{
|
||||
#ifdef XBYAK_USE_MMAP_ALLOCATOR
|
||||
puts("use Allocator with mmap");
|
||||
#else
|
||||
puts("use Allocator with posix_memalign");
|
||||
#endif
|
||||
const int N = 70000;
|
||||
std::vector<Code*> v(N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
v[i] = new Code(i);
|
||||
}
|
||||
long long sum = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
sum += v[i]->getCode<int (*)()>()();
|
||||
}
|
||||
for (int i = 0; i < N; i++) {
|
||||
delete v[i];
|
||||
}
|
||||
printf("sum=%lld\n", sum);
|
||||
} catch (std::exception& e) {
|
||||
printf("ERR %s\n", e.what());
|
||||
}
|
||||
51
test/nm_frame.cpp
Normal file
51
test/nm_frame.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdio.h>
|
||||
#define XBYAK_ENABLE_OMITTED_OPERAND
|
||||
#include "xbyak/xbyak.h"
|
||||
|
||||
using namespace Xbyak;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4245)
|
||||
#endif
|
||||
class Sample : public CodeGenerator {
|
||||
void operator=(const Sample&);
|
||||
public:
|
||||
#include "nm.cpp"
|
||||
};
|
||||
|
||||
#define _STR(x) #x
|
||||
#define TEST(syntax) err = true; try { syntax; err = false; } catch (Xbyak::Error) { } catch (...) { } if (!err) printf("should be err:%s;\n", _STR(syntax))
|
||||
|
||||
class ErrorSample : public CodeGenerator {
|
||||
void operator=(const ErrorSample&);
|
||||
public:
|
||||
void gen()
|
||||
{
|
||||
bool err;
|
||||
TEST(mov(ptr[eax],1));
|
||||
TEST(test(ptr[eax],1));
|
||||
TEST(adc(ptr[eax],1));
|
||||
TEST(setz(eax));
|
||||
}
|
||||
};
|
||||
int main()
|
||||
try
|
||||
{
|
||||
size_t size = sizeof(Xbyak::Operand);
|
||||
if (size != 4) {
|
||||
printf("sizeof Operand %d\n", (int)size);
|
||||
}
|
||||
try {
|
||||
Sample s;
|
||||
s.gen();
|
||||
} catch (std::exception& e) {
|
||||
printf("ERR:%s\n", e.what());
|
||||
} catch (...) {
|
||||
printf("unknown error\n");
|
||||
}
|
||||
ErrorSample es;
|
||||
es.gen();
|
||||
} catch (std::exception& e) {
|
||||
printf("err %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
45
test/normalize_prefix.cpp
Normal file
45
test/normalize_prefix.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
normalize prefix
|
||||
*/
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <memory.h>
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
std::string normalize(const std::string& line)
|
||||
{
|
||||
static const char tbl[][3] = { "66", "67", "F2", "F3" };
|
||||
size_t tblNum = sizeof(tbl) / sizeof(tbl[0]);
|
||||
typedef std::set<std::string> StringSet;
|
||||
StringSet suf;
|
||||
|
||||
size_t pos = 0;
|
||||
for (; pos < line.size(); pos += 2) {
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < tblNum; i++) {
|
||||
if (::memcmp(&line[pos], tbl[i], 2) == 0) {
|
||||
found = true;
|
||||
suf.insert(tbl[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) break;
|
||||
}
|
||||
std::string ret;
|
||||
for (StringSet::const_iterator i = suf.begin(), e = suf.end(); i != e; ++i) {
|
||||
ret += *i;
|
||||
}
|
||||
ret += &line[pos];
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(std::cin, line)) {
|
||||
std::string normalizedLine = normalize(line);
|
||||
std::cout << normalizedLine << '\n';//std::endl;
|
||||
}
|
||||
}
|
||||
6
test/readme.txt
Normal file
6
test/readme.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
test script on Windows
|
||||
|
||||
this test requires nasm.exe, yasm.exe, cl.exe, awk, diff
|
||||
|
||||
test_all ; for all tests
|
||||
88
test/rip-label-imm.cpp
Normal file
88
test/rip-label-imm.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
/*
|
||||
dump of vc
|
||||
|
||||
00000000003A0000 F3 0F C2 05 F1 00 00 00 00 cmpeqss xmm0,dword ptr [3A00FAh]
|
||||
00000000003A0009 F7 05 E7 00 00 00 21 00 00 00 test dword ptr [3A00FAh],21h
|
||||
00000000003A0013 0F BA 25 DF 00 00 00 03 bt dword ptr [3A00FAh],3
|
||||
00000000003A001B C4 E3 79 0D 05 D5 00 00 00 03 vblendpd xmm0,xmm0,xmmword ptr [3A00FAh],3
|
||||
00000000003A0025 C4 E3 79 0F 05 CB 00 00 00 04 vpalignr xmm0,xmm0,xmmword ptr [3A00FAh],4
|
||||
00000000003A002F C4 E3 7D 19 1D C1 00 00 00 0C vextractf128 xmmword ptr [3A00FAh],ymm3,0Ch
|
||||
00000000003A0039 C4 E3 75 46 05 B7 00 00 00 0D vperm2i128 ymm0,ymm1,ymmword ptr [3A00FAh],0Dh
|
||||
00000000003A0043 C4 E3 79 1D 15 AD 00 00 00 2C vcvtps2ph mmword ptr [3A00FAh],xmm2,2Ch
|
||||
00000000003A004D C7 05 A3 00 00 00 34 12 00 00 mov dword ptr [3A00FAh],1234h
|
||||
00000000003A0057 C1 25 9C 00 00 00 03 shl dword ptr [3A00FAh],3
|
||||
00000000003A005E D1 2D 96 00 00 00 shr dword ptr [3A00FAh],1
|
||||
00000000003A0064 48 0F A4 05 8D 00 00 00 03 shld qword ptr [3A00FAh],rax,3
|
||||
00000000003A006D 48 6B 05 85 00 00 00 15 imul rax,qword ptr [3A00FAh],15h
|
||||
00000000003A0075 C4 E3 FB F0 05 7B 00 00 00 15 rorx rax,qword ptr [3A00FAh],15h
|
||||
00000000003A007F F7 05 71 00 00 00 05 00 00 00 test dword ptr [3A00FAh],5
|
||||
00000000003A0089 66 48 0F 3A 16 05 66 00 00 00 03 pextrq qword ptr [3A00FAh],xmm0,3
|
||||
00000000003A0094 66 48 0F 3A 22 15 5B 00 00 00 05 pinsrq xmm2,qword ptr [3A00FAh],5
|
||||
00000000003A009F 66 0F 3A 15 0D 51 00 00 00 04 pextrw word ptr [3A00FAh],xmm1,4
|
||||
00000000003A00A9 81 15 47 00 00 00 45 23 01 00 adc dword ptr [3A00FAh],12345h
|
||||
00000000003A00B3 0F BA 25 3F 00 00 00 34 bt dword ptr [3A00FAh],34h
|
||||
00000000003A00BB 66 0F BA 3D 36 00 00 00 34 btc word ptr [3A00FAh],34h
|
||||
00000000003A00C4 0F BA 35 2E 00 00 00 34 btr dword ptr [3A00FAh],34h
|
||||
00000000003A00CC C1 15 27 00 00 00 04 rcl dword ptr [3A00FAh],4
|
||||
00000000003A00D3 48 0F A4 05 1E 00 00 00 04 shld qword ptr [3A00FAh],rax,4
|
||||
00000000003A00DC 0F 3A 0F 05 15 00 00 00 04 palignr mm0,mmword ptr [3A00FAh],4
|
||||
00000000003A00E5 66 0F 3A DF 1D 0B 00 00 00 04 aeskeygenassist xmm3,xmmword ptr [3A00FAh],4
|
||||
00000000003A00EF C4 E3 79 60 15 01 00 00 00 07 vpcmpestrm xmm2,xmmword ptr [3A00FAh],7
|
||||
00000000003A00F9 C3 ret
|
||||
00000000003A00FA F0 DE BC 9A 78 56 34 12
|
||||
*/
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code()
|
||||
{
|
||||
Xbyak::Label label;
|
||||
cmpss(xmm0, ptr[rip + label], 0);
|
||||
test(dword[rip + label], 33);
|
||||
bt(dword[rip + label ], 3);
|
||||
vblendpd(xmm0, dword[rip + label], 3);
|
||||
vpalignr(xmm0, qword[rip + label], 4);
|
||||
vextractf128(dword[rip + label], ymm3, 12);
|
||||
vperm2i128(ymm0, ymm1, qword[rip + label], 13);
|
||||
vcvtps2ph(ptr[rip + label], xmm2, 44);
|
||||
mov(dword[rip + label], 0x1234);
|
||||
shl(dword[rip + label], 3);
|
||||
shr(dword[rip + label], 1);
|
||||
shld(qword[rip + label], rax, 3);
|
||||
imul(rax, qword[rip + label], 21);
|
||||
rorx(rax, qword[rip + label], 21);
|
||||
test(dword[rip + label], 5);
|
||||
pextrq(ptr[rip + label], xmm0, 3);
|
||||
pinsrq(xmm2, ptr[rip + label], 5);
|
||||
pextrw(ptr[rip + label], xmm1, 4);
|
||||
adc(dword[rip + label], 0x12345);
|
||||
bt(byte[rip + label], 0x34);
|
||||
btc(word[rip + label], 0x34);
|
||||
btr(dword[rip + label], 0x34);
|
||||
rcl(dword[rip + label], 4);
|
||||
shld(qword[rip + label], rax, 4);
|
||||
palignr(mm0, ptr[rip + label], 4);
|
||||
aeskeygenassist(xmm3, ptr[rip + label], 4);
|
||||
vpcmpestrm(xmm2, ptr[rip + label], 7);
|
||||
ret();
|
||||
L(label);
|
||||
dq(0x123456789abcdef0ull);
|
||||
};
|
||||
};
|
||||
|
||||
void dump(const unsigned char *p, size_t n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
printf("%02x ", p[i]);
|
||||
if ((i % 16) == 15) putchar('\n');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Code code;
|
||||
void (*f)() = code.getCode<void (*)()>();
|
||||
dump(code.getCode(), code.getSize());
|
||||
f();
|
||||
}
|
||||
338
test/sf_test.cpp
Normal file
338
test/sf_test.cpp
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak_util.h>
|
||||
|
||||
#ifdef XBYAK32
|
||||
#error "this sample is for only 64-bit mode"
|
||||
#endif
|
||||
|
||||
using namespace Xbyak::util;
|
||||
|
||||
struct Code : public Xbyak::CodeGenerator {
|
||||
void gen1()
|
||||
{
|
||||
StackFrame sf(this, 1);
|
||||
mov(rax, sf.p[0]);
|
||||
}
|
||||
void gen2()
|
||||
{
|
||||
StackFrame sf(this, 2);
|
||||
lea(rax, ptr [sf.p[0] + sf.p[1]]);
|
||||
}
|
||||
void gen3()
|
||||
{
|
||||
StackFrame sf(this, 3);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
void gen4()
|
||||
{
|
||||
StackFrame sf(this, 4);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen5()
|
||||
{
|
||||
StackFrame sf(this, 4, UseRCX);
|
||||
xor_(rcx, rcx);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen6()
|
||||
{
|
||||
StackFrame sf(this, 4, UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen7()
|
||||
{
|
||||
StackFrame sf(this, 3, UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
|
||||
void gen8()
|
||||
{
|
||||
StackFrame sf(this, 3, 3 | UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(sf.t[0], 1);
|
||||
mov(sf.t[1], 2);
|
||||
mov(sf.t[2], 3);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
|
||||
void gen9()
|
||||
{
|
||||
StackFrame sf(this, 3, 3 | UseRCX | UseRDX, 32);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(sf.t[0], 1);
|
||||
mov(sf.t[1], 2);
|
||||
mov(sf.t[2], 3);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
mov(ptr [rsp + 8 * 0], rax);
|
||||
mov(ptr [rsp + 8 * 1], rax);
|
||||
mov(ptr [rsp + 8 * 2], rax);
|
||||
mov(ptr [rsp + 8 * 3], rax);
|
||||
}
|
||||
|
||||
void gen10()
|
||||
{
|
||||
StackFrame sf(this, 4, 8 | UseRCX | UseRDX, 32);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
mov(sf.t[i], i);
|
||||
}
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
mov(ptr [rsp + 8 * 0], rax);
|
||||
mov(ptr [rsp + 8 * 1], rax);
|
||||
mov(ptr [rsp + 8 * 2], rax);
|
||||
mov(ptr [rsp + 8 * 3], rax);
|
||||
}
|
||||
|
||||
void gen11()
|
||||
{
|
||||
StackFrame sf(this, 0, UseRCX);
|
||||
xor_(rcx, rcx);
|
||||
mov(rax, 3);
|
||||
}
|
||||
|
||||
void gen12()
|
||||
{
|
||||
StackFrame sf(this, 4, UseRDX);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
};
|
||||
|
||||
struct Code2 : Xbyak::CodeGenerator {
|
||||
Code2()
|
||||
: Xbyak::CodeGenerator(4096 * 32)
|
||||
{
|
||||
}
|
||||
void gen(int pNum, int tNum, int stackSizeByte)
|
||||
{
|
||||
StackFrame sf(this, pNum, tNum, stackSizeByte);
|
||||
if (tNum & UseRCX) xor_(rcx, rcx);
|
||||
if (tNum & UseRDX) xor_(rdx, rdx);
|
||||
for (int i = 0, n = tNum & ~(UseRCX | UseRDX); i < n; i++) {
|
||||
mov(sf.t[i], 5);
|
||||
}
|
||||
for (int i = 0; i < stackSizeByte; i++) {
|
||||
mov(byte [rsp + i], 0);
|
||||
}
|
||||
mov(rax, 1);
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
add(rax, sf.p[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int errNum = 0;
|
||||
void check(int x, int y)
|
||||
{
|
||||
if (x != y) {
|
||||
printf("err x=%d, y=%d\n", x, y);
|
||||
errNum++;
|
||||
}
|
||||
}
|
||||
|
||||
void verify(const Xbyak::uint8 *f, int pNum)
|
||||
{
|
||||
switch (pNum) {
|
||||
case 0:
|
||||
check(1, Xbyak::CastTo<int (*)()>(f)());
|
||||
return;
|
||||
case 1:
|
||||
check(11, Xbyak::CastTo<int (*)(int)>(f)(10));
|
||||
return;
|
||||
case 2:
|
||||
check(111, Xbyak::CastTo<int (*)(int, int)>(f)(10, 100));
|
||||
return;
|
||||
case 3:
|
||||
check(1111, Xbyak::CastTo<int (*)(int, int, int)>(f)(10, 100, 1000));
|
||||
return;
|
||||
case 4:
|
||||
check(11111, Xbyak::CastTo<int (*)(int, int, int, int)>(f)(10, 100, 1000, 10000));
|
||||
return;
|
||||
default:
|
||||
printf("ERR pNum=%d\n", pNum);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void testAll()
|
||||
{
|
||||
Code2 code;
|
||||
for (int stackSize = 0; stackSize < 32; stackSize += 7) {
|
||||
for (int pNum = 0; pNum < 4; pNum++) {
|
||||
for (int mode = 0; mode < 4; mode++) {
|
||||
int maxNum = 0;
|
||||
int opt = 0;
|
||||
if (mode == 0) {
|
||||
maxNum = 10;
|
||||
} else if (mode == 1) {
|
||||
maxNum = 9;
|
||||
opt = UseRCX;
|
||||
} else if (mode == 2) {
|
||||
maxNum = 9;
|
||||
opt = UseRDX;
|
||||
} else {
|
||||
maxNum = 8;
|
||||
opt = UseRCX | UseRDX;
|
||||
}
|
||||
for (int tNum = 0; tNum < maxNum; tNum++) {
|
||||
// printf("pNum=%d, tNum=%d, stackSize=%d\n", pNum, tNum | opt, stackSize);
|
||||
const Xbyak::uint8 *f = code.getCurr();
|
||||
code.gen(pNum, tNum | opt, stackSize);
|
||||
verify(f, pNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testPartial()
|
||||
{
|
||||
Code code;
|
||||
int (*f1)(int) = code.getCurr<int (*)(int)>();
|
||||
code.gen1();
|
||||
check(5, f1(5));
|
||||
|
||||
int (*f2)(int, int) = code.getCurr<int (*)(int, int)>();
|
||||
code.gen2();
|
||||
check(9, f2(3, 6));
|
||||
|
||||
int (*f3)(int, int, int) = code.getCurr<int (*)(int, int, int)>();
|
||||
code.gen3();
|
||||
check(14, f3(1, 4, 9));
|
||||
|
||||
int (*f4)(int, int, int, int) = code.getCurr<int (*)(int, int, int, int)>();
|
||||
code.gen4();
|
||||
check(30, f4(1, 4, 9, 16));
|
||||
|
||||
int (*f5)(int, int, int, int) = code.getCurr<int (*)(int, int, int, int)>();
|
||||
code.gen5();
|
||||
check(23, f5(2, 5, 7, 9));
|
||||
|
||||
int (*f6)(int, int, int, int) = code.getCurr<int (*)(int, int, int, int)>();
|
||||
code.gen6();
|
||||
check(18, f6(3, 4, 5, 6));
|
||||
|
||||
int (*f7)(int, int, int) = code.getCurr<int (*)(int, int, int)>();
|
||||
code.gen7();
|
||||
check(12, f7(3, 4, 5));
|
||||
|
||||
int (*f8)(int, int, int) = code.getCurr<int (*)(int, int, int)>();
|
||||
code.gen8();
|
||||
check(23, f8(5, 8, 10));
|
||||
|
||||
int (*f9)(int, int, int) = code.getCurr<int (*)(int, int, int)>();
|
||||
code.gen9();
|
||||
check(60, f9(10, 20, 30));
|
||||
|
||||
int (*f10)(int, int, int, int) = code.getCurr<int (*)(int, int, int, int)>();
|
||||
code.gen10();
|
||||
check(100, f10(10, 20, 30, 40));
|
||||
|
||||
int (*f11)() = code.getCurr<int (*)()>();
|
||||
code.gen11();
|
||||
check(3, f11());
|
||||
|
||||
int (*f12)(int, int, int, int) = code.getCurr<int (*)(int, int, int, int)>();
|
||||
code.gen12();
|
||||
check(24, f12(3, 5, 7, 9));
|
||||
}
|
||||
|
||||
void put(const Xbyak::util::Pack& p)
|
||||
{
|
||||
for (size_t i = 0, n = p.size(); i < n; i++) {
|
||||
printf("%s ", p[i].toString());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void verifyPack(const Xbyak::util::Pack& p, const int *tbl, size_t tblNum)
|
||||
{
|
||||
for (size_t i = 0; i < tblNum; i++) {
|
||||
check(p[i].getIdx(), tbl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void testPack()
|
||||
{
|
||||
const int N = 10;
|
||||
Xbyak::Reg64 regTbl[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
regTbl[i] = Xbyak::Reg64(i);
|
||||
}
|
||||
Xbyak::util::Pack p(regTbl, N);
|
||||
const struct {
|
||||
int pos;
|
||||
int num;
|
||||
int tbl[10];
|
||||
} tbl[] = {
|
||||
{ 0, 10, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 1, 9, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 2, 8, { 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 3, 7, { 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 4, 6, { 4, 5, 6, 7, 8, 9 } },
|
||||
{ 5, 5, { 5, 6, 7, 8, 9 } },
|
||||
{ 6, 4, { 6, 7, 8, 9 } },
|
||||
{ 7, 3, { 7, 8, 9 } },
|
||||
{ 8, 2, { 8, 9 } },
|
||||
{ 9, 1, { 9 } },
|
||||
{ 3, 5, { 3, 4, 5, 6, 7 } },
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(tbl) / sizeof(*tbl); i++) {
|
||||
const int pos = tbl[i].pos;
|
||||
const int num = tbl[i].num;
|
||||
verifyPack(p.sub(pos, num), tbl[i].tbl, num);
|
||||
if (pos + num == N) {
|
||||
verifyPack(p.sub(pos), tbl[i].tbl, num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
try
|
||||
{
|
||||
testAll();
|
||||
|
||||
testPartial();
|
||||
testPack();
|
||||
printf("errNum=%d\n", errNum);
|
||||
} catch (std::exception& e) {
|
||||
printf("err %s\n", e.what());
|
||||
return 1;
|
||||
} catch (...) {
|
||||
puts("ERR");
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIN
test/state.pptx
Normal file
BIN
test/state.pptx
Normal file
Binary file not shown.
37
test/test_address.bat
Normal file
37
test/test_address.bat
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
@echo off
|
||||
set FILTER=cat
|
||||
if /i "%1"=="64" (
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
) else (
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
)
|
||||
|
||||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
|
||||
if /i "%1"=="64" (
|
||||
call :sub 1
|
||||
call :sub 2
|
||||
) else (
|
||||
call :sub 1
|
||||
)
|
||||
goto end
|
||||
|
||||
:sub
|
||||
echo cl address.cpp %OPT% %OPT2%
|
||||
cl address.cpp %OPT% %OPT2%
|
||||
address %1% > a.asm
|
||||
echo nasm -f %OPT3% -l a.lst a.asm
|
||||
nasm -f %OPT3% -l a.lst a.asm
|
||||
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
echo address %1% jit > nm.cpp
|
||||
address %1% jit > nm.cpp
|
||||
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||
nm_frame > x.lst
|
||||
diff x.lst ok.lst
|
||||
wc x.lst
|
||||
|
||||
:end
|
||||
42
test/test_address.sh
Executable file
42
test/test_address.sh
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh
|
||||
|
||||
FILTER="grep -v warning"
|
||||
|
||||
sub()
|
||||
{
|
||||
|
||||
CFLAGS="-Wall -fno-operator-names -I../ $OPT2"
|
||||
echo "compile address.cpp"
|
||||
g++ $CFLAGS address.cpp -o address
|
||||
|
||||
./address $1 > a.asm
|
||||
echo "asm"
|
||||
$EXE -f$OPT3 a.asm -l a.lst
|
||||
awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = "" }} ' < a.lst | $FILTER > ok.lst
|
||||
|
||||
echo "xbyak"
|
||||
./address $1 jit > nm.cpp
|
||||
echo "compile nm_frame.cpp"
|
||||
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame
|
||||
./nm_frame > x.lst
|
||||
diff ok.lst x.lst && echo "ok"
|
||||
wc x.lst
|
||||
|
||||
}
|
||||
|
||||
if [ "$1" = "64" ]; then
|
||||
echo "nasm(64bit)"
|
||||
EXE=nasm
|
||||
OPT2=-DXBYAK64
|
||||
OPT3=win64
|
||||
|
||||
sub 1
|
||||
sub 2
|
||||
else
|
||||
echo "nasm(32bit)"
|
||||
EXE=nasm
|
||||
OPT2=-DXBYAK32
|
||||
OPT3=win32
|
||||
sub 1
|
||||
fi
|
||||
|
||||
8
test/test_all.bat
Normal file
8
test/test_all.bat
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
@echo off
|
||||
call test_nm_all
|
||||
echo *** test addressing ***
|
||||
call test_address
|
||||
call test_address 64
|
||||
echo *** test jmp address ***
|
||||
call test_jmp
|
||||
echo *** all test end ***
|
||||
42
test/test_avx.bat
Normal file
42
test/test_avx.bat
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
@echo off
|
||||
set FILTER=cat
|
||||
set Y=0
|
||||
if /i "%1"=="Y" (
|
||||
set Y=1
|
||||
set EXE=yasm.exe
|
||||
set OPT2=-DUSE_YASM -DXBYAK32
|
||||
set OPT3=win32
|
||||
) else if /i "%1"=="64" (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else if /i "%1"=="Y64" (
|
||||
set Y=1
|
||||
set EXE=yasm.exe
|
||||
set OPT2=-DUSE_YASM -DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
)
|
||||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
||||
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
||||
make_nm > a.asm
|
||||
%EXE% -f %OPT3% -l a.lst a.asm
|
||||
rem connect "?????-" and "??"
|
||||
if /i "%Y%"=="1" (
|
||||
awk "NR > 1 {if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
) else (
|
||||
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
)
|
||||
make_nm jit > nm.cpp
|
||||
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||
nm_frame |%FILTER% > x.lst
|
||||
diff x.lst ok.lst
|
||||
wc x.lst
|
||||
44
test/test_avx.sh
Executable file
44
test/test_avx.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/tcsh
|
||||
|
||||
set FILTER="grep -v warning"
|
||||
|
||||
if ($1 == "Y") then
|
||||
echo "yasm(32bit)"
|
||||
set EXE=yasm
|
||||
set OPT2="-DUSE_YASM -DXBYAK32"
|
||||
set OPT3=win32
|
||||
else if ($1 == "64") then
|
||||
echo "nasm(64bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=./normalize_prefix
|
||||
else if ($1 == "Y64") then
|
||||
echo "yasm(64bit)"
|
||||
set EXE=yasm
|
||||
set OPT2="-DUSE_YASM -DXBYAK64"
|
||||
set OPT3=win64
|
||||
set FILTER=./normalize_prefix
|
||||
else
|
||||
echo "nasm(32bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
endif
|
||||
|
||||
set CFLAGS="-Wall -fno-operator-names -I../ $OPT2 -DUSE_AVX"
|
||||
echo "compile make_nm.cpp"
|
||||
g++ $CFLAGS make_nm.cpp -o make_nm
|
||||
|
||||
./make_nm > a.asm
|
||||
echo "asm"
|
||||
$EXE -f$OPT3 a.asm -l a.lst
|
||||
awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = "" }} ' < a.lst | $FILTER > ok.lst
|
||||
|
||||
echo "xbyak"
|
||||
./make_nm jit > nm.cpp
|
||||
echo "compile nm_frame.cpp"
|
||||
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame
|
||||
./nm_frame | $FILTER > x.lst
|
||||
diff ok.lst x.lst && echo "ok"
|
||||
exit 0
|
||||
31
test/test_avx512.bat
Normal file
31
test/test_avx512.bat
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
@echo off
|
||||
set FILTER=cat
|
||||
set Y=0
|
||||
if /i "%1"=="min" (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK64 -DMIN_TEST
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else if /i "%1"=="64" (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
)
|
||||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
echo cl -I../ make_512.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
||||
cl -I../ make_512.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
||||
make_512 > a.asm
|
||||
%EXE% -f %OPT3% -l a.lst a.asm
|
||||
rem connect "?????-" and "??"
|
||||
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
make_512 jit > nm.cpp
|
||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2% /DXBYAK_AVX512
|
||||
nm_frame |%FILTER% > x.lst
|
||||
diff x.lst ok.lst
|
||||
wc x.lst
|
||||
33
test/test_avx512.sh
Executable file
33
test/test_avx512.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/tcsh
|
||||
|
||||
set FILTER="grep -v warning"
|
||||
|
||||
if ($1 == "64") then
|
||||
echo "nasm(64bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=./normalize_prefix
|
||||
else
|
||||
echo "nasm(32bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
endif
|
||||
|
||||
set CFLAGS="-Wall -fno-operator-names -I../ $OPT2 -DUSE_AVX512"
|
||||
echo "compile make_512.cpp"
|
||||
g++ $CFLAGS make_512.cpp -o make_512
|
||||
|
||||
./make_512 > a.asm
|
||||
echo "asm"
|
||||
$EXE -f$OPT3 a.asm -l a.lst
|
||||
awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = "" }} ' < a.lst | $FILTER > ok.lst
|
||||
|
||||
echo "xbyak"
|
||||
./make_512 jit > nm.cpp
|
||||
echo "compile nm_frame.cpp"
|
||||
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame -DXBYAK_AVX512
|
||||
./nm_frame | $FILTER > x.lst
|
||||
diff ok.lst x.lst && echo "ok"
|
||||
exit 0
|
||||
9
test/test_avx_all.bat
Normal file
9
test/test_avx_all.bat
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
@echo off
|
||||
echo ** nasm-avx(32bit) ***
|
||||
call test_avx
|
||||
echo ** nasm-avx(64bit) ***
|
||||
call test_avx 64
|
||||
echo ** yasm-avx(32bit) ***
|
||||
call test_avx Y
|
||||
echo ** yasm-avx(64bit) ***
|
||||
call test_avx Y64
|
||||
4
test/test_jmp.bat
Normal file
4
test/test_jmp.bat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
cl -I../ -I./ -DXBYAK_TEST jmp.cpp %OPT% /Od /Zi
|
||||
jmp
|
||||
4
test/test_misc.bat
Normal file
4
test/test_misc.bat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
cl -I../ -I./ -DXBYAK_TEST misc.cpp %OPT% /Od /Zi
|
||||
misc
|
||||
78
test/test_mmx.cpp
Normal file
78
test/test_mmx.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
#pragma warning(disable:4514)
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../include.mie/mie_thread.h"
|
||||
#include "xbyak/xbyak.h"
|
||||
|
||||
class WriteMMX : public Xbyak::CodeGenerator {
|
||||
public:
|
||||
WriteMMX()
|
||||
{
|
||||
#ifdef XBYAK32
|
||||
mov(ecx, ptr [esp + 4]);
|
||||
#endif
|
||||
movd(mm0, ecx);
|
||||
ret();
|
||||
}
|
||||
void (*set() const)(int x) { return (void (*)(int x))getCode(); }
|
||||
};
|
||||
|
||||
class ReadMMX : public Xbyak::CodeGenerator {
|
||||
public:
|
||||
ReadMMX()
|
||||
{
|
||||
movd(eax, mm0);
|
||||
ret();
|
||||
}
|
||||
int (*get() const)() { return (int (*)())getCode(); }
|
||||
};
|
||||
|
||||
class Test : public MIE::ThreadBase<Test> {
|
||||
int n_;
|
||||
public:
|
||||
Test(int n)
|
||||
: n_(n)
|
||||
{
|
||||
}
|
||||
void threadEntry()
|
||||
{
|
||||
printf("n=%d\n", n_);
|
||||
WriteMMX w;
|
||||
w.set()(n_);
|
||||
ReadMMX r;
|
||||
for (;;) {
|
||||
int b = r.get()();
|
||||
printf("b=%d\n", b);
|
||||
if (b != n_) {
|
||||
printf("mm0 has changed!\n");
|
||||
}
|
||||
MIE::MIE_Sleep(1000);
|
||||
}
|
||||
}
|
||||
void stopThread() { }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef XBYAK32
|
||||
puts("32bit");
|
||||
#else
|
||||
puts("64bit");
|
||||
#endif
|
||||
try {
|
||||
int n = atoi(argc == 1 ? "1223" : argv[1]);
|
||||
Test test0(n), test1(n + 1);
|
||||
test0.beginThread();
|
||||
test1.beginThread();
|
||||
|
||||
test0.joinThread();
|
||||
test1.joinThread();
|
||||
} catch (std::exception& e) {
|
||||
printf("ERR:%s\n", e.what());
|
||||
} catch (...) {
|
||||
printf("unknown error\n");
|
||||
}
|
||||
}
|
||||
43
test/test_nm.bat
Normal file
43
test/test_nm.bat
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
@echo off
|
||||
set FILTER=cat
|
||||
set Y=0
|
||||
if /i "%1"=="Y" (
|
||||
set Y=1
|
||||
set EXE=yasm.exe
|
||||
set OPT2=-DUSE_YASM -DXBYAK32
|
||||
set OPT3=win32
|
||||
) else if /i "%1"=="64" (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else if /i "%1"=="Y64" (
|
||||
set Y=1
|
||||
set EXE=yasm.exe
|
||||
set OPT2=-DUSE_YASM -DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=normalize_prefix
|
||||
) else (
|
||||
set EXE=nasm.exe
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
)
|
||||
call set_opt
|
||||
bmake -f Makefile.win all
|
||||
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
||||
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
||||
make_nm > a.asm
|
||||
rm a.lst
|
||||
echo %EXE% -f %OPT3% -l a.lst a.asm
|
||||
%EXE% -f %OPT3% -l a.lst a.asm
|
||||
rem connect "?????-" and "??"
|
||||
if /i "%Y%"=="1" (
|
||||
awk "NR > 1 {if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
) else (
|
||||
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||
)
|
||||
make_nm jit > nm.cpp
|
||||
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||
nm_frame |%FILTER% > x.lst
|
||||
diff x.lst ok.lst
|
||||
wc x.lst
|
||||
44
test/test_nm.sh
Executable file
44
test/test_nm.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/tcsh
|
||||
|
||||
set FILTER=cat
|
||||
|
||||
if ($1 == "Y") then
|
||||
echo "yasm(32bit)"
|
||||
set EXE=yasm
|
||||
set OPT2="-DUSE_YASM -DXBYAK32"
|
||||
set OPT3=win32
|
||||
else if ($1 == "64") then
|
||||
echo "nasm(64bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
set FILTER=./normalize_prefix
|
||||
else if ($1 == "Y64") then
|
||||
echo "yasm(64bit)"
|
||||
set EXE=yasm
|
||||
set OPT2="-DUSE_YASM -DXBYAK64"
|
||||
set OPT3=win64
|
||||
set FILTER=./normalize_prefix
|
||||
else
|
||||
echo "nasm(32bit)"
|
||||
set EXE=nasm
|
||||
set OPT2=-DXBYAK32
|
||||
set OPT3=win32
|
||||
endif
|
||||
|
||||
set CFLAGS="-Wall -fno-operator-names -I../ $OPT2"
|
||||
echo "compile make_nm.cpp"
|
||||
g++ $CFLAGS make_nm.cpp -o make_nm
|
||||
|
||||
./make_nm > a.asm
|
||||
echo "asm"
|
||||
$EXE -f$OPT3 a.asm -l a.lst
|
||||
awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = "" }} ' < a.lst | $FILTER > ok.lst
|
||||
|
||||
echo "xbyak"
|
||||
./make_nm jit > nm.cpp
|
||||
echo "compile nm_frame.cpp"
|
||||
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame
|
||||
./nm_frame | $FILTER > x.lst
|
||||
diff ok.lst x.lst && echo "ok"
|
||||
exit 0
|
||||
11
test/test_nm_all.bat
Normal file
11
test/test_nm_all.bat
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
@echo off
|
||||
echo *** nasm(32bit) ***
|
||||
call test_nm
|
||||
echo *** yasm(32bit) ***
|
||||
call test_nm Y
|
||||
echo *** nasm(64bit) ***
|
||||
call test_nm 64
|
||||
echo *** yasm(64bit) ***
|
||||
call test_nm Y64
|
||||
|
||||
call test_avx_all
|
||||
Loading…
Add table
Add a link
Reference in a new issue