support putL(LABEL); function

This commit is contained in:
MITSUNARI Shigeo 2013-06-21 21:20:54 +09:00
parent 8bfefc8f1f
commit 265dfa6588
14 changed files with 181 additions and 7 deletions

View file

@ -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

View file

@ -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をサポート

View file

@ -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)

View file

@ -1,3 +1,4 @@
#define XBYAK_NO_OP_NAMES
#include "xbyak/xbyak.h"
#include <stdio.h>
#include <stdlib.h>

View file

@ -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)

View file

@ -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
View 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));
}

View file

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#define XBYAK_NO_OP_NAMES
#include <xbyak/xbyak.h>
struct A {

View file

@ -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

View file

@ -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];

View file

@ -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 {

View file

@ -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]))

View file

@ -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); }

View file

@ -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); }