add in_, out_
diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp
index 889cb87..7feb178 100644
--- a/gen/gen_code.cpp
+++ b/gen/gen_code.cpp
@@ -965,6 +965,12 @@
printf("void %s(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0x%02X); }\n", p->name, p->code);
}
}
+ { // in/out
+ puts("void in_(const Reg& a, uint8 v) { opInOut(a, 0xE4, v); }");
+ puts("void in_(const Reg& a, const Reg& d) { opInOut(a, d, 0xEC); }");
+ puts("void out_(uint8 v, const Reg& a) { opInOut(a, 0xE6, v); }");
+ puts("void out_(const Reg& d, const Reg& a) { opInOut(a, d, 0xEE); }");
+ }
// mpx
{
puts("void bndcl(const BoundsReg& bnd, const Operand& op) { db(0xF3); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }");
diff --git a/test/make_nm.cpp b/test/make_nm.cpp
index 4c52f47..2279988 100644
--- a/test/make_nm.cpp
+++ b/test/make_nm.cpp
@@ -609,6 +609,14 @@
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");
+ puts(isXbyak_ ? "in_(ax, dx); dump();" : "in ax, dx");
+ puts(isXbyak_ ? "in_(eax, dx); dump();" : "in eax, dx");
+ put(isXbyak_ ? "out_" : "out", IMM8, AL|AX|EAX);
+ puts(isXbyak_ ? "out_(dx, al); dump();" : "out dx, al");
+ puts(isXbyak_ ? "out_(dx, ax); dump();" : "out dx, ax");
+ puts(isXbyak_ ? "out_(dx, eax); dump();" : "out dx, eax");
}
void putJmp() const
{
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index 64b4ee3..c8c0507 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -2185,6 +2185,28 @@
if (addr.getRegExp().getIndex().getKind() != kind) throw Error(ERR_BAD_VSIB_ADDRESSING);
opVex(x, 0, addr, type, code);
}
+ void opInOut(const Reg& a, const Reg& d, uint8 code)
+ {
+ if (a.getIdx() == Operand::AL && d.getIdx() == Operand::DX && d.getBit() == 16) {
+ switch (a.getBit()) {
+ case 8: db(code); return;
+ case 16: db(0x66); db(code + 1); return;
+ case 32: db(code + 1); return;
+ }
+ }
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ void opInOut(const Reg& a, uint8 code, uint8 v)
+ {
+ if (a.getIdx() == Operand::AL) {
+ switch (a.getBit()) {
+ case 8: db(code); db(v); return;
+ case 16: db(0x66); db(code + 1); db(v); return;
+ case 32: db(code + 1); db(v); return;
+ }
+ }
+ throw Error(ERR_BAD_COMBINATION);
+ }
public:
unsigned int getVersion() const { return VERSION; }
using CodeArray::db;
diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h
index eb4bebe..55de124 100644
--- a/xbyak/xbyak_mnemonic.h
+++ b/xbyak/xbyak_mnemonic.h
@@ -309,6 +309,8 @@
void hsubps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7D, 0xF2, isXMM_XMMorMEM); }
void idiv(const Operand& op) { opR_ModM(op, 0, 7, 0xF6); }
void imul(const Operand& op) { opR_ModM(op, 0, 5, 0xF6); }
+void in_(const Reg& a, const Reg& d) { opInOut(a, d, 0xEC); }
+void in_(const Reg& a, uint8 v) { opInOut(a, 0xE4, v); }
void inc(const Operand& op) { opIncDec(op, 0x40, 0); }
void insertps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
void int3() { db(0xCC); }
@@ -517,6 +519,8 @@
void or_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x08); }
void orpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x56, 0x66, isXMM_XMMorMEM); }
void orps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x56, 0x100, isXMM_XMMorMEM); }
+void out_(const Reg& d, const Reg& a) { opInOut(a, d, 0xEE); }
+void out_(uint8 v, const Reg& a) { opInOut(a, 0xE6, v); }
void outsb() { db(0x6E); }
void outsd() { db(0x6F); }
void outsw() { db(0x66); db(0x6F); }