4#define XBYAK_NO_OP_NAMES
13 for (
int i = 0; i < n; i++) {
18void diff(
const std::string&
a,
const std::string& b)
21 if (
a.size() != b.size()) printf(
"size diff %d %d\n", (
int)
a.size(), (
int)b.size());
22 for (
size_t i = 0; i < (std::min)(
a.size(), b.size()); i++) {
24 printf(
"diff %d(%04x) %02x %02x\n", (
int)i, (
int)i, (
unsigned char)
a[i], (
unsigned char)b[i]);
29void dump(
const std::string& m)
31 printf(
"size=%d\n ", (
int)m.size());
32 for (
int i = 0; i < 16; i++) {
36 for (
int i = 0; i < 16; i++) {
40 for (
size_t i = 0; i < m.size(); i++) {
41 if ((i % 16) == 0) printf(
"%04x ", (
int)(i / 16));
42 printf(
"%02x ", (
unsigned char)m[i]);
43 if ((i % 16) == 15) putchar(
'\n');
82 TestJmp(
int offset,
bool isBack,
bool isShort,
bool useNewLabel)
116 static const struct Tbl {
123 { 0,
true,
true, { 0xeb, 0xfe }, 2 },
124 { 1,
true,
true, { 0xeb, 0xfd }, 2 },
125 { 126,
true,
true, { 0xeb, 0x80 }, 2 },
126 { 127,
true,
false, {0xe9, 0x7c, 0xff, 0xff, 0xff }, 5 },
127 { 0,
false,
true, { 0xeb, 0x00 }, 2 },
128 { 1,
false,
true, { 0xeb, 0x01 }, 2 },
129 { 127,
false,
true, { 0xeb, 0x7f }, 2 },
130 { 128,
false,
false, { 0xe9, 0x80, 0x00, 0x00, 0x00 }, 5 },
133 const Tbl *
p = &
tbl[i];
134 for (
int k = 0; k < 2; k++) {
135 TestJmp jmp(
p->offset,
p->isBack,
p->isShort, k == 0);
137 if (
p->isBack) q +=
p->offset;
148 explicit TestJmpCx(
void *
p,
bool useNewLabel)
196 "\x67\xe3\xfd\xe3\xfb", 5
198 "\xe3\xfe\x67\xe3\xfb", 5
201 for (
int j = 0;
j < 2;
j++) {
203 TestJmpCx code(
buf,
j == 0);
209 #pragma warning(disable : 4310)
234 TestJmp2(
void *
p,
bool useNewLabel)
258 Label f1, f2, f3, f4;
277 ok.resize(0x18C + 128, (
char)0x90);
278 ok[0x080] = (char)0xeb;
279 ok[0x081] = (char)0x80;
281 ok[0x101] = (char)0xe9;
282 ok[0x102] = (char)0x7c;
283 ok[0x103] = (char)0xff;
284 ok[0x104] = (char)0xff;
285 ok[0x105] = (char)0xff;
287 ok[0x106] = (char)0xeb;
288 ok[0x107] = (char)0x7f;
290 ok[0x187] = (char)0xe9;
291 ok[0x188] = (char)0x80;
292 ok[0x189] = (char)0x00;
293 ok[0x18a] = (char)0x00;
294 ok[0x18b] = (char)0x00;
295 for (
int i = 0; i < 2; i++) {
296 for (
int j = 0;
j < 2;
j++) {
299 std::string m((
const char*)c.getCode(), c.getSize());
306int add5(
int x) {
return x + 5; }
307int add2(
int x) {
return x + 2; }
323 for (
int i = 0; i < dummySize; i++) {
328 for (
int dummySize = 0; dummySize < 40000; dummySize += 10000) {
329 printf(
"dummySize=%d\n", dummySize);
332 int (*
f)() = (
int (*)())g.getCode();
346 if (size <
sizeof(
bufS)) {
347 printf(
"test use bufS(%d)\n", (
int)size);
350 if (size <
sizeof(
bufL)) {
351 printf(
"test use bufL(%d)\n", (
int)size);
354 fprintf(stderr,
"no memory %d\n", (
int)size);
365 Test4(
int size,
void *mode,
bool useNewLabel)
384 for (
int i = 0; i < 2; i++) {
385 const bool useNewLabel = i == 0;
387 Test4
fc(1024, 0, useNewLabel);
390 fm.assign((
const char*)
fc.getCode(),
fc.getSize());
391 gm.assign((
const char*)gc.getCode(), gc.getSize());
399 explicit Test5(
int size,
int count,
void *mode)
402 using namespace Xbyak;
407 for (
int i = 0; i <
count; i++) {
416 if (i ==
count / 2) {
417 jmp(
".exit", T_NEAR);
430 const int count = 50;
433 ret = ((int (*)())
fc.getCode())();
435 fm.assign((
const char*)
fc.getCode(),
fc.getSize());
438 ret = ((int (*)())gc.getCode())();
440 gm.assign((
const char*)gc.getCode(), gc.getSize());
447 for (
size_t i = 0; i <
sizeof(size_t); i++) {
448 v |= size_t(
p[i]) << (i * 8);
462 MovLabelCode(
bool grow,
bool useNewLabel)
466 const Reg64&
a = rax;
529 for (
int j = 0;
j < 2;
j++) {
530 const bool grow =
j == 0;
531 for (
int k = 0; k < 2; k++) {
532 const bool useNewLabel = k == 0;
533 MovLabelCode code(grow, useNewLabel);
534 if (grow) code.ready();
535 const uint8*
const p = code.getCode();
537 int pos =
tbl[i].pos;
559 const Reg64&
a = rax;
560 const Reg64& c = rcx;
585 int ret = code.getCode<int (*)()>()();
682 const int expectedTbl[] = {
683 2, 0, 3, 3, 5, 2, 2, 6
687 int ret = code.getCode<int (*)()>()();
700 jmp(
"start0", T_NEAR);
703 jmp(
".next", T_NEAR);
706 jmp(
".back", T_NEAR);
711 jmp(
".next", T_NEAR);
714 jmp(
".back", T_NEAR);
718 jmp(
".next", T_NEAR);
721 jmp(
".back", T_NEAR);
724 jmp(
"start1", T_NEAR);
728 jmp(
"start2", T_NEAR);
732 jmp(
"start3", T_NEAR);
739 jmp(
".back", T_NEAR);
744 jmp(
".next", T_NEAR);
747 jmp(
"start4", T_NEAR);
750 jmp(
".back", T_NEAR);
759 for (
int i = 0; i < 2; i++) {
760 const bool grow = i == 1;
761 printf(
"test6 grow=%d\n", i);
762 TestLocal code(grow);
763 if (grow) code.ready();
764 int (*
f)() = code.getCode<int (*)()>();
788 const void *
p =
a.getCode<
const void*>();
789 for (
int i = 0; i < 2; i++) {
795 int (*
f)() = b.getCode<int (*)()>();
881 for (
int i = 0; i < 2; i++) {
882 const bool grow = i == 1;
883 printf(
"testNewLabel grow=%d\n", grow);
885 if (grow) code.ready();
886 int (*
f)() = code.getCode<int (*)()>();
920 for (
int i = 0; i < 2; i++) {
921 const bool grow = i == 0;
922 printf(
"testAssign grow=%d\n", grow);
924 if (grow) code.ready();
925 int (*
f)() = code.getCode<int (*)()>();
948 Label label1, label2;
956 Label label1, label2;
1005 bool autoGrow = size != 4096;
1032 const int sizeTbl[] = {
1037 int size = sizeTbl[i];
1050 int a[] = { 1, 10 };
1051 int b[] = { 100, 1000 };
1053 Code(
const int *
a,
const int *b)
1055 Label label1, label2;
1076 int ret = code.getCode<int (*)()>()();
1103 db((
size_t)ret1234, 8);
1104 db((
size_t)ret9999, 8);
1107 int ret = code.getCode<int (*)()>()();
1126 code.getCode<void (*)()>()();
1133 static
char *
p =
buf + 4096;
1134 static
int *x0 = (
int*)
buf;
1135 static
int *x1 = x0 + 1;
1140 mov(ptr[rip + x0], eax);
1141 mov(dword[rip + x1], 456);
1142 mov(
byte[rip + 1 + x1 + 3], 99);
1147 code.getCode<void (*)()>()();
#define CYBOZU_NUM_OF_ARRAY(x)
#define CYBOZU_TEST_ASSERT(x)
#define CYBOZU_TEST_EXCEPTION(statement, Exception)
#define CYBOZU_TEST_EQUAL_POINTER(x, y)
#define CYBOZU_TEST_EQUAL(x, y)
#define CYBOZU_TEST_AUTO(name)
const uint8 * getCode() const
static bool protect(const void *addr, size_t size, bool canExec)
const uint8 * getCurr() const
void jecxz(std::string label)
void call(const Operand &op)
void xor_(const Operand &op, uint32 imm)
CodeGenerator(size_t maxSize=DEFAULT_MAX_CODE_SIZE, void *userPtr=0, Allocator *allocator=0)
void jcxz(std::string label)
void cmp(const Operand &op, uint32 imm)
void jmp(const Operand &op)
void inc(const Operand &op)
void jne(const Label &label, LabelType type=T_AUTO)
void test(const Operand &op, const Reg ®)
bool hasUndefinedLabel() const
void add(const Operand &op, uint32 imm)
void sub(const Operand &op, uint32 imm)
void je(const Label &label, LabelType type=T_AUTO)
void nop(size_t size=1, bool useMultiByteNop=true)
void jz(const Label &label, LabelType type=T_AUTO)
void mov(const Operand ®1, const Operand ®2)
void assignL(Label &dst, const Label &src)
void jnz(const Label &label, LabelType type=T_AUTO)
void L(const std::string &label)
void push(const Operand &op)
static std::string toStr(int num)
const uint8 * getAddress() const
Xbyak::uint8 bufL[4096 *32]
void dump(const std::string &m)
size_t getValue(const uint8 *p)
void putNop(Xbyak::CodeGenerator *gen, int n)
void diff(const std::string &a, const std::string &b)
Xbyak::uint8 bufS[4096 *2]
void checkAddr(const uint8 *p, size_t offset, size_t expect)
LOGGING_API void printf(Category category, const char *format,...)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
GetAddressCode2(int size)
Xbyak::uint8 * alloc(size_t size)
void free(Xbyak::uint8 *)
int type definition and macros Copyright (C) 2008 Cybozu Labs, Inc., all rights reserved.
Xbyak ; JIT assembler for x86(IA32)/x64 by C++.
void jnz(const Label &label, LabelType type=T_AUTO)