add some fpu mnemonics
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 @@
{ "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 @@
{ 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 @@
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 @@
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 @@
"fabs",
"faddp",
"fchs",
+ "fclex",
+ "fnclex",
"fcom",
"fcomp",
"fcompp",
@@ -600,16 +602,35 @@
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 @@
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 @@
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 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 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 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 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 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); }