mirror of
https://github.com/herumi/xbyak
synced 2024-11-21 16:09:11 -07:00
support putL(LABEL); function
This commit is contained in:
parent
8bfefc8f1f
commit
265dfa6588
14 changed files with 181 additions and 7 deletions
|
@ -1,5 +1,5 @@
|
|||
|
||||
Xbyak 4.00 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||
Xbyak 4.02 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||
=============
|
||||
|
||||
Abstract
|
||||
|
@ -235,6 +235,7 @@ http://opensource.org/licenses/BSD-3-Clause
|
|||
|
||||
History
|
||||
-------------
|
||||
* 2013/Jun/21 ver 4.02 add putL(LABEL) function to put the address of the label
|
||||
* 2013/Jun/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm).
|
||||
support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest).
|
||||
* 2013/May/30 ver 4.00 support AVX2, VEX-encoded GPR-instructions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.01
|
||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.02
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
◎概要
|
||||
|
@ -244,6 +244,7 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
|
|||
-----------------------------------------------------------------------------
|
||||
◎履歴
|
||||
|
||||
2013/06/21 ver 4.02 LABELの指すアドレスを書き込むputL(LABEL)関数の追加。
|
||||
2013/06/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm)
|
||||
support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest)
|
||||
2013/05/30 ver 4.00 AVX2, VEX-encoded GPR-instructionをサポート
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TARGET = test quantize bf toyvm test_util memfunc static_buf
|
||||
TARGET = test quantize bf toyvm test_util memfunc static_buf jmp_table
|
||||
XBYAK_INC=../xbyak/xbyak.h
|
||||
|
||||
BOOST_EXIST=$(shell echo "\#include <boost/spirit/core.hpp>" | (gcc -E - 2>/dev/null) | grep "boost/spirit/core.hpp" >/dev/null && echo "1")
|
||||
|
@ -12,7 +12,7 @@ BIT=64
|
|||
endif
|
||||
|
||||
ifeq ($(BIT),64)
|
||||
TARGET += test64 bf64 memfunc64 test_util64 static_buf64
|
||||
TARGET += test64 bf64 memfunc64 test_util64 static_buf64 jmp_table64
|
||||
ifeq ($(BOOST_EXIST),1)
|
||||
TARGET += calc64 #calc2_64
|
||||
endif
|
||||
|
@ -26,7 +26,7 @@ all: $(TARGET)
|
|||
|
||||
CFLAGS_WARN=-Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith -pedantic
|
||||
|
||||
CFLAGS=-g -O2 -fomit-frame-pointer -DXBYAK_NO_OP_NAMES -Wall -I../ $(CFLAGS_WARN)
|
||||
CFLAGS=-g -O2 -fomit-frame-pointer -Wall -I../ $(CFLAGS_WARN)
|
||||
|
||||
test:
|
||||
$(CXX) $(CFLAGS) test0.cpp -o $@ -m32
|
||||
|
@ -66,6 +66,10 @@ static_buf:
|
|||
$(CXX) $(CFLAGS) static_buf.cpp -o $@ -m32
|
||||
static_buf64:
|
||||
$(CXX) $(CFLAGS) static_buf.cpp -o $@ -m64
|
||||
jmp_table:
|
||||
$(CXX) $(CFLAGS) jmp_table.cpp -o $@ -m32
|
||||
jmp_table64:
|
||||
$(CXX) $(CFLAGS) jmp_table.cpp -o $@ -m64
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(TARGET) *.exe
|
||||
|
@ -86,3 +90,5 @@ static_buf: static_buf.cpp $(XBYAK_INC)
|
|||
static_buf64: static_buf.cpp $(XBYAK_INC)
|
||||
test_util : test_util.cpp $(XBYAK_INC) ../xbyak/xbyak_util.h
|
||||
test_util2 : test_util.cpp $(XBYAK_INC) ../xbyak/xbyak_util.h
|
||||
jmp_table: jmp_table.cpp $(XBYAK_INC)
|
||||
jmp_table64: jmp_table.cpp $(XBYAK_INC)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4127) // for boost(constant condition)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
|
||||
enum Operand {
|
||||
|
|
132
sample/jmp_table.cpp
Normal file
132
sample/jmp_table.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
sample of move(reg, LABEL);, L(LABEL), putL(LABEL);
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
const int expectTbl[] = {
|
||||
5, 9, 12
|
||||
};
|
||||
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
explicit Code(int mode, size_t size, void *p)
|
||||
: Xbyak::CodeGenerator(size, p)
|
||||
{
|
||||
inLocalLabel();
|
||||
#ifdef XBYAK64
|
||||
const Xbyak::Reg64& a = rax;
|
||||
const Xbyak::Reg64& c = rcx;
|
||||
#ifdef XBYAK64_WIN
|
||||
mov(rax, rcx);
|
||||
#else
|
||||
mov(rax, rdi);
|
||||
#endif
|
||||
#else
|
||||
const Xbyak::Reg32& a = eax;
|
||||
const Xbyak::Reg32& c = ecx;
|
||||
mov(a, ptr [esp + 4]);
|
||||
#endif
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
mov(c, ".jmp_table");
|
||||
lea(c, ptr [c + a * 8]);
|
||||
jmp(c);
|
||||
align(8);
|
||||
L(".jmp_table");
|
||||
mov(a, expectTbl[0]);
|
||||
ret();
|
||||
align(8);
|
||||
mov(a, expectTbl[1]);
|
||||
ret();
|
||||
align(8);
|
||||
mov(a, expectTbl[2]);
|
||||
ret();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/*
|
||||
the label for putL is defined when called
|
||||
*/
|
||||
mov(c, ".jmp_table");
|
||||
jmp(ptr [c + a * (int)sizeof(size_t)]);
|
||||
L(".label1");
|
||||
mov(a, expectTbl[0]);
|
||||
jmp(".end");
|
||||
L(".label2");
|
||||
mov(a, expectTbl[1]);
|
||||
jmp(".end");
|
||||
L(".label3");
|
||||
mov(a, expectTbl[2]);
|
||||
jmp(".end");
|
||||
L(".end");
|
||||
ret();
|
||||
|
||||
/*
|
||||
this table should be in code segment
|
||||
*/
|
||||
align(8);
|
||||
L(".jmp_table");
|
||||
putL(".label1");
|
||||
putL(".label2");
|
||||
putL(".label3");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
the label for putL is not defined when called
|
||||
*/
|
||||
jmp(".in");
|
||||
align(8);
|
||||
/*
|
||||
this table should be in code segment
|
||||
*/
|
||||
L(".jmp_table");
|
||||
putL(".label1");
|
||||
putL(".label2");
|
||||
putL(".label3");
|
||||
L(".in");
|
||||
mov(c, ".jmp_table");
|
||||
jmp(ptr [c + a * (int)sizeof(size_t)]);
|
||||
L(".label1");
|
||||
mov(a, expectTbl[0]);
|
||||
jmp(".end");
|
||||
L(".label2");
|
||||
mov(a, expectTbl[1]);
|
||||
jmp(".end");
|
||||
L(".label3");
|
||||
mov(a, expectTbl[2]);
|
||||
jmp(".end");
|
||||
L(".end");
|
||||
ret();
|
||||
break;
|
||||
}
|
||||
outLocalLabel();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
try
|
||||
{
|
||||
for (int mode = 0; mode < 3; mode++) {
|
||||
printf("mode=%d\n", mode);
|
||||
for (int grow = 0; grow < 2; grow++) {
|
||||
printf("auto grow=%s\n", grow ? "on" : "off");
|
||||
Code c(mode, grow ? 10 : 4096, grow ? Xbyak::AutoGrow : 0);
|
||||
int (*f)(int) = c.getCode<int (*)(int)>();
|
||||
c.ready();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const int a = expectTbl[i];
|
||||
const int b = f(i);
|
||||
if (a != b) {
|
||||
printf("ERR i=%d, a=%d, b=%d\n", i, a, b);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
puts("ok");
|
||||
} catch (Xbyak::Error e) {
|
||||
printf("ERR %s\n", Xbyak::ConvertErrorToString(e));
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
struct A {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4996) // scanf
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
sample to use static memory
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
|
||||
MIE_ALIGN(4096) char buf[4096];
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
|
||||
class Sample : public Xbyak::CodeGenerator {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <vector>
|
||||
#define XBYAK_NO_OP_NAMES
|
||||
#include "xbyak/xbyak.h"
|
||||
#include "xbyak/xbyak_util.h"
|
||||
#define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Xbyak {
|
|||
|
||||
enum {
|
||||
DEFAULT_MAX_CODE_SIZE = 4096,
|
||||
VERSION = 0x4001 /* 0xABCD = A.BC(D) */
|
||||
VERSION = 0x4002 /* 0xABCD = A.BC(D) */
|
||||
};
|
||||
|
||||
#ifndef MIE_INTEGER_TYPE_DEFINED
|
||||
|
@ -1637,6 +1637,7 @@ public:
|
|||
throw ERR_BAD_COMBINATION;
|
||||
}
|
||||
}
|
||||
// QQQ : rewrite this function with putL
|
||||
void mov(
|
||||
#ifdef XBYAK64
|
||||
const Reg64& reg,
|
||||
|
@ -1673,6 +1674,31 @@ public:
|
|||
jmp.mode = isAutoGrow() ? inner::LaddTop : inner::Labs;
|
||||
label_.addUndefinedLabel(label, jmp);
|
||||
}
|
||||
/*
|
||||
put address of label to buffer
|
||||
@note the put size is 4(32-bit), 8(64-bit)
|
||||
*/
|
||||
void putL(const char *label)
|
||||
{
|
||||
const int jmpSize = (int)sizeof(size_t);
|
||||
if (isAutoGrow() && size_ + 16 >= maxSize_) growMemory();
|
||||
size_t offset = 0;
|
||||
if (label_.getOffset(&offset, label)) {
|
||||
if (isAutoGrow()) {
|
||||
db(uint64(0), jmpSize);
|
||||
save(size_ - jmpSize, offset, jmpSize, inner::LaddTop);
|
||||
} else {
|
||||
db(size_t(top_) + offset, jmpSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
db(uint64(0), jmpSize);
|
||||
JmpLabel jmp;
|
||||
jmp.endOfJmp = size_;
|
||||
jmp.jmpSize = jmpSize;
|
||||
jmp.mode = isAutoGrow() ? inner::LaddTop : inner::Labs;
|
||||
label_.addUndefinedLabel(label, jmp);
|
||||
}
|
||||
void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), 0x0F, B11000111); }
|
||||
#ifdef XBYAK64
|
||||
void cmpxchg16b(const Address& addr) { opModM(addr, Reg64(1), 0x0F, B11000111); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const char *getVersionString() const { return "4.001"; }
|
||||
const char *getVersionString() const { return "4.002"; }
|
||||
void packssdw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6B); }
|
||||
void packsswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x63); }
|
||||
void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); }
|
||||
|
|
Loading…
Reference in a new issue