decode-new.c.inc (aba2b8ecb90552cb347ac2e33557a3d475830ed4) decode-new.c.inc (7170a17ec3f29320dc66075cfea671013d4e2511)
1/*
2 * New-style decoder for i386 instructions
3 *
4 * Copyright (c) 2022 Red Hat, Inc.
5 *
6 * Author: Paolo Bonzini <pbonzini@redhat.com>
7 *
8 * This library is free software; you can redistribute it and/or

--- 542 unchanged lines hidden (view full) ---

551};
552
553static void decode_0F3A(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
554{
555 *b = x86_ldub_code(env, s);
556 *entry = opcodes_0F3A[*b];
557}
558
1/*
2 * New-style decoder for i386 instructions
3 *
4 * Copyright (c) 2022 Red Hat, Inc.
5 *
6 * Author: Paolo Bonzini <pbonzini@redhat.com>
7 *
8 * This library is free software; you can redistribute it and/or

--- 542 unchanged lines hidden (view full) ---

551};
552
553static void decode_0F3A(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
554{
555 *b = x86_ldub_code(env, s);
556 *entry = opcodes_0F3A[*b];
557}
558
559/*
560 * There are some mistakes in the operands in the manual, and the load/store/register
561 * cases are easiest to keep separate, so the entries for 10-17 follow simplicity and
562 * efficiency of implementation rather than copying what the manual says.
563 *
564 * In particular:
565 *
566 * 1) "VMOVSS m32, xmm1" and "VMOVSD m64, xmm1" do not support VEX.vvvv != 1111b,
567 * but this is not mentioned in the tables.
568 *
569 * 2) MOVHLPS, MOVHPS, MOVHPD, MOVLPD, MOVLPS read the high quadword of one of their
570 * operands, which must therefore be dq; MOVLPD and MOVLPS also write the high
571 * quadword of the V operand.
572 */
573static void decode_0F10(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
574{
575 static const X86OpEntry opcodes_0F10_reg[4] = {
576 X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPS */
577 X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPD */
578 X86_OP_ENTRY3(VMOVSS, V,x, H,x, W,x, vex4),
579 X86_OP_ENTRY3(VMOVLPx, V,x, H,x, W,x, vex4), /* MOVSD */
580 };
581
582 static const X86OpEntry opcodes_0F10_mem[4] = {
583 X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPS */
584 X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPD */
585 X86_OP_ENTRY3(VMOVSS_ld, V,x, H,x, M,ss, vex4),
586 X86_OP_ENTRY3(VMOVSD_ld, V,x, H,x, M,sd, vex4),
587 };
588
589 if ((get_modrm(s, env) >> 6) == 3) {
590 *entry = *decode_by_prefix(s, opcodes_0F10_reg);
591 } else {
592 *entry = *decode_by_prefix(s, opcodes_0F10_mem);
593 }
594}
595
596static void decode_0F11(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
597{
598 static const X86OpEntry opcodes_0F11_reg[4] = {
599 X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPS */
600 X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPD */
601 X86_OP_ENTRY3(VMOVSS, W,x, H,x, V,x, vex4),
602 X86_OP_ENTRY3(VMOVLPx, W,x, H,x, V,q, vex4), /* MOVSD */
603 };
604
605 static const X86OpEntry opcodes_0F11_mem[4] = {
606 X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPS */
607 X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPD */
608 X86_OP_ENTRY3(VMOVSS_st, M,ss, None,None, V,x, vex4),
609 X86_OP_ENTRY3(VMOVLPx_st, M,sd, None,None, V,x, vex4), /* MOVSD */
610 };
611
612 if ((get_modrm(s, env) >> 6) == 3) {
613 *entry = *decode_by_prefix(s, opcodes_0F11_reg);
614 } else {
615 *entry = *decode_by_prefix(s, opcodes_0F11_mem);
616 }
617}
618
619static void decode_0F12(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
620{
621 static const X86OpEntry opcodes_0F12_mem[4] = {
622 /*
623 * Use dq for operand for compatibility with gen_MOVSD and
624 * to allow VEX128 only.
625 */
626 X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex4), /* MOVLPS */
627 X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex4), /* MOVLPD */
628 X86_OP_ENTRY3(VMOVSLDUP, V,x, None,None, W,x, vex4 cpuid(SSE3)),
629 X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, WM,q, vex4 cpuid(SSE3)), /* qq if VEX.256 */
630 };
631 static const X86OpEntry opcodes_0F12_reg[4] = {
632 X86_OP_ENTRY3(VMOVHLPS, V,dq, H,dq, U,dq, vex4),
633 X86_OP_ENTRY3(VMOVLPx, W,x, H,x, U,q, vex4), /* MOVLPD */
634 X86_OP_ENTRY3(VMOVSLDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
635 X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
636 };
637
638 if ((get_modrm(s, env) >> 6) == 3) {
639 *entry = *decode_by_prefix(s, opcodes_0F12_reg);
640 } else {
641 *entry = *decode_by_prefix(s, opcodes_0F12_mem);
642 if ((s->prefix & PREFIX_REPNZ) && s->vex_l) {
643 entry->s2 = X86_SIZE_qq;
644 }
645 }
646}
647
648static void decode_0F16(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
649{
650 static const X86OpEntry opcodes_0F16_mem[4] = {
651 /*
652 * Operand 1 technically only reads the low 64 bits, but uses dq so that
653 * it is easier to check for op0 == op1 in an endianness-neutral manner.
654 */
655 X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex4), /* MOVHPS */
656 X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex4), /* MOVHPD */
657 X86_OP_ENTRY3(VMOVSHDUP, V,x, None,None, W,x, vex4 cpuid(SSE3)),
658 {},
659 };
660 static const X86OpEntry opcodes_0F16_reg[4] = {
661 /* Same as above, operand 1 could be Hq if it wasn't for big-endian. */
662 X86_OP_ENTRY3(VMOVLHPS, V,dq, H,dq, U,q, vex4),
663 X86_OP_ENTRY3(VMOVHPx, V,x, H,x, U,x, vex4), /* MOVHPD */
664 X86_OP_ENTRY3(VMOVSHDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
665 {},
666 };
667
668 if ((get_modrm(s, env) >> 6) == 3) {
669 *entry = *decode_by_prefix(s, opcodes_0F16_reg);
670 } else {
671 *entry = *decode_by_prefix(s, opcodes_0F16_mem);
672 }
673}
674
559static void decode_sse_unary(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
560{
561 if (!(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))) {
562 entry->op1 = X86_TYPE_None;
563 entry->s1 = X86_SIZE_None;
564 }
565 switch (*b) {
566 case 0x51: entry->gen = gen_VSQRT; break;

--- 21 unchanged lines hidden (view full) ---

588 X86_OP_ENTRY2(VCVTTPD2DQ, V,x, W,x, vex2),
589 X86_OP_ENTRY2(VCVTDQ2PD, V,x, W,x, vex2),
590 X86_OP_ENTRY2(VCVTPD2DQ, V,x, W,x, vex2),
591 };
592 *entry = *decode_by_prefix(s, opcodes_0FE6);
593}
594
595static const X86OpEntry opcodes_0F[256] = {
675static void decode_sse_unary(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
676{
677 if (!(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))) {
678 entry->op1 = X86_TYPE_None;
679 entry->s1 = X86_SIZE_None;
680 }
681 switch (*b) {
682 case 0x51: entry->gen = gen_VSQRT; break;

--- 21 unchanged lines hidden (view full) ---

704 X86_OP_ENTRY2(VCVTTPD2DQ, V,x, W,x, vex2),
705 X86_OP_ENTRY2(VCVTDQ2PD, V,x, W,x, vex2),
706 X86_OP_ENTRY2(VCVTPD2DQ, V,x, W,x, vex2),
707 };
708 *entry = *decode_by_prefix(s, opcodes_0FE6);
709}
710
711static const X86OpEntry opcodes_0F[256] = {
712 [0x10] = X86_OP_GROUP0(0F10),
713 [0x11] = X86_OP_GROUP0(0F11),
714 [0x12] = X86_OP_GROUP0(0F12),
715 [0x13] = X86_OP_ENTRY3(VMOVLPx_st, M,q, None,None, V,q, vex4 p_00_66),
716 [0x14] = X86_OP_ENTRY3(VUNPCKLPx, V,x, H,x, W,x, vex4 p_00_66),
717 [0x15] = X86_OP_ENTRY3(VUNPCKHPx, V,x, H,x, W,x, vex4 p_00_66),
718 [0x16] = X86_OP_GROUP0(0F16),
719 /* Incorrectly listed as Mq,Vq in the manual */
720 [0x17] = X86_OP_ENTRY3(VMOVHPx_st, M,q, None,None, V,dq, vex4 p_00_66),
721
596 [0x50] = X86_OP_ENTRY3(MOVMSK, G,y, None,None, U,x, vex7 p_00_66),
597 [0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
598 [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
599 [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
600 [0x54] = X86_OP_ENTRY3(PAND, V,x, H,x, W,x, vex4 p_00_66), /* vand */
601 [0x55] = X86_OP_ENTRY3(PANDN, V,x, H,x, W,x, vex4 p_00_66), /* vandn */
602 [0x56] = X86_OP_ENTRY3(POR, V,x, H,x, W,x, vex4 p_00_66), /* vor */
603 [0x57] = X86_OP_ENTRY3(PXOR, V,x, H,x, W,x, vex4 p_00_66), /* vxor */

--- 978 unchanged lines hidden ---
722 [0x50] = X86_OP_ENTRY3(MOVMSK, G,y, None,None, U,x, vex7 p_00_66),
723 [0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
724 [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
725 [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
726 [0x54] = X86_OP_ENTRY3(PAND, V,x, H,x, W,x, vex4 p_00_66), /* vand */
727 [0x55] = X86_OP_ENTRY3(PANDN, V,x, H,x, W,x, vex4 p_00_66), /* vandn */
728 [0x56] = X86_OP_ENTRY3(POR, V,x, H,x, W,x, vex4 p_00_66), /* vor */
729 [0x57] = X86_OP_ENTRY3(PXOR, V,x, H,x, W,x, vex4 p_00_66), /* vxor */

--- 978 unchanged lines hidden ---