support putL(LABEL); function
diff --git a/readme.md b/readme.md
index 1c46e53..3031c17 100644
--- a/readme.md
+++ b/readme.md
@@ -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 @@
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
diff --git a/readme.txt b/readme.txt
index 1ee8bbb..a5a4067 100644
--- a/readme.txt
+++ b/readme.txt
@@ -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 @@
-----------------------------------------------------------------------------
◎履歴
+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をサポート
diff --git a/sample/Makefile b/sample/Makefile
index 35a285c..279707d 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -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 @@
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 @@
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 @@
$(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_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)
diff --git a/sample/bf.cpp b/sample/bf.cpp
index 13c9718..2c38486 100644
--- a/sample/bf.cpp
+++ b/sample/bf.cpp
@@ -1,3 +1,4 @@
+#define XBYAK_NO_OP_NAMES
#include "xbyak/xbyak.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/sample/calc.cpp b/sample/calc.cpp
index 01c568d..a1e83f2 100644
--- a/sample/calc.cpp
+++ b/sample/calc.cpp
@@ -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)
diff --git a/sample/calc2.cpp b/sample/calc2.cpp
index ce2b222..fc7afa9 100644
--- a/sample/calc2.cpp
+++ b/sample/calc2.cpp
@@ -22,6 +22,7 @@
#include <assert.h>
#include <string>
#include <vector>
+#define XBYAK_NO_OP_NAMES
#include "xbyak/xbyak.h"
enum Operand {
diff --git a/sample/jmp_table.cpp b/sample/jmp_table.cpp
new file mode 100644
index 0000000..415f74e
--- /dev/null
+++ b/sample/jmp_table.cpp
@@ -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));
+}
diff --git a/sample/memfunc.cpp b/sample/memfunc.cpp
index eeedaa9..a98dd73 100644
--- a/sample/memfunc.cpp
+++ b/sample/memfunc.cpp
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#define XBYAK_NO_OP_NAMES
#include <xbyak/xbyak.h>
struct A {
diff --git a/sample/quantize.cpp b/sample/quantize.cpp
index 401f886..f028927 100644
--- a/sample/quantize.cpp
+++ b/sample/quantize.cpp
@@ -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
diff --git a/sample/static_buf.cpp b/sample/static_buf.cpp
index d5f4183..a2ef0e2 100644
--- a/sample/static_buf.cpp
+++ b/sample/static_buf.cpp
@@ -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];
diff --git a/sample/test0.cpp b/sample/test0.cpp
index c54ecc8..93cfa9d 100644
--- a/sample/test0.cpp
+++ b/sample/test0.cpp
@@ -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 {
diff --git a/sample/toyvm.cpp b/sample/toyvm.cpp
index aa2e3ad..a98b7ce 100644
--- a/sample/toyvm.cpp
+++ b/sample/toyvm.cpp
@@ -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]))
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index 0ee884f..aebf5df 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -85,7 +85,7 @@
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 @@
throw ERR_BAD_COMBINATION;
}
}
+ // QQQ : rewrite this function with putL
void mov(
#ifdef XBYAK64
const Reg64& reg,
@@ -1673,6 +1674,31 @@
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); }
diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h
index 5d6939e..e2ef2bd 100644
--- a/xbyak/xbyak_mnemonic.h
+++ b/xbyak/xbyak_mnemonic.h
@@ -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); }