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 @@ void put() 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 @@ class Test { 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 @@ private: 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 hsubpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7D, 0x66, isXM 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& op, uint32 imm) { opRM_I(op, imm, 0x08, 1); } 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); }