mirror of
https://github.com/FEX-Emu/xbyak.git
synced 2025-02-23 14:50:45 +00:00
use 32bit extended encoding for mov(reg64, imm)
This commit is contained in:
parent
2965c4c0ba
commit
ba203dc894
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak version 2.26
|
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak version 2.27
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
◎概要
|
◎概要
|
||||||
@ -199,6 +199,7 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
◎履歴
|
◎履歴
|
||||||
|
|
||||||
|
2010/06/01 ver 2.27 support encoding of mov(reg64, imm) like yasm(not nasm)
|
||||||
2010/05/24 ver 2.26 fix sub(rsp, 1000)
|
2010/05/24 ver 2.26 fix sub(rsp, 1000)
|
||||||
2010/04/26 ver 2.25 add jc/jnc(I forgot to implement them...)
|
2010/04/26 ver 2.25 add jc/jnc(I forgot to implement them...)
|
||||||
2010/04/16 ver 2.24 change the prototype of rewrite() method
|
2010/04/16 ver 2.24 change the prototype of rewrite() method
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Xbyak 2.26 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
Xbyak 2.27 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
<Abstract>
|
<Abstract>
|
||||||
@ -148,6 +148,7 @@ http://www.opensource.org/licenses/bsd-license.php
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
<History>
|
<History>
|
||||||
|
|
||||||
|
2010/Jun/01 ver 2.27 support encoding of mov(reg64, imm) like yasm(not nasm)
|
||||||
2010/May/24 ver 2.26 fix sub(rsp, 1000)
|
2010/May/24 ver 2.26 fix sub(rsp, 1000)
|
||||||
2010/Apr/26 ver 2.25 add jc/jnc(I forgot to implement them...)
|
2010/Apr/26 ver 2.25 add jc/jnc(I forgot to implement them...)
|
||||||
2010/Apr/16 ver 2.24 change the prototype of rewrite() method
|
2010/Apr/16 ver 2.24 change the prototype of rewrite() method
|
||||||
@ -184,5 +185,5 @@ http://www.opensource.org/licenses/bsd-license.php
|
|||||||
MITSUNARI Shigeo(herumi at nifty dot com)
|
MITSUNARI Shigeo(herumi at nifty dot com)
|
||||||
|
|
||||||
---
|
---
|
||||||
$Revision: 1.46 $
|
$Revision: 1.47 $
|
||||||
$Date: 2010/05/24 06:13:44 $
|
$Date: 2010/06/01 01:21:39 $
|
||||||
|
@ -20,12 +20,17 @@ normalize_prefix: normalize_prefix.cpp
|
|||||||
g++ $(CFLAGS) normalize_prefix.cpp -o $@
|
g++ $(CFLAGS) normalize_prefix.cpp -o $@
|
||||||
test_mmx: test_mmx.cpp
|
test_mmx: test_mmx.cpp
|
||||||
g++ $(CFLAGS) test_mmx.cpp -o $@ -lpthread
|
g++ $(CFLAGS) test_mmx.cpp -o $@ -lpthread
|
||||||
|
jmp: jmp.cpp
|
||||||
|
g++ $(CFLAGS) jmp.cpp -o $@
|
||||||
|
|
||||||
test: normalize_prefix
|
test: normalize_prefix jmp
|
||||||
./test_nm.sh
|
./test_nm.sh
|
||||||
./test_nm.sh Y
|
./test_nm.sh Y
|
||||||
./test_nm.sh 64
|
./test_nm.sh 64
|
||||||
./test_nm.sh Y64
|
./test_nm.sh Y64
|
||||||
|
./test_address.sh
|
||||||
|
./test_address.sh 64
|
||||||
|
./jmp
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o $(TARGET)
|
rm -rf *.o $(TARGET)
|
||||||
|
@ -5,16 +5,21 @@
|
|||||||
|
|
||||||
void genAddress(bool isJIT, const char regTbl[][5], size_t regTblNum)
|
void genAddress(bool isJIT, const char regTbl[][5], size_t regTblNum)
|
||||||
{
|
{
|
||||||
|
int count = 0;
|
||||||
|
int funcNum = 1;
|
||||||
|
if (isJIT) {
|
||||||
|
puts("void gen0(){");
|
||||||
|
}
|
||||||
for (size_t i = 0; i < regTblNum + 1; i++) {
|
for (size_t i = 0; i < regTblNum + 1; i++) {
|
||||||
const char *base = regTbl[i];
|
const char *base = regTbl[i];
|
||||||
for (size_t j = 0; j < regTblNum + 1; j++) {
|
for (size_t j = 0; j < regTblNum + 1; j++) {
|
||||||
if (j == 4) continue; /* esp is not index register */
|
if (j == 4) continue; /* esp is not index register */
|
||||||
const char *index = regTbl[j];
|
const char *index = regTbl[j];
|
||||||
static const int scaleTbl[] = { 0, 1, 2, 4, 8 };
|
static const int scaleTbl[] = { 0, 1, 2, 4, 8 };
|
||||||
for (int k = 0; k < NUM_OF_ARRAY(scaleTbl); k++) {
|
for (size_t k = 0; k < NUM_OF_ARRAY(scaleTbl); k++) {
|
||||||
int scale = scaleTbl[k];
|
int scale = scaleTbl[k];
|
||||||
static const int dispTbl[] = { 0, 1, 1000, -1, -1000 };
|
static const int dispTbl[] = { 0, 1, 1000, -1, -1000 };
|
||||||
for (int m = 0; m < NUM_OF_ARRAY(dispTbl); m++) {
|
for (size_t m = 0; m < NUM_OF_ARRAY(dispTbl); m++) {
|
||||||
int disp = dispTbl[m];
|
int disp = dispTbl[m];
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
if (isJIT) {
|
if (isJIT) {
|
||||||
@ -47,10 +52,23 @@ void genAddress(bool isJIT, const char regTbl[][5], size_t regTblNum)
|
|||||||
} else {
|
} else {
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
}
|
}
|
||||||
|
if (isJIT) {
|
||||||
|
count++;
|
||||||
|
if ((count % 100) == 0) {
|
||||||
|
printf("}\n void gen%d(){\n", funcNum++);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isJIT) {
|
||||||
|
printf("}\nvoid gen(){\n");
|
||||||
|
for (int i = 0; i < funcNum; i++) {
|
||||||
|
printf(" gen%d();\n", i);
|
||||||
|
}
|
||||||
|
printf("}\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -60,6 +78,7 @@ int main(int argc, char *argv[])
|
|||||||
bool isJIT = (argc > 1);
|
bool isJIT = (argc > 1);
|
||||||
fprintf(stderr, "phase:%c %s\n", phase ? '1' : '2', isJIT ? "jit" : "asm");
|
fprintf(stderr, "phase:%c %s\n", phase ? '1' : '2', isJIT ? "jit" : "asm");
|
||||||
if (phase) {
|
if (phase) {
|
||||||
|
fprintf(stderr, "32bit reg\n");
|
||||||
static const char reg32Tbl[][5] = {
|
static const char reg32Tbl[][5] = {
|
||||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
@ -69,6 +88,7 @@ int main(int argc, char *argv[])
|
|||||||
genAddress(isJIT, reg32Tbl, NUM_OF_ARRAY(reg32Tbl));
|
genAddress(isJIT, reg32Tbl, NUM_OF_ARRAY(reg32Tbl));
|
||||||
} else {
|
} else {
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
|
fprintf(stderr, "64bit reg\n");
|
||||||
static const char reg64Tbl[][5] = {
|
static const char reg64Tbl[][5] = {
|
||||||
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "xbyak/xbyak.h"
|
#include "xbyak/xbyak.h"
|
||||||
#define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
#define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
||||||
|
|
||||||
@ -82,13 +83,13 @@ int main()
|
|||||||
{ 127, false, true, "EB7F" },
|
{ 127, false, true, "EB7F" },
|
||||||
{ 128, false, false, "E980000000" },
|
{ 128, false, false, "E980000000" },
|
||||||
};
|
};
|
||||||
for (int i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||||
const Tbl *p = &tbl[i];
|
const Tbl *p = &tbl[i];
|
||||||
TestJmp jmp(p->offset, p->isBack, p->isShort);
|
TestJmp jmp(p->offset, p->isBack, p->isShort);
|
||||||
const uint8 *q = (const uint8*)jmp.getCode();
|
const uint8 *q = (const uint8*)jmp.getCode();
|
||||||
char buf[32];
|
char buf[32];
|
||||||
if (p->isBack) q += p->offset; /* skip nop */
|
if (p->isBack) q += p->offset; /* skip nop */
|
||||||
for (int j = 0; j < jmp.getSize() - p->offset; j++) {
|
for (size_t j = 0; j < jmp.getSize() - p->offset; j++) {
|
||||||
sprintf(&buf[j * 2], "%02X", q[j]);
|
sprintf(&buf[j * 2], "%02X", q[j]);
|
||||||
}
|
}
|
||||||
if (strcmp(buf, p->result) != 0) {
|
if (strcmp(buf, p->result) != 0) {
|
||||||
|
@ -62,6 +62,7 @@ const uint64 NOPARA = 1ULL << (bitEnd - 1);
|
|||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
const bool isXbyak_;
|
const bool isXbyak_;
|
||||||
|
int funcNum_;
|
||||||
// check all op1, op2, op3
|
// check all op1, op2, op3
|
||||||
void put(const char *nm, uint64 op1 = NOPARA, uint64 op2 = NOPARA, uint64 op3 = NOPARA) const
|
void put(const char *nm, uint64 op1 = NOPARA, uint64 op2 = NOPARA, uint64 op3 = NOPARA) const
|
||||||
{
|
{
|
||||||
@ -811,6 +812,31 @@ class Test {
|
|||||||
put(p, REG8|REG8_3|MEM, REG8|REG8_3);
|
put(p, REG8|REG8_3|MEM, REG8|REG8_3);
|
||||||
put(p, REG32e|REG16|REG8|REG8_3|EAX|AX|AL|MEM32|MEM16|MEM8, IMM);
|
put(p, REG32e|REG16|REG8|REG8_3|EAX|AX|AL|MEM32|MEM16|MEM8, IMM);
|
||||||
}
|
}
|
||||||
|
void putMov64() const
|
||||||
|
{
|
||||||
|
const struct {
|
||||||
|
const char *a;
|
||||||
|
const char *b;
|
||||||
|
} tbl[] = {
|
||||||
|
{ "0", "dword 0" },
|
||||||
|
{ "0x123", "dword 0x123" },
|
||||||
|
{ "0x12345678", "dword 0x12345678" },
|
||||||
|
{ "0x7fffffff", "dword 0x7fffffff" },
|
||||||
|
{ "0xffffffff", "0xffffffff" },
|
||||||
|
{ "0x80000000", "0x80000000" },
|
||||||
|
{ "2147483648U", "2147483648" },
|
||||||
|
{ "0x80000001", "0x80000001" },
|
||||||
|
{ "0xffffffffffffffff", "dword 0xffffffffffffffff" },
|
||||||
|
{ "-1", "dword -1" },
|
||||||
|
{ "0xffffffff80000000", "dword 0xffffffff80000000" },
|
||||||
|
{ "0xffffffff80000001", "dword 0xffffffff80000001" },
|
||||||
|
{ "0xffffffff12345678", "0xffffffff12345678" },
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||||
|
put("mov", REG64, tbl[i].a, tbl[i].b);
|
||||||
|
}
|
||||||
|
put("mov", REG32e|REG16|REG8|RAX|EAX|AX|AL, IMM);
|
||||||
|
}
|
||||||
void putEtc() const
|
void putEtc() const
|
||||||
{
|
{
|
||||||
const char *p = "ret";
|
const char *p = "ret";
|
||||||
@ -821,7 +847,7 @@ class Test {
|
|||||||
put(p, REG64|MEM|MEM_ONLY_DISP, REG64|RAX);
|
put(p, REG64|MEM|MEM_ONLY_DISP, REG64|RAX);
|
||||||
put(p, AX|REG16|MEM|MEM_ONLY_DISP, REG16|AX);
|
put(p, AX|REG16|MEM|MEM_ONLY_DISP, REG16|AX);
|
||||||
put(p, AL|REG8|REG8_3|MEM|MEM_ONLY_DISP, REG8|REG8_3|AL);
|
put(p, AL|REG8|REG8_3|MEM|MEM_ONLY_DISP, REG8|REG8_3|AL);
|
||||||
put(p, REG32e|REG16|REG8|RAX|EAX|AX|AL, MEM|IMM|MEM_ONLY_DISP);
|
put(p, REG32e|REG16|REG8|RAX|EAX|AX|AL, MEM|MEM_ONLY_DISP);
|
||||||
put(p, MEM32|MEM16|MEM8, IMM);
|
put(p, MEM32|MEM16|MEM8, IMM);
|
||||||
put(p, REG64, "0x1234567890abcdefLL", "0x1234567890abcdef");
|
put(p, REG64, "0x1234567890abcdefLL", "0x1234567890abcdef");
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
@ -1117,32 +1143,72 @@ class Test {
|
|||||||
public:
|
public:
|
||||||
Test(bool isXbyak)
|
Test(bool isXbyak)
|
||||||
: isXbyak_(isXbyak)
|
: isXbyak_(isXbyak)
|
||||||
|
, funcNum_(1)
|
||||||
{
|
{
|
||||||
|
if (!isXbyak_) return;
|
||||||
|
printf("%s",
|
||||||
|
" void gen0()\n"
|
||||||
|
" {\n");
|
||||||
}
|
}
|
||||||
void put() const
|
/*
|
||||||
|
gcc and vc give up to compile this source,
|
||||||
|
so I split functions.
|
||||||
|
*/
|
||||||
|
void separateFunc()
|
||||||
|
{
|
||||||
|
if (!isXbyak_) return;
|
||||||
|
printf(
|
||||||
|
" }\n"
|
||||||
|
" void gen%d()\n"
|
||||||
|
" {\n", funcNum_++);
|
||||||
|
}
|
||||||
|
~Test()
|
||||||
|
{
|
||||||
|
if (!isXbyak_) return;
|
||||||
|
printf("%s",
|
||||||
|
" }\n"
|
||||||
|
" void gen()\n"
|
||||||
|
" {\n");
|
||||||
|
for (int i = 0; i < funcNum_; i++) {
|
||||||
|
printf(
|
||||||
|
" gen%d();\n", i);
|
||||||
|
}
|
||||||
|
printf(
|
||||||
|
" }\n");
|
||||||
|
}
|
||||||
|
void put()
|
||||||
{
|
{
|
||||||
#ifndef USE_YASM
|
#ifndef USE_YASM
|
||||||
putSIMPLE();
|
putSIMPLE();
|
||||||
putReg1();
|
putReg1();
|
||||||
putRorM();
|
putRorM();
|
||||||
|
separateFunc();
|
||||||
putPushPop();
|
putPushPop();
|
||||||
putTest();
|
putTest();
|
||||||
|
separateFunc();
|
||||||
putEtc();
|
putEtc();
|
||||||
putShift();
|
putShift();
|
||||||
putShxd();
|
putShxd();
|
||||||
|
|
||||||
|
separateFunc();
|
||||||
|
|
||||||
putBs();
|
putBs();
|
||||||
putMMX1();
|
putMMX1();
|
||||||
putMMX2();
|
putMMX2();
|
||||||
|
separateFunc();
|
||||||
putMMX3();
|
putMMX3();
|
||||||
putMMX4();
|
putMMX4();
|
||||||
putMMX5();
|
putMMX5();
|
||||||
|
separateFunc();
|
||||||
putXMM1();
|
putXMM1();
|
||||||
putXMM2();
|
putXMM2();
|
||||||
putXMM3();
|
putXMM3();
|
||||||
putXMM4();
|
putXMM4();
|
||||||
|
separateFunc();
|
||||||
putCmov();
|
putCmov();
|
||||||
putFpuMem16_32();
|
putFpuMem16_32();
|
||||||
putFpuMem32_64();
|
putFpuMem32_64();
|
||||||
|
separateFunc();
|
||||||
putFpuMem16_32_64();
|
putFpuMem16_32_64();
|
||||||
put("clflush", MEM); // current nasm is ok
|
put("clflush", MEM); // current nasm is ok
|
||||||
putFpu();
|
putFpu();
|
||||||
@ -1150,7 +1216,9 @@ public:
|
|||||||
putFpuFpu();
|
putFpuFpu();
|
||||||
putSSSE3();
|
putSSSE3();
|
||||||
putSSE4_1();
|
putSSE4_1();
|
||||||
|
separateFunc();
|
||||||
putSSE4_2();
|
putSSE4_2();
|
||||||
|
putMov64();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1160,4 +1228,3 @@ int main(int argc, char *[])
|
|||||||
Test test(argc > 1);
|
Test test(argc > 1);
|
||||||
test.put();
|
test.put();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6589
test/nm.cpp
6589
test/nm.cpp
File diff suppressed because it is too large
Load Diff
@ -6,21 +6,9 @@ using namespace Xbyak;
|
|||||||
class Sample : public CodeGenerator {
|
class Sample : public CodeGenerator {
|
||||||
void operator=(const Sample&);
|
void operator=(const Sample&);
|
||||||
public:
|
public:
|
||||||
void gen()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
|
|
||||||
#include "nm.cpp"
|
#include "nm.cpp"
|
||||||
|
|
||||||
} catch (Xbyak::Error err) {
|
|
||||||
printf("ERR:%s(%d)\n", ConvertErrorToString(err), err);
|
|
||||||
} catch (...) {
|
|
||||||
printf("unkwon error\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define _STR(x) #x
|
#define _STR(x) #x
|
||||||
#define TEST(syntax) err = true; try { syntax; err = false; } catch (Xbyak::Error) { } catch (...) { } if (!err) printf("should be err:%s;\n", _STR(syntax))
|
#define TEST(syntax) err = true; try { syntax; err = false; } catch (Xbyak::Error) { } catch (...) { } if (!err) printf("should be err:%s;\n", _STR(syntax))
|
||||||
|
|
||||||
@ -38,8 +26,14 @@ public:
|
|||||||
};
|
};
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Sample s;
|
try {
|
||||||
s.gen();
|
Sample s;
|
||||||
|
s.gen();
|
||||||
|
} catch (Xbyak::Error err) {
|
||||||
|
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err);
|
||||||
|
} catch (...) {
|
||||||
|
printf("unknown error\n");
|
||||||
|
}
|
||||||
ErrorSample es;
|
ErrorSample es;
|
||||||
es.gen();
|
es.gen();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ if /i "%1"=="64" (
|
|||||||
set OPT2=-DXBYAK64
|
set OPT2=-DXBYAK64
|
||||||
set OPT3=win64
|
set OPT3=win64
|
||||||
) else (
|
) else (
|
||||||
set OPT2=
|
set OPT2=-DXBYAK32
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,12 +20,16 @@ if /i "%1"=="64" (
|
|||||||
goto end
|
goto end
|
||||||
|
|
||||||
:sub
|
:sub
|
||||||
|
echo cl address.cpp %OPT% %OPT2%
|
||||||
cl address.cpp %OPT% %OPT2%
|
cl address.cpp %OPT% %OPT2%
|
||||||
address %1% > a.asm
|
address %1% > a.asm
|
||||||
|
echo nasm -f %OPT3% -l a.lst a.asm
|
||||||
nasm -f %OPT3% -l a.lst a.asm
|
nasm -f %OPT3% -l a.lst a.asm
|
||||||
awk "{print $3}" < a.lst > ok.lst
|
awk "{print $3}" < a.lst > ok.lst
|
||||||
|
echo address %1% jit > nm.cpp
|
||||||
address %1% jit > nm.cpp
|
address %1% jit > nm.cpp
|
||||||
cl -I../ -DTEST_NM nm_frame.cpp %OPT% %OPT2%
|
echo cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
nm_frame > x.lst
|
nm_frame > x.lst
|
||||||
diff x.lst ok.lst
|
diff x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pushd ..\gen
|
pushd ..\gen
|
||||||
call update
|
call update
|
||||||
popd
|
popd
|
||||||
cl -I../ -DTEST_NM jmp.cpp %OPT%
|
cl -I../ -DXBYAK_TEST jmp.cpp %OPT%
|
||||||
jmp
|
jmp
|
||||||
|
@ -18,8 +18,8 @@ if /i "%1"=="Y" (
|
|||||||
set OPT3=win64
|
set OPT3=win64
|
||||||
set FILTER=normalize_prefix
|
set FILTER=normalize_prefix
|
||||||
) else (
|
) else (
|
||||||
set EXE=nasm.exe -DXBYAK32
|
set EXE=nasm.exe
|
||||||
set OPT2=
|
set OPT2=-DXBYAK32
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
pushd ..\gen
|
pushd ..\gen
|
||||||
@ -36,7 +36,7 @@ if /i "%Y%"=="1" (
|
|||||||
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
|
||||||
)
|
)
|
||||||
make_nm jit > nm.cpp
|
make_nm jit > nm.cpp
|
||||||
cl -I../ -DTEST_NM nm_frame.cpp %OPT% %OPT2%
|
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2%
|
||||||
nm_frame |%FILTER% > x.lst
|
nm_frame |%FILTER% > x.lst
|
||||||
diff x.lst ok.lst
|
diff x.lst ok.lst
|
||||||
wc x.lst
|
wc x.lst
|
||||||
|
@ -36,7 +36,7 @@ awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti =
|
|||||||
echo "xbyak"
|
echo "xbyak"
|
||||||
./make_nm jit > nm.cpp
|
./make_nm jit > nm.cpp
|
||||||
echo "compile nm_frame.cpp"
|
echo "compile nm_frame.cpp"
|
||||||
g++ $CFLAGS -DTEST_NM nm_frame.cpp -o nm_frame
|
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame
|
||||||
./nm_frame | $FILTER > x.lst
|
./nm_frame | $FILTER > x.lst
|
||||||
diff ok.lst x.lst && echo "ok"
|
diff ok.lst x.lst && echo "ok"
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
@file xbyak.h
|
@file xbyak.h
|
||||||
@brief Xbyak ; JIT assembler for x86(IA32)/x64 by C++
|
@brief Xbyak ; JIT assembler for x86(IA32)/x64 by C++
|
||||||
@author herumi
|
@author herumi
|
||||||
@version $Revision: 1.188 $
|
@version $Revision: 1.191 $
|
||||||
@url http://homepage1.nifty.com/herumi/soft/xbyak.html
|
@url http://homepage1.nifty.com/herumi/soft/xbyak.html
|
||||||
@date $Date: 2010/05/24 06:13:44 $
|
@date $Date: 2010/06/01 05:26:11 $
|
||||||
@note modified new BSD license
|
@note modified new BSD license
|
||||||
http://www.opensource.org/licenses/bsd-license.php
|
http://www.opensource.org/licenses/bsd-license.php
|
||||||
*/
|
*/
|
||||||
@ -55,7 +55,7 @@ namespace Xbyak {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEFAULT_MAX_CODE_SIZE = 2048,
|
DEFAULT_MAX_CODE_SIZE = 2048,
|
||||||
VERSION = 0x2260, /* 0xABCD = A.BC(D) */
|
VERSION = 0x2270, /* 0xABCD = A.BC(D) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef MIE_INTEGER_TYPE_DEFINED
|
#ifndef MIE_INTEGER_TYPE_DEFINED
|
||||||
@ -144,7 +144,7 @@ namespace inner {
|
|||||||
|
|
||||||
enum { debug = 1 };
|
enum { debug = 1 };
|
||||||
|
|
||||||
static inline uint32 GetPtrDist(const void *p1, const void *p2 = 0)
|
static inline uint32 GetPtrDist(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
uint64 diff = static_cast<const char *>(p1) - static_cast<const char *>(p2);
|
uint64 diff = static_cast<const char *>(p1) - static_cast<const char *>(p2);
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
@ -154,6 +154,7 @@ static inline uint32 GetPtrDist(const void *p1, const void *p2 = 0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsInDisp8(uint32 x) { return 0xFFFFFF80 <= x || x <= 0x7F; }
|
static inline bool IsInDisp8(uint32 x) { return 0xFFFFFF80 <= x || x <= 0x7F; }
|
||||||
|
static inline bool IsInInt32(uint64 x) { return 0xFFFFFFFF80000000ULL <= x || x <= 0x7FFFFFFFU; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +556,11 @@ public:
|
|||||||
explicit AddressFrame(uint32 bit) : bit_(bit) { }
|
explicit AddressFrame(uint32 bit) : bit_(bit) { }
|
||||||
Address operator[](const void *disp) const
|
Address operator[](const void *disp) const
|
||||||
{
|
{
|
||||||
Reg32e r(Reg(), Reg(), 0, inner::GetPtrDist(disp));
|
size_t adr = reinterpret_cast<size_t>(disp);
|
||||||
|
#ifdef XBYAK64
|
||||||
|
if (adr > 0xFFFFFFFFU) throw ERR_OFFSET_IS_TOO_BIG;
|
||||||
|
#endif
|
||||||
|
Reg32e r(Reg(), Reg(), 0, adr);
|
||||||
return operator[](r);
|
return operator[](r);
|
||||||
}
|
}
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
@ -1216,13 +1221,32 @@ protected:
|
|||||||
opRM_RM(reg1, reg2, B10001000);
|
opRM_RM(reg1, reg2, B10001000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void mov(const Operand& op, uint64 imm)
|
void mov(const Operand& op,
|
||||||
|
#ifdef XBYAK64
|
||||||
|
uint64
|
||||||
|
#else
|
||||||
|
uint32
|
||||||
|
#endif
|
||||||
|
imm)
|
||||||
{
|
{
|
||||||
verifyMemHasSize(op);
|
verifyMemHasSize(op);
|
||||||
if (op.isREG()) {
|
if (op.isREG()) {
|
||||||
int w = op.isBit(8) ? 0 : 1;
|
rex(op);
|
||||||
rex(op); db(B10110000 | (w << 3) | (op.getIdx() & 7));
|
int code, size;
|
||||||
db(imm, op.getBit() / 8);
|
#ifdef XBYAK64
|
||||||
|
if (op.isBit(64) && inner::IsInInt32(imm)) {
|
||||||
|
db(B11000111);
|
||||||
|
code = B11000000;
|
||||||
|
size = 4;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
code = B10110000 | ((op.isBit(8) ? 0 : 1) << 3);
|
||||||
|
size = op.getBit() / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
db(code | (op.getIdx() & 7));
|
||||||
|
db(imm, size);
|
||||||
} else if (op.isMEM()) {
|
} else if (op.isMEM()) {
|
||||||
opModM(static_cast<const Address&>(op), Reg(0, Operand::REG, op.getBit()), B11000110);
|
opModM(static_cast<const Address&>(op), Reg(0, Operand::REG, op.getBit()), B11000110);
|
||||||
int size = op.getBit() / 8; if (size > 4) size = 4;
|
int size = op.getBit() / 8; if (size > 4) size = 4;
|
||||||
@ -1398,7 +1422,7 @@ public:
|
|||||||
// if (hasUndefinedLabel()) throw ERR_LABEL_IS_NOT_FOUND;
|
// if (hasUndefinedLabel()) throw ERR_LABEL_IS_NOT_FOUND;
|
||||||
return top_;
|
return top_;
|
||||||
}
|
}
|
||||||
#ifdef TEST_NM
|
#ifdef XBYAK_TEST
|
||||||
void dump(bool doClear = true)
|
void dump(bool doClear = true)
|
||||||
{
|
{
|
||||||
CodeArray::dump();
|
CodeArray::dump();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const char *getVersionString() const { return "2.26"; }
|
const char *getVersionString() const { return "2.27"; }
|
||||||
void packssdw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6B); }
|
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 packsswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x63); }
|
||||||
void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); }
|
void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); }
|
||||||
|
@ -95,25 +95,25 @@ public:
|
|||||||
if (data[2] == get32bitAsBE(amd)) {
|
if (data[2] == get32bitAsBE(amd)) {
|
||||||
type_ |= tAMD;
|
type_ |= tAMD;
|
||||||
getCpuid(0x80000001, data);
|
getCpuid(0x80000001, data);
|
||||||
if (data[3] & (1 << 31)) type_ |= t3DN;
|
if (data[3] & (1U << 31)) type_ |= t3DN;
|
||||||
if (data[3] & (1 << 15)) type_ |= tCMOV;
|
if (data[3] & (1U << 15)) type_ |= tCMOV;
|
||||||
if (data[3] & (1 << 30)) type_ |= tE3DN;
|
if (data[3] & (1U << 30)) type_ |= tE3DN;
|
||||||
if (data[3] & (1 << 22)) type_ |= tMMX2;
|
if (data[3] & (1U << 22)) type_ |= tMMX2;
|
||||||
}
|
}
|
||||||
if (data[2] == get32bitAsBE(intel)) {
|
if (data[2] == get32bitAsBE(intel)) {
|
||||||
type_ |= tINTEL;
|
type_ |= tINTEL;
|
||||||
}
|
}
|
||||||
getCpuid(1, data);
|
getCpuid(1, data);
|
||||||
if (data[2] & (1 << 0)) type_ |= tSSE3;
|
if (data[2] & (1U << 0)) type_ |= tSSE3;
|
||||||
if (data[2] & (1 << 9)) type_ |= tSSSE3;
|
if (data[2] & (1U << 9)) type_ |= tSSSE3;
|
||||||
if (data[2] & (1 << 19)) type_ |= tSSE41;
|
if (data[2] & (1U << 19)) type_ |= tSSE41;
|
||||||
if (data[2] & (1 << 20)) type_ |= tSSE42;
|
if (data[2] & (1U << 20)) type_ |= tSSE42;
|
||||||
if (data[2] & (1 << 23)) type_ |= tPOPCNT;
|
if (data[2] & (1U << 23)) type_ |= tPOPCNT;
|
||||||
|
|
||||||
if (data[3] & (1 << 15)) type_ |= tCMOV;
|
if (data[3] & (1U << 15)) type_ |= tCMOV;
|
||||||
if (data[3] & (1 << 23)) type_ |= tMMX;
|
if (data[3] & (1U << 23)) type_ |= tMMX;
|
||||||
if (data[3] & (1 << 25)) type_ |= tMMX2 | tSSE;
|
if (data[3] & (1U << 25)) type_ |= tMMX2 | tSSE;
|
||||||
if (data[3] & (1 << 26)) type_ |= tSSE2;
|
if (data[3] & (1U << 26)) type_ |= tSSE2;
|
||||||
}
|
}
|
||||||
bool has(Type type) const
|
bool has(Type type) const
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user