change the type of Xbyak::Error from enum to a class

This commit is contained in:
MITSUNARI Shigeo 2013-07-04 23:59:12 +09:00
parent aadf5b1b40
commit 68fc3502a8
18 changed files with 232 additions and 199 deletions

View file

@ -1398,7 +1398,7 @@ void put()
char c = p.isH ? 'h' : 'l'; char c = p.isH ? 'h' : 'l';
const char *suf = p.isPd ? "pd" : "ps"; const char *suf = p.isPd ? "pd" : "ps";
const char *type = p.isPd ? "MM_0F | PP_66" : "MM_0F"; const char *type = p.isPd ? "MM_0F | PP_66" : "MM_0F";
printf("void vmov%c%s(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x, op1, op2, %s, 0x%02X, false); }\n" printf("void vmov%c%s(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, %s, 0x%02X, false); }\n"
, c, suf, type, p.code); , c, suf, type, p.code);
printf("void vmov%c%s(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, %s, 0x%02X, false); }\n" printf("void vmov%c%s(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, %s, 0x%02X, false); }\n"
, c, suf, type, p.code + 1); , c, suf, type, p.code + 1);
@ -1449,7 +1449,7 @@ void put()
printf("void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x1A, true, 0); }\n"); printf("void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x1A, true, 0); }\n");
printf("void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x5A, true, 0); }\n"); printf("void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x5A, true, 0); }\n");
printf("void vbroadcastsd(const Ymm& y, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(y, op, MM_0F38 | PP_66, 0x19, true, 0); }\n"); printf("void vbroadcastsd(const Ymm& y, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(y, op, MM_0F38 | PP_66, 0x19, true, 0); }\n");
const struct Tbl { const struct Tbl {
const char *name; const char *name;
uint8 code; uint8 code;
@ -1462,12 +1462,12 @@ void put()
}; };
for (size_t 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];
printf("void %s(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x%02x, true, 0); }\n", p.name, p.code); printf("void %s(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x%02x, true, 0); }\n", p.name, p.code);
} }
printf("void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x19, true, 0); db(imm); }\n"); printf("void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x19, true, 0); db(imm); }\n");
printf("void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x39, true, 0); db(imm); }\n"); printf("void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x39, true, 0); db(imm); }\n");
printf("void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!(op.isREG(32) || op.isMEM()) || x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, op.isREG(), Operand::XMM, MM_0F3A | PP_66, 0x17, false, 0); db(imm); }\n"); printf("void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!(op.isREG(32) || op.isMEM()) || x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, op.isREG(), Operand::XMM, MM_0F3A | PP_66, 0x17, false, 0); db(imm); }\n");
printf("void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x18, true, 0); db(imm); }\n"); printf("void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x18, true, 0); db(imm); }\n");
printf("void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x38, true, 0); db(imm); }\n"); printf("void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x38, true, 0); db(imm); }\n");
printf("void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, MM_0F3A | PP_66, 0x06, true, 0); db(imm); }\n"); printf("void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, MM_0F3A | PP_66, 0x06, true, 0); db(imm); }\n");
@ -1478,20 +1478,20 @@ void put()
printf("void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, MM_0F, 0xAE, false, -1); }\n"); printf("void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, MM_0F, 0xAE, false, -1); }\n");
printf("void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_66, 0xF7, false, -1); }\n"); printf("void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_66, 0xF7, false, -1); }\n");
printf("void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(i32e) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x14, false); db(imm); }\n"); printf("void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(i32e) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x14, false); db(imm); }\n");
// according to Intel' manual, VEX.W1 is ignored in 64-bit mode, then always VEX.W = 0, but I follow yasm encoding. // according to Intel' manual, VEX.W1 is ignored in 64-bit mode, then always VEX.W = 0, but I follow yasm encoding.
printf("void vpextrw(const Reg& r, const Xmm& x, uint8 imm) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, x, MM_0F | PP_66, 0xC5, false, r.isBit(64) ? 1 : 0); db(imm); }\n"); printf("void vpextrw(const Reg& r, const Xmm& x, uint8 imm) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, x, MM_0F | PP_66, 0xC5, false, r.isBit(64) ? 1 : 0); db(imm); }\n");
printf("void vpextrw(const Address& addr, const Xmm& x, uint8 imm) { opAVX_X_X_XM(x, xm0, addr, MM_0F3A | PP_66, 0x15, false); db(imm); }\n"); printf("void vpextrw(const Address& addr, const Xmm& x, uint8 imm) { opAVX_X_X_XM(x, xm0, addr, MM_0F3A | PP_66, 0x15, false); db(imm); }\n");
printf("void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 0); db(imm); }\n"); printf("void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 0); db(imm); }\n");
printf("void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }\n"); printf("void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }\n");
printf("void vpinsrb(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }\n"); printf("void vpinsrb(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }\n");
printf("void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }\n"); printf("void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }\n");
printf("void vpinsrw(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }\n"); printf("void vpinsrw(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }\n");
printf("void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }\n"); printf("void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }\n");
printf("void vpinsrd(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }\n"); printf("void vpinsrd(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }\n");
printf("void vpmovmskb(const Reg32e& r, const Xmm& x) { bool isYMM= x.isYMM(); opAVX_X_X_XM(isYMM ? Ymm(r.getIdx()) : Xmm(r.getIdx()), isYMM ? ym0 : xm0, x, MM_0F | PP_66, 0xD7, true); }\n"); printf("void vpmovmskb(const Reg32e& r, const Xmm& x) { bool isYMM= x.isYMM(); opAVX_X_X_XM(isYMM ? Ymm(r.getIdx()) : Xmm(r.getIdx()), isYMM ? ym0 : xm0, x, MM_0F | PP_66, 0xD7, true); }\n");
@ -1542,11 +1542,11 @@ void put()
printf("void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0xD6, false, -1); }\n"); printf("void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0xD6, false, -1); }\n");
printf("void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_F3, 0x7E, false, -1); }\n"); printf("void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_F3, 0x7E, false, -1); }\n");
printf("void vmovhlps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F, 0x12, false); }\n"); printf("void vmovhlps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F, 0x12, false); }\n");
printf("void vmovlhps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F, 0x16, false); }\n"); printf("void vmovlhps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F, 0x16, false); }\n");
printf("void vmovmskpd(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F | PP_66, 0x50, true, 0); }\n"); printf("void vmovmskpd(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F | PP_66, 0x50, true, 0); }\n");
printf("void vmovmskps(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F, 0x50, true, 0); }\n"); printf("void vmovmskps(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F, 0x50, true, 0); }\n");
printf("void vmovntdq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0xE7, true); }\n"); printf("void vmovntdq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0xE7, true); }\n");
printf("void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0x2B, true); }\n"); printf("void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0x2B, true); }\n");
@ -1557,7 +1557,7 @@ void put()
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
char c1 = i == 0 ? 'd' : 's'; char c1 = i == 0 ? 'd' : 's';
char c2 = i == 0 ? '2' : '3'; char c2 = i == 0 ? '2' : '3';
printf("void vmovs%c(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F%c, 0x10, false); }\n", c1, c2); printf("void vmovs%c(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F%c, 0x10, false); }\n", c1, c2);
printf("void vmovs%c(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F%c, 0x10, false); }\n", c1, c2); printf("void vmovs%c(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F%c, 0x10, false); }\n", c1, c2);
printf("void vmovs%c(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F%c, 0x11, false); }\n", c1, c2); printf("void vmovs%c(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F%c, 0x11, false); }\n", c1, c2);
} }
@ -1569,15 +1569,15 @@ void put()
printf("void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 0); }\n"); printf("void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 0); }\n");
printf("void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2C, false, 0); }\n"); printf("void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2C, false, 0); }\n");
printf("void vcvtsi2ss(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F3, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }\n"); printf("void vcvtsi2ss(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F3, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }\n");
printf("void vcvtsi2sd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F2, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }\n"); printf("void vcvtsi2sd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F2, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }\n");
printf("void vcvtps2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F, 0x5A, true); }\n"); printf("void vcvtps2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F, 0x5A, true); }\n");
printf("void vcvtdq2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F | PP_F3, 0xE6, true); }\n"); printf("void vcvtdq2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F | PP_F3, 0xE6, true); }\n");
printf("void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0x5A, true); }\n"); printf("void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0x5A, true); }\n");
printf("void vcvtpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_F2, 0xE6, true); }\n"); printf("void vcvtpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_F2, 0xE6, true); }\n");
printf("void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0xE6, true); }\n"); printf("void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0xE6, true); }\n");
} }
// x64 // x64
{ {
@ -1586,10 +1586,10 @@ void put()
printf("void vmovq(const Xmm& x, const Reg64& reg) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x6E, false, 1); }\n"); printf("void vmovq(const Xmm& x, const Reg64& reg) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x6E, false, 1); }\n");
printf("void vmovq(const Reg64& reg, const Xmm& x) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x7E, false, 1); }\n"); printf("void vmovq(const Reg64& reg, const Xmm& x) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x7E, false, 1); }\n");
printf("void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 1); db(imm); }\n"); printf("void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 1); db(imm); }\n");
printf("void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }\n"); printf("void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }\n");
printf("void vpinsrq(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }\n"); printf("void vpinsrq(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }\n");
printf("void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 1); }\n"); printf("void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 1); }\n");
printf("void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 1); }\n"); printf("void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 1); }\n");

View file

@ -1,5 +1,5 @@
Xbyak 4.02 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ Xbyak 4.10 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
============= =============
Abstract Abstract
@ -51,7 +51,9 @@ These files are copied into /usr/local/include/xbyak
Break backward compatibility Break backward compatibility
------------- -------------
At the next version, (old) Reg32e class will split (new) Reg32e class and (new) RegExp. * change the type of Xbyak::Error from enum to a class.
** get the enum value by cast to int.
* An (old) Reg32e class will split (new) Reg32e class and (new) RegExp.
(new) Reg32e class is Reg32 or Reg64. (new) Reg32e class is Reg32 or Reg64.
(new) RegExp class is to deal with 'Reg32e + Reg32e * scale + disp'. (new) RegExp class is to deal with 'Reg32e + Reg32e * scale + disp'.
Please rename Reg32e as RegExp if you use (old) Reg32e as RegExp. Please rename Reg32e as RegExp if you use (old) Reg32e as RegExp.
@ -235,6 +237,7 @@ http://opensource.org/licenses/BSD-3-Clause
History History
------------- -------------
* 2013/Jul/04 ver 4.10 [break backward compatibility] change the type of Xbyak::Error from enum to a class
* 2013/Jun/21 ver 4.02 add putL(LABEL) function to put the address of the label * 2013/Jun/21 ver 4.02 add putL(LABEL) function to put the address of the label
* 2013/Jun/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm). * 2013/Jun/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm).
support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest). support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest).

View file

@ -1,5 +1,5 @@
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.02 C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.10
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
◎概要 ◎概要
@ -35,6 +35,14 @@ xbyak_mnemonic.h
これらを同一のパスに入れてインクルードパスに追加してください。 これらを同一のパスに入れてインクルードパスに追加してください。
Linuxではmake installで/usr/local/include/xbyakにコピーされます。 Linuxではmake installで/usr/local/include/xbyakにコピーされます。
-----------------------------------------------------------------------------
◎下位互換性の破れ
* Xbyak::Errorの型をenumからclassに変更
** 従来のenumの値をとるにはintにキャストしてください。
* (古い)Reg32eクラスを(新しい)Reg32eとRegExpに分ける。
** (新しい)Reg32eはReg32かReg64
** (新しい)RegExpは'Reg32e + Reg32e * scale + disp'の型
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
◎新機能 ◎新機能
@ -244,6 +252,7 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
◎履歴 ◎履歴
2013/07/04 ver 4.10 [break backward compatibility] Xbyak::Errorの型をenumからclassに変更
2013/06/21 ver 4.02 LABELの指すアドレスを書き込むputL(LABEL)関数の追加。 2013/06/21 ver 4.02 LABELの指すアドレスを書き込むputL(LABEL)関数の追加。
2013/06/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm) 2013/06/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm)
support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest) support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest)

View file

@ -196,8 +196,8 @@ int main(int argc, char *argv[])
} else { } else {
dump(bf.getCode(), bf.getSize()); dump(bf.getCode(), bf.getSize());
} }
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -216,8 +216,8 @@ int main(int argc, char *argv[])
#endif #endif
printf("f("); put(valTbl); printf(")=%f\n", y); printf("f("); put(valTbl); printf(")=%f\n", y);
} }
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (Error err) { } catch (Error err) {
printf("ERR:%d\n", err); printf("ERR:%d\n", err);
} catch (...) { } catch (...) {

View file

@ -109,7 +109,7 @@ int main()
printf("mode=%d\n", mode); printf("mode=%d\n", mode);
for (int grow = 0; grow < 2; grow++) { for (int grow = 0; grow < 2; grow++) {
printf("auto grow=%s\n", grow ? "on" : "off"); printf("auto grow=%s\n", grow ? "on" : "off");
Code c(mode, grow ? 10 : 4096, grow ? Xbyak::AutoGrow : 0); Code c(mode, grow ? 30 : 4096, grow ? Xbyak::AutoGrow : 0);
int (*f)(int) = c.getCode<int (*)(int)>(); int (*f)(int) = c.getCode<int (*)(int)>();
c.ready(); c.ready();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
@ -123,6 +123,6 @@ int main()
} }
} }
puts("ok"); puts("ok");
} catch (Xbyak::Error e) { } catch (std::exception& e) {
printf("ERR %s\n", Xbyak::ConvertErrorToString(e)); printf("ERR %s\n", e.what());
} }

View file

@ -111,8 +111,8 @@ int main()
y = (a.*p)(t1, t2, t3, t4, t5); y = (a.*p)(t1, t2, t3, t4, t5);
printf("%c %d, %d\n", x == y ? 'o' : 'x', x, y); printf("%c %d, %d\n", x == y ? 'o' : 'x', x, y);
} }
} catch (Xbyak::Error& e) { } catch (std::exception& e) {
printf("err=%s\n", Xbyak::ConvertErrorToString(e)); printf("err=%s\n", e.what());
return 1; return 1;
} }
} }

View file

@ -150,12 +150,15 @@ void quantize(uint32 dest[64], const uint32 src[64], const uint32 qTbl[64])
} }
} }
int main(int argc, char *argv[])
{
#ifdef XBYAK64 #ifdef XBYAK64
int main()
{
puts("not implemented for 64bit"); puts("not implemented for 64bit");
return 1; return 1;
#endif }
#else
int main(int argc, char *argv[])
{
int q; int q;
if (argc > 1) { if (argc > 1) {
q = atoi(argv[1]); q = atoi(argv[1]);
@ -217,9 +220,10 @@ int main(int argc, char *argv[])
quantize2(dest, src, qTbl); quantize2(dest, src, qTbl);
} }
printf("time=%.1fsec\n", (clock() - begin) / double(CLOCKS_PER_SEC)); printf("time=%.1fsec\n", (clock() - begin) / double(CLOCKS_PER_SEC));
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }
} }
#endif

View file

@ -10,9 +10,9 @@ struct Code : public Xbyak::CodeGenerator {
{ {
// see xbyak/sample/sf_test.cpp for how to use other parameter // see xbyak/sample/sf_test.cpp for how to use other parameter
Xbyak::util::StackFrame sf(this, 3); Xbyak::util::StackFrame sf(this, 3);
mov(rax, sf.p(0)); mov(rax, sf.p[0]);
add(rax, sf.p(1)); add(rax, sf.p[1]);
add(rax, sf.p(2)); add(rax, sf.p[2]);
} }
}; };

View file

@ -170,8 +170,8 @@ int main()
} }
puts("OK"); puts("OK");
testReset(); testReset();
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -324,8 +324,8 @@ int main()
clk.end(); clk.end();
printf("native C %.2fKclk\n", clk.getClock() * 1e-3); printf("native C %.2fKclk\n", clk.getClock() * 1e-3);
} }
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -576,8 +576,8 @@ int main()
puts("test MovLabelCode:grow"); puts("test MovLabelCode:grow");
testMovLabel(true); testMovLabel(true);
testMovLabel2(); testMovLabel2();
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -29,8 +29,8 @@ int main()
try { try {
Sample s; Sample s;
s.gen(); s.gen();
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -328,8 +328,8 @@ int main()
testPartial(); testPartial();
testPack(); testPack();
printf("errNum=%d\n", errNum); printf("errNum=%d\n", errNum);
} catch (const Xbyak::Error& e) { } catch (std::exception& e) {
printf("err %s\n", Xbyak::ConvertErrorToString(e)); printf("err %s\n", e.what());
return 1; return 1;
} catch (...) { } catch (...) {
puts("ERR"); puts("ERR");

View file

@ -70,8 +70,8 @@ int main(int argc, char *argv[])
test0.joinThread(); test0.joinThread();
test1.joinThread(); test1.joinThread();
} catch (Xbyak::Error err) { } catch (std::exception& e) {
printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err); printf("ERR:%s\n", e.what());
} catch (...) { } catch (...) {
printf("unknown error\n"); printf("unknown error\n");
} }

View file

@ -85,7 +85,7 @@ namespace Xbyak {
enum { enum {
DEFAULT_MAX_CODE_SIZE = 4096, DEFAULT_MAX_CODE_SIZE = 4096,
VERSION = 0x4002 /* 0xABCD = A.BC(D) */ VERSION = 0x4100 /* 0xABCD = A.BC(D) */
}; };
#ifndef MIE_INTEGER_TYPE_DEFINED #ifndef MIE_INTEGER_TYPE_DEFINED
@ -113,7 +113,7 @@ typedef unsigned char uint8;
#define MIE_PACK(x, y, z, w) ((x) * 64 + (y) * 16 + (z) * 4 + (w)) #define MIE_PACK(x, y, z, w) ((x) * 64 + (y) * 16 + (z) * 4 + (w))
#endif #endif
enum Error { enum {
ERR_NONE = 0, ERR_NONE = 0,
ERR_BAD_ADDRESSING, ERR_BAD_ADDRESSING,
ERR_CODE_IS_TOO_BIG, ERR_CODE_IS_TOO_BIG,
@ -145,41 +145,58 @@ enum Error {
ERR_INTERNAL ERR_INTERNAL
}; };
class Error : public std::exception {
int err_;
public:
explicit Error(int err) : err_(err)
{
if (err_ < 0 || err_ > ERR_INTERNAL) {
fprintf(stderr, "bad err=%d in Xbyak::Error\n", err_);
exit(1);
}
}
operator int() const { return err_; }
const char *what() const throw()
{
static const char errTbl[][40] = {
"none",
"bad addressing",
"code is too big",
"bad scale",
"esp can't be index",
"bad combination",
"bad size of register",
"imm is too big",
"bad align",
"label is redefined",
"label is too far",
"label is not found",
"code is not copyable",
"bad parameter",
"can't protect",
"can't use 64bit disp(use (void*))",
"offset is too big",
"MEM size is not specified",
"bad mem size",
"bad st combination",
"over local label",
"under local label",
"can't alloc",
"T_SHORT is not supported in AutoGrow",
"bad protect mode",
"bad pNum",
"bad tNum",
"bad vsib addressing",
"internal error",
};
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
return errTbl[err_];
}
};
inline const char *ConvertErrorToString(Error err) inline const char *ConvertErrorToString(Error err)
{ {
static const char errTbl[][40] = { return err.what();
"none",
"bad addressing",
"code is too big",
"bad scale",
"esp can't be index",
"bad combination",
"bad size of register",
"imm is too big",
"bad align",
"label is redefined",
"label is too far",
"label is not found",
"code is not copyable",
"bad parameter",
"can't protect",
"can't use 64bit disp(use (void*))",
"offset is too big",
"MEM size is not specified",
"bad mem size",
"bad st combination",
"over local label",
"under local label",
"can't alloc",
"T_SHORT is not supported in AutoGrow",
"bad protect mode",
"bad pNum",
"bad tNum",
"bad vsib addressing",
"internal error",
};
if (err < 0 || err > ERR_INTERNAL) return 0;
return errTbl[err];
} }
inline void *AlignedMalloc(size_t size, size_t alignment) inline void *AlignedMalloc(size_t size, size_t alignment)
@ -222,7 +239,7 @@ inline bool IsInInt32(uint64 x) { return ~uint64(0x7fffffffu) <= x || x <= 0x7FF
inline uint32 VerifyInInt32(uint64 x) inline uint32 VerifyInInt32(uint64 x)
{ {
#ifdef XBYAK64 #ifdef XBYAK64
if (!IsInInt32(x)) throw ERR_OFFSET_IS_TOO_BIG; if (!IsInInt32(x)) throw Error(ERR_OFFSET_IS_TOO_BIG);
#endif #endif
return static_cast<uint32>(x); return static_cast<uint32>(x);
} }
@ -327,7 +344,7 @@ public:
static const char tbl[8][4] = { "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7" }; static const char tbl[8][4] = { "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7" };
return tbl[idx]; return tbl[idx];
} }
throw ERR_INTERNAL; throw Error(ERR_INTERNAL);
} }
bool operator==(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_; } bool operator==(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_; }
bool operator!=(const Operand& rhs) const { return !operator==(rhs); } bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
@ -394,7 +411,7 @@ private:
return Reg32e(a, b.index_, b.scale_, a.disp_ + b.disp_); return Reg32e(a, b.index_, b.scale_, a.disp_ + b.disp_);
} }
} }
throw ERR_BAD_ADDRESSING; throw Error(ERR_BAD_ADDRESSING);
} }
friend Reg32e operator*(const Reg32e& r, int scale) friend Reg32e operator*(const Reg32e& r, int scale)
{ {
@ -405,7 +422,7 @@ private:
return Reg32e(Reg(), r, scale, r.disp_); return Reg32e(Reg(), r, scale, r.disp_);
} }
} }
throw ERR_BAD_SCALE; throw Error(ERR_BAD_SCALE);
} }
friend Reg32e operator+(const Reg32e& r, unsigned int disp) friend Reg32e operator+(const Reg32e& r, unsigned int disp)
{ {
@ -433,9 +450,9 @@ public:
, scale_(scale) , scale_(scale)
, disp_(disp) , disp_(disp)
{ {
if (scale != 0 && scale != 1 && scale != 2 && scale != 4 && scale != 8) throw ERR_BAD_SCALE; if (scale != 0 && scale != 1 && scale != 2 && scale != 4 && scale != 8) throw Error(ERR_BAD_SCALE);
if (!base.isNone() && !index.isNone() && base.getBit() != index.getBit()) throw ERR_BAD_COMBINATION; if (!base.isNone() && !index.isNone() && base.getBit() != index.getBit()) throw Error(ERR_BAD_COMBINATION);
if (!allowUseEspIndex && index.getIdx() == Operand::ESP) throw ERR_ESP_CANT_BE_INDEX; if (!allowUseEspIndex && index.getIdx() == Operand::ESP) throw Error(ERR_ESP_CANT_BE_INDEX);
} }
Reg32e optimize() const // select smaller size Reg32e optimize() const // select smaller size
{ {
@ -488,7 +505,7 @@ struct Vsib {
public: public:
static inline void verifyScale(int scale) static inline void verifyScale(int scale)
{ {
if (scale != 1 && scale != 2 && scale != 4 && scale != 8) throw ERR_BAD_SCALE; if (scale != 1 && scale != 2 && scale != 4 && scale != 8) throw Error(ERR_BAD_SCALE);
} }
int getIndexIdx() const { return indexIdx_; } int getIndexIdx() const { return indexIdx_; }
int getScale() const { return scale_; } int getScale() const { return scale_; }
@ -517,7 +534,7 @@ inline Vsib operator+(const Xmm& x, uint32 disp)
} }
inline Vsib operator+(const Xmm& x, const Reg32e& r) inline Vsib operator+(const Xmm& x, const Reg32e& r)
{ {
if (!r.index_.isNone()) throw ERR_BAD_COMBINATION; if (!r.index_.isNone()) throw Error(ERR_BAD_COMBINATION);
return Vsib(x.getIdx(), 1, x.isYMM(), r.getIdx(), r.getBit(), r.disp_); return Vsib(x.getIdx(), 1, x.isYMM(), r.getIdx(), r.getBit(), r.disp_);
} }
inline Vsib operator+(const Vsib& vs, uint32 disp) inline Vsib operator+(const Vsib& vs, uint32 disp)
@ -528,7 +545,7 @@ inline Vsib operator+(const Vsib& vs, uint32 disp)
} }
inline Vsib operator+(const Vsib& vs, const Reg32e& r) inline Vsib operator+(const Vsib& vs, const Reg32e& r)
{ {
if (vs.getBaseBit() || !r.index_.isNone()) throw ERR_BAD_COMBINATION; if (vs.getBaseBit() || !r.index_.isNone()) throw Error(ERR_BAD_COMBINATION);
Vsib ret(vs); Vsib ret(vs);
ret.baseIdx_ = (uint8)r.getIdx(); ret.baseIdx_ = (uint8)r.getIdx();
ret.baseBit_ = (uint8)r.getBit(); ret.baseBit_ = (uint8)r.getBit();
@ -594,7 +611,7 @@ protected:
{ {
const size_t newSize = (std::max<size_t>)(DEFAULT_MAX_CODE_SIZE, maxSize_ * 2); const size_t newSize = (std::max<size_t>)(DEFAULT_MAX_CODE_SIZE, maxSize_ * 2);
uint8 *newTop = alloc_->alloc(newSize); uint8 *newTop = alloc_->alloc(newSize);
if (newTop == 0) throw ERR_CANT_ALLOC; if (newTop == 0) throw Error(ERR_CANT_ALLOC);
for (size_t i = 0; i < size_; i++) newTop[i] = top_[i]; for (size_t i = 0; i < size_; i++) newTop[i] = top_[i];
alloc_->free(top_); alloc_->free(top_);
top_ = newTop; top_ = newTop;
@ -609,7 +626,7 @@ protected:
uint64 disp = i->getVal(top_); uint64 disp = i->getVal(top_);
rewrite(i->codeOffset, disp, i->jmpSize); rewrite(i->codeOffset, disp, i->jmpSize);
} }
if (alloc_->useProtect() && !protect(top_, size_, true)) throw ERR_CANT_PROTECT; if (alloc_->useProtect() && !protect(top_, size_, true)) throw Error(ERR_CANT_PROTECT);
} }
public: public:
CodeArray(size_t maxSize = MAX_FIXED_BUF_SIZE, void *userPtr = 0, Allocator *allocator = 0) CodeArray(size_t maxSize = MAX_FIXED_BUF_SIZE, void *userPtr = 0, Allocator *allocator = 0)
@ -619,10 +636,10 @@ public:
, top_(isAllocType() ? alloc_->alloc((std::max<size_t>)(maxSize, 1)) : type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : buf_) , top_(isAllocType() ? alloc_->alloc((std::max<size_t>)(maxSize, 1)) : type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : buf_)
, size_(0) , size_(0)
{ {
if (maxSize_ > 0 && top_ == 0) throw ERR_CANT_ALLOC; if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, true)) { if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, true)) {
alloc_->free(top_); alloc_->free(top_);
throw ERR_CANT_PROTECT; throw Error(ERR_CANT_PROTECT);
} }
} }
virtual ~CodeArray() virtual ~CodeArray()
@ -639,7 +656,7 @@ public:
, top_(buf_) , top_(buf_)
, size_(rhs.size_) , size_(rhs.size_)
{ {
if (type_ != FIXED_BUF) throw ERR_CODE_ISNOT_COPYABLE; if (type_ != FIXED_BUF) throw Error(ERR_CODE_ISNOT_COPYABLE);
for (size_t i = 0; i < size_; i++) top_[i] = rhs.top_[i]; for (size_t i = 0; i < size_; i++) top_[i] = rhs.top_[i];
} }
void resetSize() void resetSize()
@ -653,7 +670,7 @@ public:
if (type_ == AUTO_GROW) { if (type_ == AUTO_GROW) {
growMemory(); growMemory();
} else { } else {
throw ERR_CODE_IS_TOO_BIG; throw Error(ERR_CODE_IS_TOO_BIG);
} }
} }
top_[size_++] = static_cast<uint8>(code); top_[size_++] = static_cast<uint8>(code);
@ -664,7 +681,7 @@ public:
} }
void db(uint64 code, int codeSize) void db(uint64 code, int codeSize)
{ {
if (codeSize > 8) throw ERR_BAD_PARAMETER; if (codeSize > 8) throw Error(ERR_BAD_PARAMETER);
for (int i = 0; i < codeSize; i++) db(static_cast<uint8>(code >> (i * 8))); for (int i = 0; i < codeSize; i++) db(static_cast<uint8>(code >> (i * 8)));
} }
void dw(uint32 code) { db(code, 2); } void dw(uint32 code) { db(code, 2); }
@ -678,7 +695,7 @@ public:
size_t getSize() const { return size_; } size_t getSize() const { return size_; }
void setSize(size_t size) void setSize(size_t size)
{ {
if (size >= maxSize_) throw ERR_OFFSET_IS_TOO_BIG; if (size >= maxSize_) throw Error(ERR_OFFSET_IS_TOO_BIG);
size_ = size; size_ = size;
} }
void dump() const void dump() const
@ -711,7 +728,7 @@ public:
void rewrite(size_t offset, uint64 disp, size_t size) void rewrite(size_t offset, uint64 disp, size_t size)
{ {
assert(offset < maxSize_); assert(offset < maxSize_);
if (size != 1 && size != 2 && size != 4 && size != 8) throw ERR_BAD_PARAMETER; if (size != 1 && size != 2 && size != 4 && size != 8) throw Error(ERR_BAD_PARAMETER);
uint8 *const data = top_ + offset; uint8 *const data = top_ + offset;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
data[i] = static_cast<uint8>(disp >> (i * 8)); data[i] = static_cast<uint8>(disp >> (i * 8));
@ -768,7 +785,7 @@ class Address : public Operand, public CodeArray {
bool is64bitDisp_; bool is64bitDisp_;
mutable bool isVsib_; mutable bool isVsib_;
bool isYMM_; bool isYMM_;
void verify() const { if (isVsib_) throw ERR_BAD_VSIB_ADDRESSING; } void verify() const { if (isVsib_) throw Error(ERR_BAD_VSIB_ADDRESSING); }
const bool is32bit_; const bool is32bit_;
public: public:
Address(uint32 sizeBit, bool isOnlyDisp, uint64 disp, bool is32bit, bool is64bitDisp = false, bool isVsib = false, bool isYMM = false) Address(uint32 sizeBit, bool isOnlyDisp, uint64 disp, bool is32bit, bool is64bitDisp = false, bool isVsib = false, bool isYMM = false)
@ -842,7 +859,7 @@ public:
{ {
size_t adr = reinterpret_cast<size_t>(disp); size_t adr = reinterpret_cast<size_t>(disp);
#ifdef XBYAK64 #ifdef XBYAK64
if (adr > 0xFFFFFFFFU) throw ERR_OFFSET_IS_TOO_BIG; if (adr > 0xFFFFFFFFU) throw Error(ERR_OFFSET_IS_TOO_BIG);
#endif #endif
Reg32e r(Reg(), Reg(), 0, static_cast<uint32>(adr)); Reg32e r(Reg(), Reg(), 0, static_cast<uint32>(adr));
return operator[](r); return operator[](r);
@ -955,12 +972,12 @@ public:
} }
void enterLocal() void enterLocal()
{ {
if (stackPos_ == maxStack) throw ERR_OVER_LOCAL_LABEL; if (stackPos_ == maxStack) throw Error(ERR_OVER_LOCAL_LABEL);
localCount_ = stack_[stackPos_++] = ++usedCount_; localCount_ = stack_[stackPos_++] = ++usedCount_;
} }
void leaveLocal() void leaveLocal()
{ {
if (stackPos_ == 1) throw ERR_UNDER_LOCAL_LABEL; if (stackPos_ == 1) throw Error(ERR_UNDER_LOCAL_LABEL);
localCount_ = stack_[--stackPos_ - 1]; localCount_ = stack_[--stackPos_ - 1];
} }
void set(CodeArray *base) { base_ = base; } void set(CodeArray *base) { base_ = base; }
@ -976,7 +993,7 @@ public:
// add label // add label
DefinedList::value_type item(label, addrOffset); DefinedList::value_type item(label, addrOffset);
std::pair<DefinedList::iterator, bool> ret = definedList_.insert(item); std::pair<DefinedList::iterator, bool> ret = definedList_.insert(item);
if (!ret.second) throw ERR_LABEL_IS_REDEFINED; if (!ret.second) throw Error(ERR_LABEL_IS_REDEFINED);
// search undefined label // search undefined label
for (;;) { for (;;) {
UndefinedList::iterator itr = undefinedList_.find(label); UndefinedList::iterator itr = undefinedList_.find(label);
@ -991,7 +1008,7 @@ public:
} else { } else {
disp = addrOffset - jmp->endOfJmp; disp = addrOffset - jmp->endOfJmp;
if (jmp->jmpSize <= 4) disp = inner::VerifyInInt32(disp); if (jmp->jmpSize <= 4) disp = inner::VerifyInInt32(disp);
if (jmp->jmpSize == 1 && !inner::IsInDisp8((uint32)disp)) throw ERR_LABEL_IS_TOO_FAR; if (jmp->jmpSize == 1 && !inner::IsInDisp8((uint32)disp)) throw Error(ERR_LABEL_IS_TOO_FAR);
} }
if (base_->isAutoGrow()) { if (base_->isAutoGrow()) {
base_->save(offset, disp, jmp->jmpSize, jmp->mode); base_->save(offset, disp, jmp->jmpSize, jmp->mode);
@ -1088,7 +1105,7 @@ private:
uint8 rex = 0; uint8 rex = 0;
const Operand *p1 = &op1, *p2 = &op2; const Operand *p1 = &op1, *p2 = &op2;
if (p1->isMEM()) std::swap(p1, p2); if (p1->isMEM()) std::swap(p1, p2);
if (p1->isMEM()) throw ERR_BAD_COMBINATION; if (p1->isMEM()) throw Error(ERR_BAD_COMBINATION);
if (p2->isMEM()) { if (p2->isMEM()) {
const Address& addr = static_cast<const Address&>(*p2); const Address& addr = static_cast<const Address&>(*p2);
if (BIT == 64 && addr.is32bit()) db(0x67); if (BIT == 64 && addr.is32bit()) db(0x67);
@ -1133,7 +1150,7 @@ private:
} }
void opModM(const Address& addr, const Reg& reg, int code0, int code1 = NONE, int code2 = NONE) void opModM(const Address& addr, const Reg& reg, int code0, int code1 = NONE, int code2 = NONE)
{ {
if (addr.is64bitDisp()) throw ERR_CANT_USE_64BIT_DISP; if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
rex(addr, reg); rex(addr, reg);
db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2); db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
addr.updateRegField(static_cast<uint8>(reg.getIdx())); addr.updateRegField(static_cast<uint8>(reg.getIdx()));
@ -1147,7 +1164,7 @@ private:
if (type != T_NEAR && inner::IsInDisp8(disp - shortJmpSize)) { if (type != T_NEAR && inner::IsInDisp8(disp - shortJmpSize)) {
db(shortCode); db(disp - shortJmpSize); db(shortCode); db(disp - shortJmpSize);
} else { } else {
if (type == T_SHORT) throw ERR_LABEL_IS_TOO_FAR; if (type == T_SHORT) throw Error(ERR_LABEL_IS_TOO_FAR);
if (longPref) db(longPref); if (longPref) db(longPref);
db(longCode); dd(disp - longJmpSize); db(longCode); dd(disp - longJmpSize);
} }
@ -1176,7 +1193,7 @@ private:
void opJmpAbs(const void *addr, LabelType type, uint8 shortCode, uint8 longCode) void opJmpAbs(const void *addr, LabelType type, uint8 shortCode, uint8 longCode)
{ {
if (isAutoGrow()) { if (isAutoGrow()) {
if (type != T_NEAR) throw ERR_ONLY_T_NEAR_IS_SUPPORTED_IN_AUTO_GROW; if (type != T_NEAR) throw Error(ERR_ONLY_T_NEAR_IS_SUPPORTED_IN_AUTO_GROW);
if (size_ + 16 >= maxSize_) growMemory(); if (size_ + 16 >= maxSize_) growMemory();
db(longCode); db(longCode);
dd(0); dd(0);
@ -1189,7 +1206,7 @@ private:
/* preCode is for SSSE3/SSE4 */ /* preCode is for SSSE3/SSE4 */
void opGen(const Operand& reg, const Operand& op, int code, int pref, bool isValid(const Operand&, const Operand&), int imm8 = NONE, int preCode = NONE) void opGen(const Operand& reg, const Operand& op, int code, int pref, bool isValid(const Operand&, const Operand&), int imm8 = NONE, int preCode = NONE)
{ {
if (isValid && !isValid(reg, op)) throw ERR_BAD_COMBINATION; if (isValid && !isValid(reg, op)) throw Error(ERR_BAD_COMBINATION);
if (pref != NONE) db(pref); if (pref != NONE) db(pref);
if (op.isMEM()) { if (op.isMEM()) {
opModM(static_cast<const Address&>(op), static_cast<const Reg&>(reg), 0x0F, preCode, code); opModM(static_cast<const Address&>(op), static_cast<const Reg&>(reg), 0x0F, preCode, code);
@ -1216,7 +1233,7 @@ private:
} else if (op1.isMEM() && op2.isXMM()) { } else if (op1.isMEM() && op2.isXMM()) {
opModM(static_cast<const Address&>(op1), static_cast<const Reg&>(op2), 0x0F, code | 1); opModM(static_cast<const Address&>(op1), static_cast<const Reg&>(op2), 0x0F, code | 1);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} }
void opExt(const Operand& op, const Mmx& mmx, int code, int imm, bool hasMMX2 = false) void opExt(const Operand& op, const Mmx& mmx, int code, int imm, bool hasMMX2 = false)
@ -1237,7 +1254,7 @@ private:
} else if (op.isMEM()) { } else if (op.isMEM()) {
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, opBit), code0, code1, code2); opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, opBit), code0, code1, code2);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} }
void opShift(const Operand& op, int imm, int ext) void opShift(const Operand& op, int imm, int ext)
@ -1248,7 +1265,7 @@ private:
} }
void opShift(const Operand& op, const Reg8& cl, int ext) void opShift(const Operand& op, const Reg8& cl, int ext)
{ {
if (cl.getIdx() != Operand::CL) throw ERR_BAD_COMBINATION; if (cl.getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
opR_ModM(op, 0, ext, B11010010); opR_ModM(op, 0, ext, B11010010);
} }
void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE) void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE)
@ -1258,12 +1275,12 @@ private:
} else if (condM) { } else if (condM) {
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code0, code1, code2); opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code0, code1, code2);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} }
void opShxd(const Operand& op, const Reg& reg, uint8 imm, int code, const Reg8 *cl = 0) void opShxd(const Operand& op, const Reg& reg, uint8 imm, int code, const Reg8 *cl = 0)
{ {
if (cl && cl->getIdx() != Operand::CL) throw ERR_BAD_COMBINATION; if (cl && cl->getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), 0x0F, code | (cl ? 1 : 0)); opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), 0x0F, code | (cl ? 1 : 0));
if (!cl) db(imm); if (!cl) db(imm);
} }
@ -1282,7 +1299,7 @@ private:
verifyMemHasSize(op); verifyMemHasSize(op);
uint32 immBit = inner::IsInDisp8(imm) ? 8 : isInDisp16(imm) ? 16 : 32; uint32 immBit = inner::IsInDisp8(imm) ? 8 : isInDisp16(imm) ? 16 : 32;
if (op.isBit(8)) immBit = 8; if (op.isBit(8)) immBit = 8;
if (op.getBit() < immBit) throw ERR_IMM_IS_TOO_BIG; if (op.getBit() < immBit) throw Error(ERR_IMM_IS_TOO_BIG);
if (op.isBit(32|64) && immBit == 16) immBit = 32; /* don't use MEM16 if 32/64bit mode */ if (op.isBit(32|64) && immBit == 16) immBit = 32; /* don't use MEM16 if 32/64bit mode */
if (op.isREG() && op.getIdx() == 0 && (op.getBit() == immBit || (op.isBit(64) && immBit == 32))) { // rax, eax, ax, al if (op.isREG() && op.getIdx() == 0 && (op.getBit() == immBit || (op.isBit(64) && immBit == 32))) { // rax, eax, ax, al
rex(op); rex(op);
@ -1318,25 +1335,25 @@ private:
} else if (op.isMEM()) { } else if (op.isMEM()) {
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, op.getBit()), code); opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, op.getBit()), code);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} }
void verifyMemHasSize(const Operand& op) const void verifyMemHasSize(const Operand& op) const
{ {
if (op.isMEM() && op.getBit() == 0) throw ERR_MEM_SIZE_IS_NOT_SPECIFIED; if (op.isMEM() && op.getBit() == 0) throw Error(ERR_MEM_SIZE_IS_NOT_SPECIFIED);
} }
void opMovxx(const Reg& reg, const Operand& op, uint8 code) void opMovxx(const Reg& reg, const Operand& op, uint8 code)
{ {
if (op.isBit(32)) throw ERR_BAD_COMBINATION; if (op.isBit(32)) throw Error(ERR_BAD_COMBINATION);
int w = op.isBit(16); int w = op.isBit(16);
bool cond = reg.isREG() && (reg.getBit() > op.getBit()); bool cond = reg.isREG() && (reg.getBit() > op.getBit());
opModRM(reg, op, cond && op.isREG(), cond && op.isMEM(), 0x0F, code | w); opModRM(reg, op, cond && op.isREG(), cond && op.isMEM(), 0x0F, code | w);
} }
void opFpuMem(const Address& addr, uint8 m16, uint8 m32, uint8 m64, uint8 ext, uint8 m64ext) void opFpuMem(const Address& addr, uint8 m16, uint8 m32, uint8 m64, uint8 ext, uint8 m64ext)
{ {
if (addr.is64bitDisp()) throw ERR_CANT_USE_64BIT_DISP; if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
uint8 code = addr.isBit(16) ? m16 : addr.isBit(32) ? m32 : addr.isBit(64) ? m64 : 0; uint8 code = addr.isBit(16) ? m16 : addr.isBit(32) ? m32 : addr.isBit(64) ? m64 : 0;
if (!code) throw ERR_BAD_MEM_SIZE; if (!code) throw Error(ERR_BAD_MEM_SIZE);
if (m64ext && addr.isBit(64)) ext = m64ext; if (m64ext && addr.isBit(64)) ext = m64ext;
rex(addr, st0); rex(addr, st0);
@ -1349,7 +1366,7 @@ private:
void opFpuFpu(const Fpu& reg1, const Fpu& reg2, uint32 code1, uint32 code2) void opFpuFpu(const Fpu& reg1, const Fpu& reg2, uint32 code1, uint32 code2)
{ {
uint32 code = reg1.getIdx() == 0 ? code1 : reg2.getIdx() == 0 ? code2 : 0; uint32 code = reg1.getIdx() == 0 ? code1 : reg2.getIdx() == 0 ? code2 : 0;
if (!code) throw ERR_BAD_ST_COMBINATION; if (!code) throw Error(ERR_BAD_ST_COMBINATION);
db(uint8(code >> 8)); db(uint8(code >> 8));
db(uint8(code | (reg1.getIdx() | reg2.getIdx()))); db(uint8(code | (reg1.getIdx() | reg2.getIdx())));
} }
@ -1390,7 +1407,7 @@ private:
const Operand *p2 = &op2; const Operand *p2 = &op2;
if (!isR_R_RM) std::swap(p1, p2); if (!isR_R_RM) std::swap(p1, p2);
const unsigned int bit = r.getBit(); const unsigned int bit = r.getBit();
if (p1->getBit() != bit || (p2->isREG() && p2->getBit() != bit)) throw ERR_BAD_COMBINATION; if (p1->getBit() != bit || (p2->isREG() && p2->getBit() != bit)) throw Error(ERR_BAD_COMBINATION);
int w = bit == 64; int w = bit == 64;
opVex(r, p1, p2, type, code, w); opVex(r, p1, p2, type, code, w);
} }
@ -1402,12 +1419,12 @@ private:
x2 = &x1; x2 = &x1;
op = &op1; op = &op1;
} else { } else {
if (!(op1.isXMM() || (supportYMM && op1.isYMM()))) throw ERR_BAD_COMBINATION; if (!(op1.isXMM() || (supportYMM && op1.isYMM()))) throw Error(ERR_BAD_COMBINATION);
x2 = static_cast<const Xmm*>(&op1); x2 = static_cast<const Xmm*>(&op1);
op = &op2; op = &op2;
} }
// (x1, x2, op) // (x1, x2, op)
if (!((x1.isXMM() && x2->isXMM()) || (supportYMM && x1.isYMM() && x2->isYMM()))) throw ERR_BAD_COMBINATION; if (!((x1.isXMM() && x2->isXMM()) || (supportYMM && x1.isYMM() && x2->isYMM()))) throw Error(ERR_BAD_COMBINATION);
opVex(x1, x2, op, type, code0, w); opVex(x1, x2, op, type, code0, w);
} }
// if cvt then return pointer to Xmm(idx) (or Ymm(idx)), otherwise return op // if cvt then return pointer to Xmm(idx) (or Ymm(idx)), otherwise return op
@ -1424,15 +1441,15 @@ private:
// QQQ:need to refactor // QQQ:need to refactor
void opSp1(const Reg& reg, const Operand& op, uint8 pref, uint8 code0, uint8 code1) void opSp1(const Reg& reg, const Operand& op, uint8 pref, uint8 code0, uint8 code1)
{ {
if (reg.isBit(8)) throw ERR_BAD_SIZE_OF_REGISTER; if (reg.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER);
bool is16bit = reg.isREG(16) && (op.isREG(16) || op.isMEM()); bool is16bit = reg.isREG(16) && (op.isREG(16) || op.isMEM());
if (!is16bit && !(reg.isREG(i32e) && (op.isREG(reg.getBit()) || op.isMEM()))) throw ERR_BAD_COMBINATION; if (!is16bit && !(reg.isREG(i32e) && (op.isREG(reg.getBit()) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION);
if (is16bit) db(0x66); if (is16bit) db(0x66);
db(pref); opModRM(reg.changeBit(i32e == 32 ? 32 : reg.getBit()), op, op.isREG(), true, code0, code1); db(pref); opModRM(reg.changeBit(i32e == 32 ? 32 : reg.getBit()), op, op.isREG(), true, code0, code1);
} }
void opGather(const Xmm& x1, const Address& addr, const Xmm& x2, int type, uint8 code, int w, int mode) void opGather(const Xmm& x1, const Address& addr, const Xmm& x2, int type, uint8 code, int w, int mode)
{ {
if (!addr.isVsib()) throw ERR_BAD_VSIB_ADDRESSING; if (!addr.isVsib()) throw Error(ERR_BAD_VSIB_ADDRESSING);
const int y_vx_y = 0; const int y_vx_y = 0;
const int y_vy_y = 1; const int y_vy_y = 1;
// const int x_vy_x = 2; // const int x_vy_x = 2;
@ -1446,7 +1463,7 @@ private:
} else { // x_vy_x } else { // x_vy_x
isOK = !x1.isYMM() && isAddrYMM && !x2.isYMM(); isOK = !x1.isYMM() && isAddrYMM && !x2.isYMM();
} }
if (!isOK) throw ERR_BAD_VSIB_ADDRESSING; if (!isOK) throw Error(ERR_BAD_VSIB_ADDRESSING);
} }
addr.setVsib(false); addr.setVsib(false);
opAVX_X_X_XM(isAddrYMM ? Ymm(x1.getIdx()) : x1, isAddrYMM ? Ymm(x2.getIdx()) : x2, addr, type, code, true, w); opAVX_X_X_XM(isAddrYMM ? Ymm(x1.getIdx()) : x1, isAddrYMM ? Ymm(x2.getIdx()) : x2, addr, type, code, true, w);
@ -1589,7 +1606,7 @@ public:
db(reg1.isREG(8) ? 0xA0 : reg1.isREG() ? 0xA1 : reg2.isREG(8) ? 0xA2 : 0xA3); db(reg1.isREG(8) ? 0xA0 : reg1.isREG() ? 0xA1 : reg2.isREG(8) ? 0xA2 : 0xA3);
db(addr->getDisp(), 8); db(addr->getDisp(), 8);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} else } else
#else #else
@ -1634,7 +1651,7 @@ public:
int size = op.getBit() / 8; if (size > 4) size = 4; int size = op.getBit() / 8; if (size > 4) size = 4;
db(static_cast<uint32>(imm), size); db(static_cast<uint32>(imm), size);
} else { } else {
throw ERR_BAD_COMBINATION; throw Error(ERR_BAD_COMBINATION);
} }
} }
// QQQ : rewrite this function with putL // QQQ : rewrite this function with putL
@ -1713,7 +1730,7 @@ public:
if (p1->isMEM() || (p2->isREG(16 | i32e) && p2->getIdx() == 0)) { if (p1->isMEM() || (p2->isREG(16 | i32e) && p2->getIdx() == 0)) {
p1 = &op2; p2 = &op1; p1 = &op2; p2 = &op1;
} }
if (p1->isMEM()) throw ERR_BAD_COMBINATION; if (p1->isMEM()) throw Error(ERR_BAD_COMBINATION);
if (p2->isREG() && (p1->isREG(16 | i32e) && p1->getIdx() == 0) if (p2->isREG() && (p1->isREG(16 | i32e) && p1->getIdx() == 0)
#ifdef XBYAK64 #ifdef XBYAK64
&& (p2->getIdx() != 0 || !p1->isREG(32)) && (p2->getIdx() != 0 || !p1->isREG(32))
@ -1784,17 +1801,17 @@ public:
} }
void pextrq(const Operand& op, const Xmm& xmm, uint8 imm) void pextrq(const Operand& op, const Xmm& xmm, uint8 imm)
{ {
if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION);
opGen(Reg64(xmm.getIdx()), op, 0x16, 0x66, 0, imm, B00111010); // force to 64bit opGen(Reg64(xmm.getIdx()), op, 0x16, 0x66, 0, imm, B00111010); // force to 64bit
} }
void pinsrq(const Xmm& xmm, const Operand& op, uint8 imm) void pinsrq(const Xmm& xmm, const Operand& op, uint8 imm)
{ {
if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION);
opGen(Reg64(xmm.getIdx()), op, 0x22, 0x66, 0, imm, B00111010); // force to 64bit opGen(Reg64(xmm.getIdx()), op, 0x22, 0x66, 0, imm, B00111010); // force to 64bit
} }
void movsxd(const Reg64& reg, const Operand& op) void movsxd(const Reg64& reg, const Operand& op)
{ {
if (!op.isBit(32)) throw ERR_BAD_COMBINATION; if (!op.isBit(32)) throw Error(ERR_BAD_COMBINATION);
opModRM(reg, op, op.isREG(), op.isMEM(), 0x63); opModRM(reg, op, op.isREG(), op.isMEM(), 0x63);
} }
#endif #endif
@ -1806,7 +1823,7 @@ public:
void extractps(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x17, imm); } void extractps(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x17, imm); }
void pinsrw(const Mmx& mmx, const Operand& op, int imm) void pinsrw(const Mmx& mmx, const Operand& op, int imm)
{ {
if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION);
opGen(mmx, op, B11000100, mmx.isXMM() ? 0x66 : NONE, 0, imm); opGen(mmx, op, B11000100, mmx.isXMM() ? 0x66 : NONE, 0, imm);
} }
void insertps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, imm, B00111010); } void insertps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, imm, B00111010); }
@ -1820,7 +1837,7 @@ public:
} }
void maskmovq(const Mmx& reg1, const Mmx& reg2) void maskmovq(const Mmx& reg1, const Mmx& reg2)
{ {
if (!reg1.isMMX() || !reg2.isMMX()) throw ERR_BAD_COMBINATION; if (!reg1.isMMX() || !reg2.isMMX()) throw Error(ERR_BAD_COMBINATION);
opModR(reg1, reg2, 0x0F, B11110111); opModR(reg1, reg2, 0x0F, B11110111);
} }
void lea(const Reg32e& reg, const Address& addr) { opModM(addr, reg, B10001101); } void lea(const Reg32e& reg, const Address& addr) { opModM(addr, reg, B10001101); }
@ -1833,7 +1850,7 @@ public:
void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, 0x0F, B11000011); } void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, 0x0F, B11000011); }
void movntq(const Address& addr, const Mmx& mmx) void movntq(const Address& addr, const Mmx& mmx)
{ {
if (!mmx.isMMX()) throw ERR_BAD_COMBINATION; if (!mmx.isMMX()) throw Error(ERR_BAD_COMBINATION);
opModM(addr, mmx, 0x0F, B11100111); opModM(addr, mmx, 0x0F, B11100111);
} }
void crc32(const Reg32e& reg, const Operand& op) void crc32(const Reg32e& reg, const Operand& op)
@ -1842,7 +1859,7 @@ public:
db(0xF2); db(0xF2);
opModRM(reg, op, op.isREG(), op.isMEM(), 0x0F, 0x38, 0xF0 | (op.isBit(8) ? 0 : 1)); opModRM(reg, op, op.isREG(), op.isMEM(), 0x0F, 0x38, 0xF0 | (op.isBit(8) ? 0 : 1));
} }
void rdrand(const Reg& r) { if (r.isBit(8)) throw ERR_BAD_SIZE_OF_REGISTER; opModR(Reg(6, Operand::REG, r.getBit()), r, 0x0f, 0xc7); } void rdrand(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(6, Operand::REG, r.getBit()), r, 0x0f, 0xc7); }
void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), MM_0F3A | PP_F2, 0xF0, false); db(imm); } void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), MM_0F3A | PP_F2, 0xF0, false); db(imm); }
enum { NONE = 256 }; enum { NONE = 256 };
CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0, Allocator *allocator = 0) CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0, Allocator *allocator = 0)
@ -1884,7 +1901,7 @@ public:
*/ */
void ready() void ready()
{ {
if (hasUndefinedLabel()) throw ERR_LABEL_IS_NOT_FOUND; if (hasUndefinedLabel()) throw Error(ERR_LABEL_IS_NOT_FOUND);
calcJmpAddress(); calcJmpAddress();
} }
#ifdef XBYAK_TEST #ifdef XBYAK_TEST
@ -1900,7 +1917,7 @@ public:
void align(int x = 16) void align(int x = 16)
{ {
if (x == 1) return; if (x == 1) return;
if (x < 1 || (x & (x - 1))) throw ERR_BAD_ALIGN; if (x < 1 || (x & (x - 1))) throw Error(ERR_BAD_ALIGN);
if (isAutoGrow() && x > (int)inner::ALIGN_PAGE_SIZE) fprintf(stderr, "warning:autoGrow mode does not support %d align\n", x); if (isAutoGrow() && x > (int)inner::ALIGN_PAGE_SIZE) fprintf(stderr, "warning:autoGrow mode does not support %d align\n", x);
while (size_t(getCurr()) % x) { while (size_t(getCurr()) % x) {
nop(); nop();

View file

@ -1,4 +1,4 @@
const char *getVersionString() const { return "4.002"; } const char *getVersionString() const { return "4.10"; }
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); }
@ -1226,13 +1226,13 @@ void vcmpgt_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x
void vcmpgt_oqss(const Xmm& x, const Operand& op) { vcmpss(x, op, 30); } void vcmpgt_oqss(const Xmm& x, const Operand& op) { vcmpss(x, op, 30); }
void vcmptrue_usss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 31); } void vcmptrue_usss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 31); }
void vcmptrue_usss(const Xmm& x, const Operand& op) { vcmpss(x, op, 31); } void vcmptrue_usss(const Xmm& x, const Operand& op) { vcmpss(x, op, 31); }
void vmovhpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x, op1, op2, MM_0F | PP_66, 0x16, false); } void vmovhpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, MM_0F | PP_66, 0x16, false); }
void vmovhpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0x17, false); } void vmovhpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0x17, false); }
void vmovhps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x, op1, op2, MM_0F, 0x16, false); } void vmovhps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, MM_0F, 0x16, false); }
void vmovhps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F, 0x17, false); } void vmovhps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F, 0x17, false); }
void vmovlpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x, op1, op2, MM_0F | PP_66, 0x12, false); } void vmovlpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, MM_0F | PP_66, 0x12, false); }
void vmovlpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0x13, false); } void vmovlpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0x13, false); }
void vmovlps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x, op1, op2, MM_0F, 0x12, false); } void vmovlps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, MM_0F, 0x12, false); }
void vmovlps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F, 0x13, false); } void vmovlps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F, 0x13, false); }
void vfmadd132pd(const Xmm& xmm, const Xmm& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, MM_0F38 | PP_66, 0x98, true, 1); } void vfmadd132pd(const Xmm& xmm, const Xmm& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, MM_0F38 | PP_66, 0x98, true, 1); }
void vfmadd213pd(const Xmm& xmm, const Xmm& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, MM_0F38 | PP_66, 0xA8, true, 1); } void vfmadd213pd(const Xmm& xmm, const Xmm& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, MM_0F38 | PP_66, 0xA8, true, 1); }
@ -1297,15 +1297,15 @@ void vfnmsub231ss(const Xmm& xmm, const Xmm& op1, const Operand& op2 = Operand()
void vaesimc(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0xDB, false, 0); } void vaesimc(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0xDB, false, 0); }
void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x1A, true, 0); } void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x1A, true, 0); }
void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x5A, true, 0); } void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, MM_0F38 | PP_66, 0x5A, true, 0); }
void vbroadcastsd(const Ymm& y, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(y, op, MM_0F38 | PP_66, 0x19, true, 0); } void vbroadcastsd(const Ymm& y, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(y, op, MM_0F38 | PP_66, 0x19, true, 0); }
void vbroadcastss(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x18, true, 0); } void vbroadcastss(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x18, true, 0); }
void vpbroadcastb(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x78, true, 0); } void vpbroadcastb(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x78, true, 0); }
void vpbroadcastw(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x79, true, 0); } void vpbroadcastw(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x79, true, 0); }
void vpbroadcastd(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x58, true, 0); } void vpbroadcastd(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x58, true, 0); }
void vpbroadcastq(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x59, true, 0); } void vpbroadcastq(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, MM_0F38 | PP_66, 0x59, true, 0); }
void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x19, true, 0); db(imm); } void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x19, true, 0); db(imm); }
void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x39, true, 0); db(imm); } void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { opAVX_X_X_XMcvt(y, y.isXMM() ? xm0 : ym0, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x39, true, 0); db(imm); }
void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!(op.isREG(32) || op.isMEM()) || x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, op.isREG(), Operand::XMM, MM_0F3A | PP_66, 0x17, false, 0); db(imm); } void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!(op.isREG(32) || op.isMEM()) || x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, op.isREG(), Operand::XMM, MM_0F3A | PP_66, 0x17, false, 0); db(imm); }
void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x18, true, 0); db(imm); } void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x18, true, 0); db(imm); }
void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x38, true, 0); db(imm); } void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XMcvt(y1, y2, op, op.isXMM(), Operand::YMM, MM_0F3A | PP_66, 0x38, true, 0); db(imm); }
void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, MM_0F3A | PP_66, 0x06, true, 0); db(imm); } void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, MM_0F3A | PP_66, 0x06, true, 0); db(imm); }
@ -1314,16 +1314,16 @@ void vlddqu(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, x.isXMM() ? xm0
void vldmxcsr(const Address& addr) { opAVX_X_X_XM(xm2, xm0, addr, MM_0F, 0xAE, false, -1); } void vldmxcsr(const Address& addr) { opAVX_X_X_XM(xm2, xm0, addr, MM_0F, 0xAE, false, -1); }
void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, MM_0F, 0xAE, false, -1); } void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, MM_0F, 0xAE, false, -1); }
void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_66, 0xF7, false, -1); } void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_66, 0xF7, false, -1); }
void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(i32e) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x14, false); db(imm); } void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(i32e) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x14, false); db(imm); }
void vpextrw(const Reg& r, const Xmm& x, uint8 imm) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, x, MM_0F | PP_66, 0xC5, false, r.isBit(64) ? 1 : 0); db(imm); } void vpextrw(const Reg& r, const Xmm& x, uint8 imm) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, x, MM_0F | PP_66, 0xC5, false, r.isBit(64) ? 1 : 0); db(imm); }
void vpextrw(const Address& addr, const Xmm& x, uint8 imm) { opAVX_X_X_XM(x, xm0, addr, MM_0F3A | PP_66, 0x15, false); db(imm); } void vpextrw(const Address& addr, const Xmm& x, uint8 imm) { opAVX_X_X_XM(x, xm0, addr, MM_0F3A | PP_66, 0x15, false); db(imm); }
void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 0); db(imm); } void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 0); db(imm); }
void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); } void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }
void vpinsrb(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); } void vpinsrb(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x20, false); db(imm); }
void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); } void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }
void vpinsrw(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); } void vpinsrw(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F | PP_66, 0xC4, false); db(imm); }
void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); } void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }
void vpinsrd(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); } void vpinsrd(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 0); db(imm); }
void vpmovmskb(const Reg32e& r, const Xmm& x) { bool isYMM= x.isYMM(); opAVX_X_X_XM(isYMM ? Ymm(r.getIdx()) : Xmm(r.getIdx()), isYMM ? ym0 : xm0, x, MM_0F | PP_66, 0xD7, true); } void vpmovmskb(const Reg32e& r, const Xmm& x) { bool isYMM= x.isYMM(); opAVX_X_X_XM(isYMM ? Ymm(r.getIdx()) : Xmm(r.getIdx()), isYMM ? ym0 : xm0, x, MM_0F | PP_66, 0xD7, true); }
void vpslldq(const Xmm& x1, const Xmm& x2, uint8 imm) { opAVX_X_X_XM(x1.isYMM() ? ym7 : xm7, x1, x2, MM_0F | PP_66, 0x73, true); db(imm); } void vpslldq(const Xmm& x1, const Xmm& x2, uint8 imm) { opAVX_X_X_XM(x1.isYMM() ? ym7 : xm7, x1, x2, MM_0F | PP_66, 0x73, true); db(imm); }
void vpslldq(const Xmm& x, uint8 imm) { opAVX_X_X_XM(x.isYMM() ? ym7 : xm7, x, x, MM_0F | PP_66, 0x73, true); db(imm); } void vpslldq(const Xmm& x, uint8 imm) { opAVX_X_X_XM(x.isYMM() ? ym7 : xm7, x, x, MM_0F | PP_66, 0x73, true); db(imm); }
@ -1358,37 +1358,37 @@ void vmovd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F
void vmovq(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x7E, false, -1); } void vmovq(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x7E, false, -1); }
void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0xD6, false, -1); } void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_66, 0xD6, false, -1); }
void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_F3, 0x7E, false, -1); } void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, MM_0F | PP_F3, 0x7E, false, -1); }
void vmovhlps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F, 0x12, false); } void vmovhlps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F, 0x12, false); }
void vmovlhps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F, 0x16, false); } void vmovlhps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F, 0x16, false); }
void vmovmskpd(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F | PP_66, 0x50, true, 0); } void vmovmskpd(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F | PP_66, 0x50, true, 0); }
void vmovmskps(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F, 0x50, true, 0); } void vmovmskps(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), x.isXMM() ? xm0 : ym0, x, MM_0F, 0x50, true, 0); }
void vmovntdq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0xE7, true); } void vmovntdq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0xE7, true); }
void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0x2B, true); } void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F | PP_66, 0x2B, true); }
void vmovntps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F, 0x2B, true); } void vmovntps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, addr, MM_0F, 0x2B, true); }
void vmovntdqa(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ymm0, addr, MM_0F38 | PP_66, 0x2A, true); } void vmovntdqa(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, x.isXMM() ? xm0 : ymm0, addr, MM_0F38 | PP_66, 0x2A, true); }
void vmovsd(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F2, 0x10, false); } void vmovsd(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F2, 0x10, false); }
void vmovsd(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F2, 0x10, false); } void vmovsd(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F2, 0x10, false); }
void vmovsd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F2, 0x11, false); } void vmovsd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F2, 0x11, false); }
void vmovss(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F3, 0x10, false); } void vmovss(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, MM_0F | PP_F3, 0x10, false); }
void vmovss(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x10, false); } void vmovss(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x10, false); }
void vmovss(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x11, false); } void vmovss(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, MM_0F | PP_F3, 0x11, false); }
void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 0); } void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 0); }
void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 0); } void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 0); }
void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 0); } void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 0); }
void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2C, false, 0); } void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2C, false, 0); }
void vcvtsi2ss(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F3, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); } void vcvtsi2ss(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F3, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }
void vcvtsi2sd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F2, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); } void vcvtsi2sd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !(op2.isREG(i32e) || op2.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, op1, op2, op2.isREG(), Operand::XMM, MM_0F | PP_F2, 0x2A, false, (op1.isMEM() || op2.isMEM()) ? -1 : (op1.isREG(32) || op2.isREG(32)) ? 0 : 1); }
void vcvtps2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F, 0x5A, true); } void vcvtps2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F, 0x5A, true); }
void vcvtdq2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F | PP_F3, 0xE6, true); } void vcvtdq2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x.isXMM() ? xm0 : ym0, op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, MM_0F | PP_F3, 0xE6, true); }
void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0x5A, true); } void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0x5A, true); }
void vcvtpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_F2, 0xE6, true); } void vcvtpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_F2, 0xE6, true); }
void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0xE6, true); } void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, op.isYMM() ? ym0 : xm0, op, MM_0F | PP_66, 0xE6, true); }
#ifdef XBYAK64 #ifdef XBYAK64
void vmovq(const Xmm& x, const Reg64& reg) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x6E, false, 1); } void vmovq(const Xmm& x, const Reg64& reg) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x6E, false, 1); }
void vmovq(const Reg64& reg, const Xmm& x) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x7E, false, 1); } void vmovq(const Reg64& reg, const Xmm& x) { opAVX_X_X_XM(x, xm0, Xmm(reg.getIdx()), MM_0F | PP_66, 0x7E, false, 1); }
void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 1); db(imm); } void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, xm0, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x16, false, 1); db(imm); }
void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); } void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x1, x2, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }
void vpinsrq(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw ERR_BAD_COMBINATION; opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); } void vpinsrq(const Xmm& x, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, x, op, !op.isMEM(), Operand::XMM, MM_0F3A | PP_66, 0x22, false, 1); db(imm); }
void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 1); } void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2D, false, 1); }
void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 1); } void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F3, 0x2C, false, 1); }
void vcvtsd2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 1); } void vcvtsd2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, MM_0F | PP_F2, 0x2D, false, 1); }

View file

@ -292,7 +292,7 @@ public:
{ {
if (n_ == 10) { if (n_ == 10) {
fprintf(stderr, "ERR Pack::can't append\n"); fprintf(stderr, "ERR Pack::can't append\n");
throw ERR_BAD_PARAMETER; throw Error(ERR_BAD_PARAMETER);
} }
tbl_[n_++] = &t; tbl_[n_++] = &t;
return *this; return *this;
@ -301,7 +301,7 @@ public:
{ {
if (n > maxTblNum) { if (n > maxTblNum) {
fprintf(stderr, "ERR Pack::init bad n=%d\n", (int)n); fprintf(stderr, "ERR Pack::init bad n=%d\n", (int)n);
throw ERR_BAD_PARAMETER; throw Error(ERR_BAD_PARAMETER);
} }
n_ = n; n_ = n;
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
@ -312,7 +312,7 @@ public:
{ {
if (n >= n_) { if (n >= n_) {
fprintf(stderr, "ERR Pack bad n=%d\n", (int)n); fprintf(stderr, "ERR Pack bad n=%d\n", (int)n);
throw ERR_BAD_PARAMETER; throw Error(ERR_BAD_PARAMETER);
} }
return *tbl_[n]; return *tbl_[n];
} }
@ -325,7 +325,7 @@ public:
if (num == size_t(-1)) num = n_ - pos; if (num == size_t(-1)) num = n_ - pos;
if (pos + num > n_) { if (pos + num > n_) {
fprintf(stderr, "ERR Pack::sub bad pos=%d, num=%d\n", (int)pos, (int)num); fprintf(stderr, "ERR Pack::sub bad pos=%d, num=%d\n", (int)pos, (int)num);
throw ERR_BAD_PARAMETER; throw Error(ERR_BAD_PARAMETER);
} }
Pack pack; Pack pack;
pack.n_ = num; pack.n_ = num;
@ -392,9 +392,9 @@ public:
, t(t_) , t(t_)
{ {
using namespace Xbyak; using namespace Xbyak;
if (pNum < 0 || pNum > 4) throw ERR_BAD_PNUM; if (pNum < 0 || pNum > 4) throw Error(ERR_BAD_PNUM);
const int allRegNum = pNum + tNum_ + (useRcx_ ? 1 : 0) + (useRdx_ ? 1 : 0); const int allRegNum = pNum + tNum_ + (useRcx_ ? 1 : 0) + (useRdx_ ? 1 : 0);
if (allRegNum < pNum || allRegNum > 14) throw ERR_BAD_TNUM; if (allRegNum < pNum || allRegNum > 14) throw Error(ERR_BAD_TNUM);
const Reg64& rsp = code->rsp; const Reg64& rsp = code->rsp;
const AddressFrame& ptr = code->ptr; const AddressFrame& ptr = code->ptr;
saveNum_ = (std::max)(0, allRegNum - noSaveNum); saveNum_ = (std::max)(0, allRegNum - noSaveNum);
@ -458,8 +458,8 @@ public:
if (!makeEpilog_) return; if (!makeEpilog_) return;
try { try {
close(); close();
} catch (Xbyak::Error e) { } catch (std::exception& e) {
printf("ERR:StackFrame %s\n", ConvertErrorToString(e)); printf("ERR:StackFrame %s\n", e.what());
exit(1); exit(1);
} catch (...) { } catch (...) {
printf("ERR:StackFrame otherwise\n"); printf("ERR:StackFrame otherwise\n");