diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index dae0c5e..8a71517 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -710,7 +710,8 @@ void put() { "fabs", 0xD9, 0xE1 }, { "faddp", 0xDE, 0xC1 }, { "fchs", 0xD9, 0xE0 }, - + { "fclex", 0x9B, 0xDB, 0xE2 }, + { "fnclex", 0xDB, 0xE2 }, { "fcom", 0xD8, 0xD1 }, { "fcomp", 0xD8, 0xD9 }, { "fcompp", 0xDE, 0xD9 }, @@ -944,10 +945,20 @@ void put() { 0x0F, 0xAE, 3, "stmxcsr", 0 }, { 0x0F, 0xAE, 7, "clflush", 0 }, { 0x0F, 0xAE, 7, "clflushopt", 0x66 }, + { 0xDF, NONE, 4, "fbld", 0 }, + { 0xDF, NONE, 6, "fbstp", 0 }, { 0xD9, NONE, 5, "fldcw", 0 }, { 0xD9, NONE, 4, "fldenv", 0 }, + { 0xDD, NONE, 4, "frstor", 0 }, + { 0xDD, NONE, 6, "fsave", 0x9B }, + { 0xDD, NONE, 6, "fnsave", 0 }, { 0xD9, NONE, 7, "fstcw", 0x9B }, { 0xD9, NONE, 7, "fnstcw", 0 }, + { 0xD9, NONE, 6, "fstenv", 0x9B }, + { 0xD9, NONE, 6, "fnstenv", 0 }, + { 0xDD, NONE, 7, "fstsw", 0x9B }, + { 0xDD, NONE, 7, "fnstsw", 0 }, + { 0x0F, 0xAE, 1, "fxrstor", 0 }, }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; @@ -955,6 +966,8 @@ void put() if (p->prefix) printf("db(0x%02X); ", p->prefix); printf("opModM(addr, Reg32(%d), 0x%02X, 0x%02X); }\n", p->ext, p->code1, p->code2); } + puts("void fstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) throw Error(ERR_BAD_PARAMETER); db(0x9B); db(0xDF); db(0xE0); }"); + puts("void fnstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) throw Error(ERR_BAD_PARAMETER); db(0xDF); db(0xE0); }"); } { const struct Tbl { @@ -1740,6 +1753,7 @@ void put64() putGeneric(tbl, NUM_OF_ARRAY(tbl)); puts("void cmpxchg16b(const Address& addr) { opModM(addr, Reg64(1), 0x0F, 0xC7); }"); + puts("void fxrstor64(const Address& addr) { opModM(addr, Reg64(1), 0x0F, 0xAE); }"); puts("void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x7E); }"); puts("void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x6E); }"); puts("void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) throw Error(ERR_BAD_COMBINATION); opModRM(reg, op, op.isREG(), op.isMEM(), 0x63); }"); diff --git a/test/make_nm.cpp b/test/make_nm.cpp index 70897fc..9fb7dfa 100644 --- a/test/make_nm.cpp +++ b/test/make_nm.cpp @@ -557,6 +557,8 @@ class Test { "fabs", "faddp", "fchs", + "fclex", + "fnclex", "fcom", "fcomp", "fcompp", @@ -600,16 +602,35 @@ class Test { for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { put(tbl[i]); } + { + const char memTbl[][16] = { + "clflush", + "clflushopt", + "fbld", + "fbstp", + "fldcw", + "fldenv", + "frstor", + "fsave", + "fnsave", + "fstcw", + "fnstcw", + "fstenv", + "fnstenv", + "fstsw", + "fnstsw", + "fxrstor", + }; + for (size_t i = 0; i < NUM_OF_ARRAY(memTbl); i++) { + put(memTbl[i], MEM); + } + put("fstsw", AX); + put("fnstsw", AX); + } put("bswap", REG32e); put("lea", REG32e|REG16, MEM); - put("clflush", MEM); - put("clflushopt", MEM); put("enter", IMM, IMM); - put("fldcw", MEM); - put("fldenv", MEM); - put("fstcw", MEM); - put("fnstcw", MEM); put(isXbyak_ ? "int_" : "int", IMM8); put(isXbyak_ ? "in_" : "in", AL|AX|EAX, IMM8); puts(isXbyak_ ? "in_(al, dx); dump();" : "in al, dx"); @@ -1207,6 +1228,7 @@ class Test { put("cmpxchg8b", MEM); #ifdef XBYAK64 put("cmpxchg16b", MEM); + put("fxrstor64", MEM); #endif { const char tbl[][8] = { diff --git a/test/test_nm.bat b/test/test_nm.bat index 0d63b65..60644a9 100644 --- a/test/test_nm.bat +++ b/test/test_nm.bat @@ -27,7 +27,7 @@ bmake -f Makefile.win all echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs cl -I../ make_nm.cpp %OPT% %OPT2% /EHs make_nm > a.asm -rm a.lst +rm -rf a.lst echo %EXE% -f %OPT3% -l a.lst a.asm %EXE% -f %OPT3% -l a.lst a.asm rem connect "?????-" and "??" diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index b2fb1d8..6844079 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -181,7 +181,10 @@ void fadd(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8C0, 0xDCC void faddp() { db(0xDE); db(0xC1); } void faddp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEC0); } void faddp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEC0); } +void fbld(const Address& addr) { opModM(addr, Reg32(4), 0xDF, 0x100); } +void fbstp(const Address& addr) { opModM(addr, Reg32(6), 0xDF, 0x100); } void fchs() { db(0xD9); db(0xE0); } +void fclex() { db(0x9B); db(0xDB); db(0xE2); } void fcmovb(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAC0, 0x00C0); } void fcmovb(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDAC0, 0x00C0); } void fcmovbe(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAD0, 0x00D0); } @@ -255,14 +258,21 @@ void fmul(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8C8, 0xDCC void fmulp() { db(0xDE); db(0xC9); } void fmulp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEC8); } void fmulp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEC8); } +void fnclex() { db(0xDB); db(0xE2); } void fninit() { db(0xDB); db(0xE3); } void fnop() { db(0xD9); db(0xD0); } +void fnsave(const Address& addr) { opModM(addr, Reg32(6), 0xDD, 0x100); } void fnstcw(const Address& addr) { opModM(addr, Reg32(7), 0xD9, 0x100); } +void fnstenv(const Address& addr) { opModM(addr, Reg32(6), 0xD9, 0x100); } +void fnstsw(const Address& addr) { opModM(addr, Reg32(7), 0xDD, 0x100); } +void fnstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) throw Error(ERR_BAD_PARAMETER); db(0xDF); db(0xE0); } void fpatan() { db(0xD9); db(0xF3); } void fprem() { db(0xD9); db(0xF8); } void fprem1() { db(0xD9); db(0xF5); } void fptan() { db(0xD9); db(0xF2); } void frndint() { db(0xD9); db(0xFC); } +void frstor(const Address& addr) { opModM(addr, Reg32(4), 0xDD, 0x100); } +void fsave(const Address& addr) { db(0x9B); opModM(addr, Reg32(6), 0xDD, 0x100); } void fscale() { db(0xD9); db(0xFD); } void fsin() { db(0xD9); db(0xFE); } void fsincos() { db(0xD9); db(0xFB); } @@ -270,8 +280,11 @@ void fsqrt() { db(0xD9); db(0xFA); } void fst(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 2, 0); } void fst(const Fpu& reg) { opFpu(reg, 0xDD, 0xD0); } void fstcw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0xD9, 0x100); } +void fstenv(const Address& addr) { db(0x9B); opModM(addr, Reg32(6), 0xD9, 0x100); } void fstp(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 3, 0); } void fstp(const Fpu& reg) { opFpu(reg, 0xDD, 0xD8); } +void fstsw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0xDD, 0x100); } +void fstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) throw Error(ERR_BAD_PARAMETER); db(0x9B); db(0xDF); db(0xE0); } void fsub(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 4, 0); } void fsub(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8E0, 0xDCE8); } void fsub(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8E0, 0xDCE8); } @@ -298,6 +311,7 @@ void fwait() { db(0x9B); } void fxam() { db(0xD9); db(0xE5); } void fxch() { db(0xD9); db(0xC9); } void fxch(const Fpu& reg) { opFpu(reg, 0xD9, 0xC8); } +void fxrstor(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0xAE); } void fxtract() { db(0xD9); db(0xF4); } void fyl2x() { db(0xD9); db(0xF1); } void fyl2xp1() { db(0xD9); db(0xF9); } @@ -1591,6 +1605,7 @@ void stosq() { db(0x48); db(0xAB); } void syscall() { db(0x0F); db(0x05); } void sysret() { db(0x0F); db(0x07); } void cmpxchg16b(const Address& addr) { opModM(addr, Reg64(1), 0x0F, 0xC7); } +void fxrstor64(const Address& addr) { opModM(addr, Reg64(1), 0x0F, 0xAE); } void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x7E); } void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x6E); } void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) throw Error(ERR_BAD_COMBINATION); opModRM(reg, op, op.isREG(), op.isMEM(), 0x63); }