-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
cmp_jmp.cpp
59 lines (52 loc) · 1.29 KB
/
cmp_jmp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <xbyak/xbyak_util.h>
#include <cybozu/benchmark.hpp>
using namespace Xbyak;
using namespace Xbyak::util;
typedef int (*funcType)(int n);
const char *g_callStr;
struct Code : Xbyak::CodeGenerator {
bool gen(int mode)
{
Xbyak::util::StackFrame sf(this, 1, UseRCX | UseRDX);
const Reg64& n = sf.p[0];
Label funcL, memL, tblL;
xor_(rax, rax);
switch (mode) {
case 0: mov(rdx, funcL); break;
case 1: mov(rdx, memL); break;
case 4: mov(rcx, tblL); break;
default: break;
}
Label lpL = L();
switch (mode) {
case 0: call(rdx); g_callStr = "call(rdx)"; break;
case 1: call(ptr[rdx]); g_callStr = "call(ptr[rdx])"; break;
case 2: call(funcL); g_callStr = "call(funcL)"; break;
case 3: call(ptr[rip + memL]); g_callStr = "call(ptr[rip + memL])"; break;
case 4: mov(rdx, ptr[rcx]); call(ptr[rdx]); g_callStr = "mov(rdx, [rdx]); call([rdx])"; break;
default : return false;
}
sub(n, 1);
jnz(lpL);
ret();
L(funcL);
add(rax, 1);
ret();
L(memL);
dq(uint64_t(funcL.getAddress()));
L(tblL);
dq(uint64_t(memL.getAddress()));
return true;
}
};
int main()
{
const int n = 1000;
for (int i = 0; i < 10; i++) {
Code c;
if (!c.gen(i)) break;
funcType f = c.getCode<funcType>();
printf("f=%25s(%d) ", g_callStr, f(n));
CYBOZU_BENCH_C("call", 10000, f, n);
}
}