080b4b3aff
4a6fac8a update version to 5.77 801cf3fd cosmetic change of getNumCores d397e824 fix number of cores that share LLC cache a669e092 support non-intel-cpu visual studio af5f422e Merge branch 'fenghaitao-guard_x86' into develop 9b98dc17 Guard x86 specific codes with "#if defined(__i386__) || defined(__x86_64__)" dd4173e1 move some member variables input private f72646a7 update version 4612528f format change 4b95e862 Merge branch 'shelleygoel-master' 4c262fa6 add functionality to get num of cores using x2APIC ID bc70e7e1 recover Xbyak::CastTo d09a230f unlink Label when LabelManager is destroyed 973e8597 update version afdb9fe9 Xbyak::CastTo is removed b011aca4 add RegRip +/- int acae93cd increase max temp regs for StackFrame ea4e3562 util::StackFrame uses push/pop instead of mov 42462ef9 use evex encoding for vpslld/vpslldq/vpsraw/...(reg, mem, imm); da9117a9 update version of readme.md d35f4fb7 fix the encoding of vinsertps for disp8N 1de435ed bf uses Label class 613922bd add Label L() for convenience 43e15583 fix typo 93579ee6 add protect-re.cpp 60004b5c fix url of protect-re.cpp 348b2709 fix typo of doc f34f6ed5 update manual 232110be update test 82b78bf0 add setProtectMode dd8b290f put warning message if pageSize != 4096 64775ca2 a little refactoring 7c3e7b85 fix wrong VSIB encoding with idx >= 16 git-subtree-dir: externals/xbyak git-subtree-split: 4a6fac8ade404f667b94170f713367fe7da2a852
190 lines
3.9 KiB
C++
190 lines
3.9 KiB
C++
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
|
#pragma warning(disable:4514)
|
|
#pragma warning(disable:4786)
|
|
#endif
|
|
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
|
|
#pragma warning(disable:4456)
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#define XBYAK_NO_OP_NAMES
|
|
#include "xbyak/xbyak.h"
|
|
|
|
class Sample : public Xbyak::CodeGenerator {
|
|
void operator=(const Sample&);
|
|
public:
|
|
Sample(void *userPtr = 0, size_t size = Xbyak::DEFAULT_MAX_CODE_SIZE) : Xbyak::CodeGenerator(size, userPtr)
|
|
{
|
|
inLocalLabel(); // use local label for multiple instance
|
|
#ifdef XBYAK32
|
|
mov(ecx, ptr [esp + 4]); // n
|
|
#elif defined(XBYAK64_GCC)
|
|
mov(ecx, edi); // n
|
|
#else
|
|
// n = ecx
|
|
#endif
|
|
xor_(eax, eax); // sum
|
|
test(ecx, ecx);
|
|
jz(".exit");
|
|
xor_(edx, edx); // i
|
|
L(".lp");
|
|
add(eax, edx);
|
|
inc(edx);
|
|
|
|
cmp(edx, ecx);
|
|
jbe(".lp"); // jmp to previous @@
|
|
L(".exit"); // <B>
|
|
ret();
|
|
outLocalLabel(); // end of local label
|
|
}
|
|
};
|
|
|
|
class AddFunc : public Xbyak::CodeGenerator {
|
|
void operator=(const AddFunc&);
|
|
public:
|
|
AddFunc(int y)
|
|
{
|
|
#ifdef XBYAK32
|
|
mov(eax, ptr [esp + 4]);
|
|
add(eax, y);
|
|
#elif defined(XBYAK64_WIN)
|
|
lea(rax, ptr [rcx + y]);
|
|
#else
|
|
lea(eax, ptr [edi + y]);
|
|
#endif
|
|
ret();
|
|
}
|
|
int (*get() const)(int) { return getCode<int(*)(int)>(); }
|
|
};
|
|
|
|
class CallAtoi : public Xbyak::CodeGenerator {
|
|
void operator=(const CallAtoi&);
|
|
public:
|
|
CallAtoi()
|
|
{
|
|
#ifdef XBYAK64
|
|
#ifdef XBYAK64_WIN
|
|
sub(rsp, 32); // return-address is destroied if 64bit debug mode
|
|
#endif
|
|
mov(rax, (size_t)atoi);
|
|
call(rax);
|
|
#ifdef XBYAK64_WIN
|
|
add(rsp, 32);
|
|
#endif
|
|
#else
|
|
mov(eax, ptr [esp + 4]);
|
|
push(eax);
|
|
#ifdef XBYAK_VARIADIC_TEMPLATE
|
|
call(atoi);
|
|
#else
|
|
call(reinterpret_cast<const void*>(atoi));
|
|
#endif
|
|
add(esp, 4);
|
|
#endif
|
|
ret();
|
|
}
|
|
int (*get() const)(const char *) { return getCode<int (*)(const char *)>(); }
|
|
};
|
|
|
|
class JmpAtoi : public Xbyak::CodeGenerator {
|
|
void operator=(const JmpAtoi&);
|
|
public:
|
|
JmpAtoi()
|
|
{
|
|
/* already pushed "456" */
|
|
#ifdef XBYAK64
|
|
mov(rax, (size_t)atoi);
|
|
jmp(rax);
|
|
#else
|
|
jmp(reinterpret_cast<const void*>(atoi));
|
|
#endif
|
|
}
|
|
int (*get() const)(const char *) { return getCode<int (*)(const char *)>(); }
|
|
};
|
|
|
|
struct Reset : public Xbyak::CodeGenerator {
|
|
void init(int n)
|
|
{
|
|
xor_(eax, eax);
|
|
mov(ecx, n);
|
|
test(ecx, ecx);
|
|
jnz("@f");
|
|
ret();
|
|
L("@@");
|
|
for (int i = 0; i < 10 - n; i++) {
|
|
add(eax, ecx);
|
|
}
|
|
sub(ecx, 1);
|
|
jnz("@b");
|
|
ret();
|
|
}
|
|
};
|
|
|
|
void testReset()
|
|
{
|
|
puts("testReset");
|
|
Reset code;
|
|
int (*f)(int) = code.getCode<int(*)(int)>();
|
|
for (int i = 0; i < 10; i++) {
|
|
code.init(i);
|
|
int v = f(i);
|
|
printf("%d %d\n", i, v);
|
|
code.reset();
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
try {
|
|
Sample s;
|
|
printf("Xbyak version=%s\n", s.getVersionString());
|
|
#ifdef XBYAK64_GCC
|
|
puts("64bit mode(gcc)");
|
|
#elif defined(XBYAK64_WIN)
|
|
puts("64bit mode(win)");
|
|
#else
|
|
puts("32bit");
|
|
#endif
|
|
int (*func)(int) = s.getCode<int (*)(int)>();
|
|
for (int i = 0; i <= 10; i++) {
|
|
printf("0 + ... + %d = %d\n", i, func(i));
|
|
}
|
|
for (int i = 0; i < 10; i++) {
|
|
AddFunc a(i);
|
|
int (*add)(int) = a.get();
|
|
int y = add(i);
|
|
printf("%d + %d = %d\n", i, i, y);
|
|
}
|
|
CallAtoi c;
|
|
printf("call atoi(\"123\") = %d\n", c.get()("123"));
|
|
JmpAtoi j;
|
|
printf("jmp atoi(\"456\") = %d\n", j.get()("456"));
|
|
{
|
|
// use memory allocated by user
|
|
using namespace Xbyak;
|
|
const size_t codeSize = 4096;
|
|
uint8 buf[codeSize + 16];
|
|
uint8 *p = CodeArray::getAlignedAddress(buf);
|
|
Sample s(p, codeSize);
|
|
if (!CodeArray::protect(p, codeSize, CodeArray::PROTECT_RWE)) {
|
|
fprintf(stderr, "can't protect\n");
|
|
return 1;
|
|
}
|
|
int (*func)(int) = s.getCode<int (*)(int)>();
|
|
const uint8 *funcp = reinterpret_cast<const uint8*>(func);
|
|
if (funcp != p) {
|
|
fprintf(stderr, "internal error %p %p\n", p, funcp);
|
|
return 1;
|
|
}
|
|
printf("0 + ... + %d = %d\n", 100, func(100));
|
|
CodeArray::protect(p, codeSize, CodeArray::PROTECT_RW);
|
|
}
|
|
puts("OK");
|
|
testReset();
|
|
} catch (std::exception& e) {
|
|
printf("ERR:%s\n", e.what());
|
|
} catch (...) {
|
|
printf("unknown error\n");
|
|
}
|
|
}
|
|
|