236 const int NO = CodeGenerator::NONE;
241 snprintf(
buf,
sizeof(
buf),
"%d.%02X%x", v >> 12, (v >> 4) & 0xFF, v & 0xF);
243 snprintf(
buf,
sizeof(
buf),
"%d.%02X", v >> 12, (v >> 4) & 0xFF);
245 printf(
"const char *getVersionString() const { return \"%s\"; }\n",
buf);
247 const int B = 1 << 0;
248 const int W = 1 << 1;
249 const int D = 1 << 2;
250 const int Q = 1 << 3;
257 { 0x6B,
"packssdw" },
258 { 0x63,
"packsswb" },
259 { 0x67,
"packuswb" },
271 { 0x68,
"punpckhbw" },
272 { 0x69,
"punpckhwd" },
273 { 0x6A,
"punpckhdq" },
275 { 0x60,
"punpcklbw" },
276 { 0x61,
"punpcklwd" },
277 { 0x62,
"punpckldq" },
295 const Tbl *
p = &
tbl[i];
296 printf(
"void %s(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x%02X); }\n"
307 { 0xFC,
B|W|
D,
"padd" },
308 { 0xEC,
B|W ,
"padds" },
309 { 0xDC,
B|W ,
"paddus" },
310 { 0x74,
B|W|
D,
"pcmpeq" },
311 { 0x64,
B|W|
D,
"pcmpgt" },
312 { 0xF0, W|
D|Q,
"psll" },
313 { 0xE0, W|
D ,
"psra" },
314 { 0xD0, W|
D|Q,
"psrl" },
315 { 0xF8,
B|W|
D,
"psub" },
316 { 0xE8,
B|W ,
"psubs" },
317 { 0xD8,
B|W ,
"psubus" },
320 const Tbl *
p = &
tbl[i];
321 static const char modTbl[][4] = {
324 for (
int j = 0;
j < 4;
j++) {
326 if (!(
p->mode & (1 <<
j)))
continue;
327 printf(
"void %s%s(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x%02X); }\n"
342 { 0x70, 6, W|
D|Q,
"psll" },
343 { 0x70, 4, W|
D ,
"psra" },
344 { 0x70, 2, W|
D|Q,
"psrl" },
347 const Tbl *
p = &
tbl[i];
348 static const char modTbl[][4] = {
351 for (
int j = 0;
j < 4;
j++) {
353 if (!(
p->mode & (1 <<
j)))
continue;
354 printf(
"void %s%s(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x%02X, %d); }\n"
361 printf(
"void pslldq(const Xmm& xmm, int imm8) { opMMX_IMM(xmm, imm8, 0x%02X, %d); }\n", 0x73, 7);
362 printf(
"void psrldq(const Xmm& xmm, int imm8) { opMMX_IMM(xmm, imm8, 0x%02X, %d); }\n", 0x73, 3);
371 { 0x70, 0,
"pshufw" },
372 { 0x70, 0xF2,
"pshuflw" },
373 { 0x70, 0xF3,
"pshufhw" },
374 { 0x70, 0x66,
"pshufd" },
377 const Tbl *
p = &
tbl[i];
378 printf(
"void %s(const Mmx& mmx, const Operand& op, uint8 imm8) { opMMX(mmx, op, 0x%02X, 0x%02X, imm8); }\n",
p->name,
p->code,
p->pref);
382 const struct MmxTbl6 {
388 { 0x6F, 0x7F, 0x66,
"movdqa" },
389 { 0x6F, 0x7F, 0xF3,
"movdqu" },
391 { 0x28, 0x29, NO,
"movaps" },
392 { 0x10, 0x11, 0xF3,
"movss" },
393 { 0x10, 0x11, NO,
"movups" },
394 { 0x28, 0x29, 0x66,
"movapd" },
395 { 0x10, 0x11, 0xF2,
"movsd" },
396 { 0x10, 0x11, 0x66,
"movupd" },
399 const MmxTbl6 *
p = &mmxTbl6[i];
400 printf(
"void %s(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x%02X, 0x%02X); }\n",
p->name,
p->code,
p->pref);
401 printf(
"void %s(const Address& addr, const Xmm& xmm) { ",
p->name);
402 if (
p->pref != NO) printf(
"db(0x%02X); ",
p->pref);
403 printf(
"opModM(addr, xmm, 0x0F, 0x%02X); }\n",
p->code2);
428 { 0x58, PS|SS|PD|SD,
"add" },
429 { 0x55, PS|PD ,
"andn" },
430 { 0x54, PS|PD ,
"and" },
431 { 0xC2, PS|SS|PD|SD,
"cmp",
true },
432 { 0x5E, PS|SS|PD|SD,
"div" },
433 { 0x5F, PS|SS|PD|SD,
"max" },
434 { 0x5D, PS|SS|PD|SD,
"min" },
435 { 0x59, PS|SS|PD|SD,
"mul" },
436 { 0x56, PS|PD ,
"or" },
437 { 0x53, PS|SS ,
"rcp" },
438 { 0x52, PS|SS ,
"rsqrt" },
439 { 0xC6, PS|PD ,
"shuf",
true },
440 { 0x51, PS|SS|PD|SD,
"sqrt" },
441 { 0x5C, PS|SS|PD|SD,
"sub" },
442 { 0x15, PS|PD ,
"unpckh" },
443 { 0x14, PS|PD ,
"unpckl" },
444 { 0x57, PS|PD ,
"xor" },
448 const Tbl *
p = &
tbl[i];
450 if (!(
p->mode & (1 <<
j)))
continue;
453 printf(
"void %s%s(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0x%2X, 0x%02X, isXMM_XMMorMEM, imm8); }\n",
p->name, sufTbl[
j].name,
p->code, sufTbl[
j].code);
455 printf(
"void %s%s(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x%2X, 0x%02X, isXMM_XMMorMEM); }\n",
p->name, sufTbl[
j].name,
p->code, sufTbl[
j].code);
467 { 0xF7, 0x66,
"maskmovdqu" },
468 { 0x12, 0 ,
"movhlps" },
469 { 0x16, 0 ,
"movlhps" },
472 const Tbl *
p = &
tbl[i];
473 printf(
"void %s(const Xmm& reg1, const Xmm& reg2) { ",
p->name);
474 if (
p->pref) printf(
"db(0x%02X); ",
p->pref);
475 printf(
" opModR(reg1, reg2, 0x0F, 0x%02X); }\n",
p->code);
485 { 0x6D, 0x66,
"punpckhqdq" },
486 { 0x6C, 0x66,
"punpcklqdq" },
488 { 0x2F, NO ,
"comiss" },
489 { 0x2E, NO ,
"ucomiss" },
490 { 0x2F, 0x66,
"comisd" },
491 { 0x2E, 0x66,
"ucomisd" },
493 { 0x5A, 0x66,
"cvtpd2ps" },
494 { 0x5A, NO ,
"cvtps2pd" },
495 { 0x5A, 0xF2,
"cvtsd2ss" },
496 { 0x5A, 0xF3,
"cvtss2sd" },
497 { 0xE6, 0xF2,
"cvtpd2dq" },
498 { 0xE6, 0x66,
"cvttpd2dq" },
499 { 0xE6, 0xF3,
"cvtdq2pd" },
500 { 0x5B, 0x66,
"cvtps2dq" },
501 { 0x5B, 0xF3,
"cvttps2dq" },
502 { 0x5B, NO ,
"cvtdq2ps" },
505 const Tbl *
p = &
tbl[i];
506 printf(
"void %s(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x%02X, 0x%02X, isXMM_XMMorMEM); }\n",
p->name,
p->code,
p->pref);
518 { 0x2A, NO ,
"cvtpi2ps",
"isXMM_MMXorMEM" },
519 { 0x2D, NO ,
"cvtps2pi",
"isMMX_XMMorMEM" },
520 { 0x2A, 0xF3,
"cvtsi2ss",
"isXMM_REG32orMEM" },
521 { 0x2D, 0xF3,
"cvtss2si",
"isREG32_XMMorMEM" },
522 { 0x2C, NO ,
"cvttps2pi",
"isMMX_XMMorMEM" },
523 { 0x2C, 0xF3,
"cvttss2si",
"isREG32_XMMorMEM" },
524 { 0x2A, 0x66,
"cvtpi2pd",
"isXMM_MMXorMEM" },
525 { 0x2D, 0x66,
"cvtpd2pi",
"isMMX_XMMorMEM" },
526 { 0x2A, 0xF2,
"cvtsi2sd",
"isXMM_REG32orMEM" },
527 { 0x2D, 0xF2,
"cvtsd2si",
"isREG32_XMMorMEM" },
528 { 0x2C, 0x66,
"cvttpd2pi",
"isMMX_XMMorMEM" },
529 { 0x2C, 0xF2,
"cvttsd2si",
"isREG32_XMMorMEM" },
532 const Tbl *
p = &
tbl[i];
533 printf(
"void %s(const Operand& reg, const Operand& op) { opGen(reg, op, 0x%02X, 0x%02X, %s); }\n",
p->name,
p->code,
p->pref,
p->cond);
551 const Tbl *
p = &
tbl[i];
552 printf(
"void prefetch%s(const Address& addr) { opModM(addr, Reg32(%d), 0x0F, 0x%02X); }\n",
p->name,
p->ext,
p->code);
561 { 0x16, NO,
"movhps" },
562 { 0x12, NO,
"movlps" },
563 { 0x16, 0x66,
"movhpd" },
564 { 0x12, 0x66,
"movlpd" },
567 const Tbl *
p = &
tbl[i];
568 printf(
"void %s(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x%02X, 0x%02X); }\n",
p->name,
p->code,
p->pref);
608 const char *msg =
"//-V524";
610 const Tbl *
p = &
tbl[i];
611 printf(
"void cmov%s(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | %d); }%s\n",
p->name,
p->ext, msg);
612 printf(
"void j%s(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }%s\n",
p->name,
p->ext | 0x70,
p->ext | 0x80, 0x0F, msg);
613 printf(
"void j%s(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }%s\n",
p->name,
p->ext | 0x70,
p->ext | 0x80, 0x0F, msg);
614 printf(
"void j%s(const char *label, LabelType type = T_AUTO) { j%s(std::string(label), type); }%s\n",
p->name,
p->name, msg);
615 printf(
"void j%s(const void *addr) { opJmpAbs(addr, T_NEAR, 0x%02X, 0x%02X, 0x%02X); }%s\n",
p->name,
p->ext | 0x70,
p->ext | 0x80, 0x0F, msg);
616 printf(
"void set%s(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | %d); }%s\n",
p->name,
p->ext, msg);
623 {
"cbw", 0x66, 0x98 },
630 {
"cpuid", 0x0F, 0xA2 },
631 {
"cwd", 0x66, 0x99 },
634 {
"movsw", 0x66, 0xA5 },
646 {
"emms", 0x0F, 0x77 },
647 {
"pause", 0xF3, 0x90 },
648 {
"sfence", 0x0F, 0xAE, 0xF8 },
649 {
"lfence", 0x0F, 0xAE, 0xE8 },
650 {
"mfence", 0x0F, 0xAE, 0xF0 },
651 {
"monitor", 0x0F, 0x01, 0xC8 },
652 {
"mwait", 0x0F, 0x01, 0xC9 },
654 {
"rdmsr", 0x0F, 0x32 },
655 {
"rdpmc", 0x0F, 0x33 },
656 {
"rdtsc", 0x0F, 0x31 },
657 {
"rdtscp", 0x0F, 0x01, 0xF9 },
658 {
"ud2", 0x0F, 0x0B },
661 {
"wbinvd", 0x0F, 0x09 },
662 {
"wrmsr", 0x0F, 0x30 },
667 {
"stac", 0x0F, 0x01, 0xCB },
669 {
"vzeroall", 0xC5, 0xFC, 0x77 },
670 {
"vzeroupper", 0xC5, 0xF8, 0x77 },
671 {
"xgetbv", 0x0F, 0x01, 0xD0 },
674 {
"f2xm1", 0xD9, 0xF0 },
675 {
"fabs", 0xD9, 0xE1 },
676 {
"faddp", 0xDE, 0xC1 },
677 {
"fchs", 0xD9, 0xE0 },
679 {
"fcom", 0xD8, 0xD1 },
680 {
"fcomp", 0xD8, 0xD9 },
681 {
"fcompp", 0xDE, 0xD9 },
682 {
"fcos", 0xD9, 0xFF },
683 {
"fdecstp", 0xD9, 0xF6 },
684 {
"fdivp", 0xDE, 0xF9 },
685 {
"fdivrp", 0xDE, 0xF1 },
686 {
"fincstp", 0xD9, 0xF7 },
687 {
"finit", 0x9B, 0xDB, 0xE3 },
688 {
"fninit", 0xDB, 0xE3 },
689 {
"fld1", 0xD9, 0xE8 },
690 {
"fldl2t", 0xD9, 0xE9 },
691 {
"fldl2e", 0xD9, 0xEA },
692 {
"fldpi", 0xD9, 0xEB },
693 {
"fldlg2", 0xD9, 0xEC },
694 {
"fldln2", 0xD9, 0xED },
695 {
"fldz", 0xD9, 0xEE },
696 {
"fmulp", 0xDE, 0xC9 },
697 {
"fnop", 0xD9, 0xD0 },
698 {
"fpatan", 0xD9, 0xF3 },
699 {
"fprem", 0xD9, 0xF8 },
700 {
"fprem1", 0xD9, 0xF5 },
701 {
"fptan", 0xD9, 0xF2 },
702 {
"frndint", 0xD9, 0xFC },
703 {
"fscale", 0xD9, 0xFD },
704 {
"fsin", 0xD9, 0xFE },
705 {
"fsincos", 0xD9, 0xFB },
706 {
"fsqrt", 0xD9, 0xFA },
707 {
"fsubp", 0xDE, 0xE9 },
708 {
"fsubrp", 0xDE, 0xE1 },
709 {
"ftst", 0xD9, 0xE4 },
710 {
"fucom", 0xDD, 0xE1 },
711 {
"fucomp", 0xDD, 0xE9 },
712 {
"fucompp", 0xDA, 0xE9 },
713 {
"fxam", 0xD9, 0xE5 },
714 {
"fxch", 0xD9, 0xC9 },
715 {
"fxtract", 0xD9, 0xF4 },
716 {
"fyl2x", 0xD9, 0xF1 },
717 {
"fyl2xp1", 0xD9, 0xF9 },
737 const Tbl *
p = &
tbl[i];
738 printf(
"void %s(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x%02X); }\n",
p->name,
p->code);
739 printf(
"void %s(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x%02X, %d); }\n",
p->name,
p->code,
p->ext);
753 const Tbl *
p = &
tbl[i];
754 printf(
"void %s(const Operand& op) { opIncDec(op, 0x%02X, %d); }\n",
p->name,
p->code,
p->ext);
769 const Tbl *
p = &
tbl[i];
770 printf(
"void %s(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), 0x0f, 0x%02X); }\n",
p->name,
p->code);
771 printf(
"void %s(const Operand& op, uint8 imm) { opR_ModM(op, 16|32|64, %d, 0x0f, 0xba, NONE, false, 1); db(imm); }\n",
p->name,
p->ext);
788 const Tbl *
p = &
tbl[i];
789 const std::string
name =
p->name;
790 printf(
"void %s(const Operand& op) { opR_ModM(op, 0, %d, 0x%02X); }\n",
p->name,
p->ext,
p->code);
809 const Tbl *
p = &
tbl[i];
810 printf(
"void %s(const Operand& op, int imm) { opShift(op, imm, %d); }\n",
p->name,
p->ext);
811 printf(
"void %s(const Operand& op, const Reg8& _cl) { opShift(op, _cl, %d); }\n",
p->name,
p->ext);
823 const Tbl *
p = &
tbl[i];
824 printf(
"void %s(const Operand& op, const Reg& reg, uint8 imm) { opShxd(op, reg, imm, 0x%02X); }\n",
p->name,
p->code);
825 printf(
"void %s(const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(op, reg, 0, 0x%02X, &_cl); }\n",
p->name,
p->code);
837 const Tbl *
p = &
tbl[i];
838 printf(
"void %s(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x%02X); }\n",
p->name,
p->code);
851 const Tbl *
p = &
tbl[i];
852 printf(
"void %s(const Reg®, const Operand& op) { opSp1(reg, op, 0xF3, 0x0F, 0x%02X); }\n",
p->name,
p->code);
865 { 0x04,
"pmaddubsw" },
872 { 0x0b,
"pmulhrsw" },
878 const Tbl *
p = &
tbl[i];
879 printf(
"void %s(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x%02X, 0x66, NONE, 0x38); }\n",
p->name,
p->code);
881 printf(
"void palignr(const Mmx& mmx, const Operand& op, int imm) { opMMX(mmx, op, 0x0f, 0x66, static_cast<uint8>(imm), 0x3a); }\n");
888 {
"pclmullqlqdq", 0 },
889 {
"pclmulhqlqdq", 1 },
890 {
"pclmullqhdq", 0x10 },
891 {
"pclmulhqhdq", 0x11 },
894 const Tbl *
p = &
tbl[i];
895 printf(
"void %s(const Xmm& xmm, const Operand& op) { pclmulqdq(xmm, op, 0x%02X); }\n",
p->name,
p->code);
905 { 0x0F, 0xAE, 2,
"ldmxcsr" },
906 { 0x0F, 0xAE, 3,
"stmxcsr" },
907 { 0x0F, 0xAE, 7,
"clflush" },
908 { 0xD9,
NONE, 5,
"fldcw" },
912 const Tbl *
p = &
tbl[i];
913 printf(
"void %s(const Address& addr) { opModM(addr, Reg32(%d), 0x%02X, 0x%02X); }\n",
p->name,
p->ext,
p->code1,
p->code2);
915 printf(
"void fstcw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0xD9, NONE); }\n");
926 const Tbl *
p = &
tbl[i];
928 printf(
"void %s(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), 0x0F, 0x%02X); }\n",
p->name,
p->code);
940 const Tbl *
p = &
tbl[i];
941 printf(
"void %s(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0x%02X); }\n",
p->name,
p->code);
946 puts(
"void bndcl(const BoundsReg& bnd, const Operand& op) { db(0xF3); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }");
947 puts(
"void bndcu(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }");
948 puts(
"void bndcn(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1B, NONE, !op.isMEM()); }");
949 puts(
"void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, 0x0F, 0x1A); }");
950 puts(
"void bndmk(const BoundsReg& bnd, const Address& addr) { db(0xF3); opModM(addr, bnd, 0x0F, 0x1B); }");
951 puts(
"void bndmov(const BoundsReg& bnd, const Operand& op) { db(0x66); opModRM(bnd, op, op.isBNDREG(), op.isMEM(), 0x0F, 0x1A); }");
952 puts(
"void bndmov(const Address& addr, const BoundsReg& bnd) { db(0x66); opModM(addr, bnd, 0x0F, 0x1B); }");
953 puts(
"void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, 0x0F, 0x1B); }");
957 puts(
"void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModM(addr, reg, 0x8D); }");
958 puts(
"void bswap(const Reg32e& reg) { opModR(Reg32(1), reg, 0x0F); }");
959 puts(
"void ret(int imm = 0) { if (imm) { db(0xC2); dw(imm); } else { db(0xC3); } }");
961 puts(
"void xadd(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), 0x0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); }");
962 puts(
"void cmpxchg(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), 0x0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); }");
963 puts(
"void movbe(const Reg& reg, const Address& addr) { opModM(addr, reg, 0x0F, 0x38, 0xF0); }");
964 puts(
"void movbe(const Address& addr, const Reg& reg) { opModM(addr, reg, 0x0F, 0x38, 0xF1); }");
965 puts(
"void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }");
966 puts(
"void adox(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0xF3, isREG32_REG32orMEM, NONE, 0x38); }");
967 puts(
"void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0xC7); }");
969 puts(
"void pextrw(const Operand& op, const Mmx& xmm, uint8 imm) { opExt(op, xmm, 0x15, imm, true); }");
970 puts(
"void pextrb(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x14, imm); }");
971 puts(
"void pextrd(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x16, imm); }");
972 puts(
"void extractps(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x17, imm); }");
973 puts(
"void pinsrw(const Mmx& mmx, const Operand& op, int imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opGen(mmx, op, 0xC4, mmx.isXMM() ? 0x66 : NONE, 0, imm); }");
974 puts(
"void insertps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, imm, 0x3A); }");
975 puts(
"void pinsrb(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x20, 0x66, isXMM_REG32orMEM, imm, 0x3A); }");
976 puts(
"void pinsrd(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x22, 0x66, isXMM_REG32orMEM, imm, 0x3A); }");
978 puts(
"void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(reg, mmx, 0x0F, 0xD7); }");
979 puts(
"void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) throw Error(ERR_BAD_COMBINATION); opModR(reg1, reg2, 0x0F, 0xF7); }");
980 puts(
"void movmskps(const Reg32e& reg, const Xmm& xmm) { opModR(reg, xmm, 0x0F, 0x50); }");
981 puts(
"void movmskpd(const Reg32e& reg, const Xmm& xmm) { db(0x66); movmskps(reg, xmm); }");
982 puts(
"void movntps(const Address& addr, const Xmm& xmm) { opModM(addr, Mmx(xmm.getIdx()), 0x0F, 0x2B); }");
983 puts(
"void movntdqa(const Xmm& xmm, const Address& addr) { db(0x66); opModM(addr, xmm, 0x0F, 0x38, 0x2A); }");
984 puts(
"void lddqu(const Xmm& xmm, const Address& addr) { db(0xF2); opModM(addr, xmm, 0x0F, 0xF0); }");
985 puts(
"void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, 0x0F, 0xC3); }");
986 puts(
"void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) throw Error(ERR_BAD_COMBINATION); opModM(addr, mmx, 0x0F, 0xE7); }");
988 puts(
"void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, 0x7E); }");
989 puts(
"void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x7E); }");
990 puts(
"void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, 0x6E); }");
991 puts(
"void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x6E); }");
992 puts(
"void movq2dq(const Xmm& xmm, const Mmx& mmx) { db(0xF3); opModR(xmm, mmx, 0x0F, 0xD6); }");
993 puts(
"void movdq2q(const Mmx& mmx, const Xmm& xmm) { db(0xF2); opModR(mmx, xmm, 0x0F, 0xD6); }");
994 puts(
"void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opModRM(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), 0x0F, mmx.isXMM() ? 0x7E : 0x6F); }");
995 puts(
"void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, mmx.isXMM() ? 0xD6 : 0x7F); }");
996 puts(
"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); }");
997 puts(
"void rdseed(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(7, Operand::REG, r.getBit()), r, 0x0F, 0xC7); }");
998 puts(
"void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); db(0xF2); opModRM(reg, op, op.isREG(), op.isMEM(), 0x0F, 0x38, 0xF0 | (op.isBit(8) ? 0 : 1)); }");
1009 { 0x00, 0xD8, 0xDC, 0,
"fadd" },
1010 { 0xDE, 0xDA, 0x00, 0,
"fiadd" },
1011 { 0x00, 0xD8, 0xDC, 2,
"fcom" },
1012 { 0x00, 0xD8, 0xDC, 3,
"fcomp" },
1013 { 0x00, 0xD8, 0xDC, 6,
"fdiv" },
1014 { 0xDE, 0xDA, 0x00, 6,
"fidiv" },
1015 { 0x00, 0xD8, 0xDC, 7,
"fdivr" },
1016 { 0xDE, 0xDA, 0x00, 7,
"fidivr" },
1017 { 0xDE, 0xDA, 0x00, 2,
"ficom" },
1018 { 0xDE, 0xDA, 0x00, 3,
"ficomp" },
1019 { 0xDF, 0xDB, 0xDF, 0,
"fild", 5 },
1020 { 0xDF, 0xDB, 0x00, 2,
"fist" },
1021 { 0xDF, 0xDB, 0xDF, 3,
"fistp", 7 },
1022 { 0xDF, 0xDB, 0xDD, 1,
"fisttp" },
1023 { 0x00, 0xD9, 0xDD, 0,
"fld" },
1024 { 0x00, 0xD8, 0xDC, 1,
"fmul" },
1025 { 0xDE, 0xDA, 0x00, 1,
"fimul" },
1026 { 0x00, 0xD9, 0xDD, 2,
"fst" },
1027 { 0x00, 0xD9, 0xDD, 3,
"fstp" },
1028 { 0x00, 0xD8, 0xDC, 4,
"fsub" },
1029 { 0xDE, 0xDA, 0x00, 4,
"fisub" },
1030 { 0x00, 0xD8, 0xDC, 5,
"fsubr" },
1031 { 0xDE, 0xDA, 0x00, 5,
"fisubr" },
1034 const Tbl *
p = &
tbl[i];
1035 printf(
"void %s(const Address& addr) { opFpuMem(addr, 0x%02X, 0x%02X, 0x%02X, %d, %d); }\n",
p->name,
p->m16,
p->m32,
p->m64,
p->ext,
p->m64ext);
1044 { 0xD8C0, 0xDCC0,
"fadd" },
1045 { 0x0000, 0xDEC0,
"faddp" },
1047 { 0xDAC0, 0x00C0,
"fcmovb" },
1048 { 0xDAC8, 0x00C8,
"fcmove" },
1049 { 0xDAD0, 0x00D0,
"fcmovbe" },
1050 { 0xDAD8, 0x00D8,
"fcmovu" },
1051 { 0xDBC0, 0x00C0,
"fcmovnb" },
1052 { 0xDBC8, 0x00C8,
"fcmovne" },
1053 { 0xDBD0, 0x00D0,
"fcmovnbe" },
1054 { 0xDBD8, 0x00D8,
"fcmovnu" },
1056 { 0xDBF0, 0x00F0,
"fcomi" },
1057 { 0xDFF0, 0x00F0,
"fcomip" },
1058 { 0xDBE8, 0x00E8,
"fucomi" },
1059 { 0xDFE8, 0x00E8,
"fucomip" },
1061 { 0xD8F0, 0xDCF8,
"fdiv" },
1062 { 0x0000, 0xDEF8,
"fdivp" },
1063 { 0xD8F8, 0xDCF0,
"fdivr" },
1064 { 0x0000, 0xDEF0,
"fdivrp" },
1065 { 0xD8C8, 0xDCC8,
"fmul" },
1066 { 0x0000, 0xDEC8,
"fmulp" },
1067 { 0xD8E0, 0xDCE8,
"fsub" },
1068 { 0x0000, 0xDEE8,
"fsubp" },
1069 { 0xD8E8, 0xDCE0,
"fsubr" },
1070 { 0x0000, 0xDEE0,
"fsubrp" },
1073 const Tbl *
p = &
tbl[i];
1074 printf(
"void %s(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x%04X, 0x%04X); }\n",
p->name,
p->code1,
p->code2);
1077 printf(
"void %s(const Fpu& reg1) { opFpuFpu(st0, reg1, 0x%04X, 0x%04X); }\n",
p->name,
p->code1,
p->code2);
1079 printf(
"void %s(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x%04X, 0x%04X); }\n",
p->name,
p->code1,
p->code2);
1089 { 0xD8, 0xD0,
"fcom" },
1090 { 0xD8, 0xD8,
"fcomp" },
1091 { 0xDD, 0xC0,
"ffree" },
1092 { 0xD9, 0xC0,
"fld" },
1093 { 0xDD, 0xD0,
"fst" },
1094 { 0xDD, 0xD8,
"fstp" },
1095 { 0xDD, 0xE0,
"fucom" },
1096 { 0xDD, 0xE8,
"fucomp" },
1097 { 0xD9, 0xC8,
"fxch" },
1100 const Tbl *
p = &
tbl[i];
1101 printf(
"void %s(const Fpu& reg) { opFpu(reg, 0x%02X, 0x%02X); }\n",
p->name,
p->code1,
p->code2);
1111 { 0x58,
"add",
false },
1112 { 0x5C,
"sub",
false },
1113 { 0x59,
"mul",
false },
1114 { 0x5E,
"div",
false },
1115 { 0x5F,
"max",
false },
1116 { 0x5D,
"min",
false },
1117 { 0x54,
"and",
true },
1118 { 0x55,
"andn",
true },
1119 { 0x56,
"or",
true },
1120 { 0x57,
"xor",
true },
1123 const Tbl *
p = &
tbl[i];
1124 printf(
"void v%spd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x%02X); }\n",
p->name,
p->code);
1125 printf(
"void v%sps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x%02X); }\n",
p->name,
p->code);
1126 if (
p->only_pd_ps)
continue;
1127 printf(
"void v%ssd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x%02X); }\n",
p->name,
p->code);
1128 printf(
"void v%sss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x%02X); }\n",
p->name,
p->code);
1142 { 0x15,
"blendvpd",
T_0F38 |
T_66,
false, 1 },
1143 { 0x14,
"blendvps",
T_0F38 |
T_66,
false, 1 },
1144 { 0x10,
"pblendvb",
T_0F38 |
T_66,
false, 1 },
1145 { 0xDF,
"aeskeygenassist",
T_0F3A |
T_66,
true, 3 },
1151 { 0x61,
"pcmpestri",
T_0F3A |
T_66,
true, 3 },
1152 { 0x60,
"pcmpestrm",
T_0F3A |
T_66,
true, 3 },
1153 { 0x63,
"pcmpistri",
T_0F3A |
T_66,
true, 3 },
1154 { 0x62,
"pcmpistrm",
T_0F3A |
T_66,
true, 3 },
1175 { 0x41,
"phminposuw",
T_0F38 |
T_66,
false, 3 },
1196 { 0x53,
"rcpps",
T_0F |
T_YMM,
false, 2 },
1197 { 0x52,
"rsqrtps",
T_0F |
T_YMM,
false, 2 },
1205 { 0xCC,
"sha1rnds4",
T_0F3A,
true, 1 },
1206 { 0xC8,
"sha1nexte",
T_0F38,
false, 1 },
1207 { 0xC9,
"sha1msg1",
T_0F38,
false, 1 },
1208 { 0xCA,
"sha1msg2",
T_0F38,
false, 1 },
1209 { 0xCB,
"sha256rnds2",
T_0F38,
false, 1 },
1210 { 0xCC,
"sha256msg1",
T_0F38,
false, 1 },
1211 { 0xCD,
"sha256msg2",
T_0F38,
false, 1 },
1214 const Tbl *
p = &
tbl[i];
1217 const char *immS1 =
p->hasIMM ?
", uint8 imm" :
"";
1218 const char *immS2 =
p->hasIMM ?
", imm" :
", NONE";
1219 const char *pref =
p->type &
T_66 ?
"0x66" :
p->type &
T_F2 ?
"0xF2" :
p->type &
T_F3 ?
"0xF3" :
"NONE";
1220 const char *suf =
p->type &
T_0F38 ?
"0x38" :
p->type &
T_0F3A ?
"0x3A" :
"NONE";
1221 printf(
"void %s(const Xmm& xmm, const Operand& op%s) { opGen(xmm, op, 0x%02X, %s, isXMM_XMMorMEM%s, %s); }\n",
p->name, immS1,
p->code, pref, immS2, suf);
1224 printf(
"void v%s(const Xmm& xm, const Operand& op%s) { opAVX_X_XM_IMM(xm, op, %s, 0x%02X%s); }\n"
1225 ,
p->name,
p->hasIMM ?
", uint8 imm" :
"", type.c_str(),
p->code,
p->hasIMM ?
", imm" :
"");
1244 const Tbl *
p = &
tbl[i];
1246 printf(
"void v%s(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, %s, 0x%02X); }\n"
1247 ,
p->name, type.c_str(),
p->code);
1271 const Tbl *
p = &
tbl[i];
1275 printf(
"void %s(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x%02X, 0x%02X, isXMM_XMMorMEM%s); }\n",
p->name,
p->code, pref,
p->type &
T_0F38 ?
", NONE, 0x38" :
"");
1278 printf(
"void v%s(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, %s, 0x%02X); }\n"
1279 ,
p->name, type.c_str(),
p->code);
1285 const char suf[][8] = {
"ps",
"pd" };
1286 for (
int i = 0; i < 2; i++) {
1287 printf(
"void vmaskmov%s(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x%02X); }\n", suf[i], 0x2C + i);
1288 printf(
"void vmaskmov%s(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x%02X); }\n", suf[i], 0x2E + i);
1293 const char suf[][8] = {
"d",
"q" };
1294 for (
int i = 0; i < 2; i++) {
1295 printf(
"void vpmaskmov%s(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W%d | T_YMM, 0x%02X); }\n", suf[i], i, 0x8C);
1296 printf(
"void vpmaskmov%s(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W%d | T_YMM, 0x%02X); }\n", suf[i], i, 0x8E);
1312 const Tbl&
p =
tbl[i];
1314 printf(
"void %s(const Ymm& y1, const Ymm& y2, const Operand& op) { opAVX_X_X_XM(y1, y2, op, %s, 0x%02X); }\n",
p.name, type.c_str(),
p.code);
1328 const Tbl&
p =
tbl[i];
1330 printf(
"void %s(const Ymm& y, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(y, op, %s, 0x%02X, imm); }\n",
p.name, type.c_str(),
p.code);
1335 const char pred[32][16] = {
1336 "eq",
"lt",
"le",
"unord",
"neq",
"nlt",
"nle",
"ord",
1337 "eq_uq",
"nge",
"ngt",
"false",
"neq_oq",
"ge",
"gt",
1338 "true",
"eq_os",
"lt_oq",
"le_oq",
"unord_s",
"neq_us",
"nlt_uq",
"nle_uq",
"ord_s",
1339 "eq_us",
"nge_uq",
"ngt_uq",
"false_os",
"neq_os",
"ge_oq",
"gt_oq",
"true_us"
1341 const char suf[][4] = {
"pd",
"ps",
"sd",
"ss" };
1342 for (
int i = 0; i < 4; i++) {
1343 const char *
s = suf[i];
1344 for (
int j = 0;
j < 32;
j++) {
1346 printf(
"void cmp%s%s(const Xmm& x, const Operand& op) { cmp%s(x, op, %d); }\n", pred[
j],
s,
s,
j);
1348 printf(
"void vcmp%s%s(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmp%s(x1, x2, op, %d); }\n", pred[
j],
s,
s,
j);
1359 {
true,
true, 0x16 },
1360 {
true,
false, 0x16 },
1361 {
false,
true, 0x12 },
1362 {
false,
false, 0x12 },
1365 const Tbl&
p =
tbl[i];
1366 char c =
p.isH ?
'h' :
'l';
1367 const char *suf =
p.isPd ?
"pd" :
"ps";
1368 const char *type =
p.isPd ?
"T_0F | T_66 | T_EVEX | T_EW1 | T_N8" :
"T_0F | T_EVEX | T_EW0 | T_N8";
1369 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); }\n"
1370 , c, suf, type,
p.code);
1371 printf(
"void vmov%c%s(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, %s, 0x%02X); }\n"
1372 , c, suf, type,
p.code + 1);
1382 { 0x08,
"vfmadd",
true },
1383 { 0x09,
"vfmadd",
false },
1384 { 0x06,
"vfmaddsub",
true },
1385 { 0x07,
"vfmsubadd",
true },
1386 { 0x0A,
"vfmsub",
true },
1387 { 0x0B,
"vfmsub",
false },
1388 { 0x0C,
"vfnmadd",
true },
1389 { 0x0D,
"vfnmadd",
false },
1390 { 0x0E,
"vfnmsub",
true },
1391 { 0x0F,
"vfnmsub",
false },
1394 for (
int j = 0;
j < 2;
j++) {
1395 const char sufTbl[][2][8] = {
1399 for (
int k = 0; k < 3; k++) {
1411 const std::string suf = sufTbl[
tbl[i].supportYMM ? 0 : 1][
j];
1414 }
else if (suf ==
"ps") {
1416 }
else if (suf ==
"sd") {
1422 printf(
"void %s%s%s(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, %s, 0x%02X); }\n"
1423 ,
tbl[i].
name, ord[k].str, suf.c_str(), type.c_str(),
tbl[i].code + ord[k].code);
1430 printf(
"void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x1A); }\n");
1431 printf(
"void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x5A); }\n");
1432 printf(
"void vbroadcastsd(const Ymm& y, const Operand& op) { if (!op.isMEM() && !(y.isYMM() && op.isXMM()) && !(y.isZMM() && op.isXMM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(y, op, T_0F38 | T_66 | T_W0 | T_YMM | T_EVEX | T_EW1 | T_N8, 0x19); }\n");
1446 const Tbl&
p =
tbl[i];
1448 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, %s, 0x%02X); }\n",
p.name, type.c_str(),
p.code);
1451 puts(
"void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { if (!(op.isXMEM() && y.isYMM())) throw Error(ERR_BAD_COMBINATION); opVex(y, 0, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x19, imm); }");
1452 puts(
"void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { if (!(op.isXMEM() && y.isYMM())) throw Error(ERR_BAD_COMBINATION); opVex(y, 0, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x39, imm); }");
1453 puts(
"void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(32) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_N4, 0x17, imm); }");
1454 puts(
"void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isXMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x18, imm); }");
1455 puts(
"void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isXMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x38, imm); }");
1456 puts(
"void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isYMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x06, imm); }");
1457 puts(
"void vperm2i128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isYMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x46, imm); }");
1459 puts(
"void vlddqu(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_F2 | T_W0 | T_YMM, 0xF0); }");
1460 puts(
"void vldmxcsr(const Address& addr) { opAVX_X_X_XM(xm2, xm0, addr, T_0F, 0xAE); }");
1461 puts(
"void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, T_0F, 0xAE); }");
1462 puts(
"void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, T_0F | T_66, 0xF7); }");
1464 puts(
"void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(8|16|i32e) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_EVEX | T_N1, 0x14, imm); }");
1465 puts(
"void vpextrw(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(16|i32e) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); if (op.isREG() && x.getIdx() < 16) { opAVX_X_X_XM(Xmm(op.getIdx()), xm0, x, T_0F | T_66, 0xC5, imm); } else { opVex(x, 0, op, T_0F3A | T_66 | T_EVEX | T_N2, 0x15, imm); } }");
1466 puts(
"void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(32) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N4, 0x16, imm); }");
1467 puts(
"void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(64) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W1 | T_EVEX | T_EW1 | T_N8, 0x16, imm); }");
1469 puts(
"void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_EVEX | T_N1, 0x20, imm); }");
1470 puts(
"void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F | T_66 | T_EVEX | T_N2, 0xC4, imm); }");
1471 puts(
"void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N4, 0x22, imm); }");
1472 puts(
"void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(64) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_W1 | T_EVEX | T_EW1 | T_N8, 0x22, imm); }");
1474 puts(
"void vpmovmskb(const Reg32e& r, const Xmm& x) { if (!x.is(Operand::XMM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(x.isYMM() ? Ymm(r.getIdx()) : Xmm(r.getIdx()), 0, x, T_0F | T_66 | T_YMM, 0xD7); }");
1497 const Tbl&
p =
tbl[i];
1499 printf(
"void v%s(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), %d), x, op, %s, 0x%02X, imm); }\n",
p.name,
p.idx, type.c_str(),
p.code);
1508 {
"vblendvpd", 0x4B },
1509 {
"vblendvps", 0x4A },
1510 {
"vpblendvb", 0x4C },
1513 const Tbl&
p =
tbl[i];
1514 printf(
"void %s(const Xmm& x1, const Xmm& x2, const Operand& op, const Xmm& x4) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_YMM, 0x%02X, x4.getIdx() << 4); }\n",
p.name,
p.code);
1519 printf(
"void vmovd(const Xmm& x, const Operand& op) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, xm0, op, T_0F | T_66 | T_W0 | T_EVEX | T_N4, 0x6E); }\n");
1520 printf(
"void vmovd(const Operand& op, const Xmm& x) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, xm0, op, T_0F | T_66 | T_W0 | T_EVEX | T_N4, 0x7E); }\n");
1522 printf(
"void vmovq(const Xmm& x, const Address& addr) { int type, code; if (x.getIdx() < 16) { type = T_0F | T_F3; code = 0x7E; } else { type = T_0F | T_66 | T_EVEX | T_EW1 | T_N8; code = 0x6E; } opAVX_X_X_XM(x, xm0, addr, type, code); }\n");
1523 printf(
"void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, x.getIdx() < 16 ? 0xD6 : 0x7E); }\n");
1524 printf(
"void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, T_0F | T_F3 | T_EVEX | T_EW1 | T_N8, 0x7E); }\n");
1526 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, T_0F | T_EVEX | T_EW0, 0x12); }\n");
1527 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, T_0F | T_EVEX | T_EW0, 0x16); }\n");
1529 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()), cvtIdx0(x), x, T_0F | T_66 | T_W0 | T_YMM, 0x50); }\n");
1530 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()), cvtIdx0(x), x, T_0F | T_W0 | T_YMM, 0x50); }\n");
1532 puts(
"void vmovntdq(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW0, 0xE7); }");
1533 puts(
"void vmovntpd(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW1, 0x2B); }");
1534 puts(
"void vmovntps(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_YMM | T_EVEX | T_EW0, 0x2B); }");
1535 puts(
"void vmovntdqa(const Xmm& x, const Address& addr) { opVex(x, 0, addr, T_0F38 | T_66 | T_YMM | T_EVEX | T_EW0, 0x2A); }");
1538 for (
int i = 0; i < 2; i++) {
1539 char c1 = i == 0 ?
'd' :
's';
1543 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, %s, 0x10); }\n", c1,
s.c_str());
1544 printf(
"void vmovs%c(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, %s, 0x10); }\n", c1,
s.c_str());
1545 printf(
"void vmovs%c(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, %s | T_M_K, 0x11); }\n", c1,
s.c_str());
1550 puts(
"void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0 | T_EVEX | T_EW0 | T_ER_X | T_N8, 0x2D); }");
1551 puts(
"void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0 | T_EVEX | T_EW0 | T_SAE_X | T_N8, 0x2C); }");
1552 puts(
"void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0 | T_EVEX | T_EW0 | T_N4 | T_ER_X, 0x2D); }");
1553 puts(
"void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0 | T_EVEX | T_EW0 | T_N4 | T_SAE_X, 0x2C); }");
1555 puts(
"void vcvtsi2ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_0F | T_F3 | T_EVEX | T_ER_X, T_W1 | T_EW1 | T_N8, T_W0 | T_EW0 | T_N4, 0x2A); }");
1556 puts(
"void vcvtsi2sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_0F | T_F2 | T_EVEX, T_W1 | T_EW1 | T_ER_X | T_N8, T_W0 | T_EW0 | T_N4, 0x2A); }");
1559 puts(
"void vcvtps2pd(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F | T_YMM | T_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_SAE_Y, 0x5A); }");
1560 puts(
"void vcvtdq2pd(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F | T_F3 | T_YMM | T_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL, 0xE6); }");
1562 puts(
"void vcvtpd2ps(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_66 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0x5A); }");
1563 puts(
"void vcvtpd2dq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6); }");
1565 puts(
"void vcvttpd2dq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_66 | T_0F | T_YMM | T_EVEX |T_EW1 | T_B64 | T_ER_Z, 0xE6); }");
1567 puts(
"void vcvtph2ps(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F38 | T_66 | T_W0 | T_EVEX | T_EW0 | T_N8 | T_N_VL | T_SAE_Y, 0x13); }");
1568 puts(
"void vcvtps2ph(const Operand& op, const Xmm& x, uint8 imm) { checkCvt1(x, op); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N8 | T_N_VL | T_SAE_Y, 0x1D, imm); }");
1578 {
"andn",
T_0F38, 0xF2 },
1584 const Tbl&
p =
tbl[i];
1585 printf(
"void %s(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, %s, 0x%x, true); }\n",
p.name,
type2String(
p.type).c_str(),
p.code);
1595 {
"bextr",
T_0F38, 0xF7 },
1596 {
"bzhi",
T_0F38, 0xF5 },
1602 const Tbl&
p =
tbl[i];
1603 printf(
"void %s(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, %s, 0x%x, false); }\n",
p.name,
type2String(
p.type).c_str(),
p.code);
1605 puts(
"void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), T_0F3A | T_F2, 0xF0, false, imm); }");
1615 {
"blsi",
T_0F38, 0xF3, 3 },
1616 {
"blsmsk",
T_0F38, 0xF3, 2 },
1617 {
"blsr",
T_0F38, 0xF3, 1 },
1620 const Tbl&
p =
tbl[i];
1621 printf(
"void %s(const Reg32e& r, const Operand& op) { opGpr(Reg32e(%d, r.getBit()), op, r, %s, 0x%x, false); }\n",
p.name,
p.idx,
type2String(
p.type).c_str(),
p.code);
1626 const int y_vx_y = 0;
1627 const int y_vy_y = 1;
1628 const int x_vy_x = 2;
1635 {
"vgatherdpd", 0x92, 1, y_vx_y },
1636 {
"vgatherqpd", 0x93, 1, y_vy_y },
1637 {
"vgatherdps", 0x92, 0, y_vy_y },
1638 {
"vgatherqps", 0x93, 0, x_vy_x },
1639 {
"vpgatherdd", 0x90, 0, y_vy_y },
1640 {
"vpgatherqd", 0x91, 0, x_vy_x },
1641 {
"vpgatherdq", 0x90, 1, y_vx_y },
1642 {
"vpgatherqq", 0x91, 1, y_vy_y },
1645 const Tbl&
p =
tbl[i];
1646 printf(
"void %s(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_W%d, 0x%x, %d); }\n",
p.name,
p.w,
p.code,
p.mode);
#define D(var, file, col, who, lev,...)