Commit ecc7e843 authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg/i386: Add tcg_out_vex_modrm



Prepare for emitting BMI insns which require VEX encoding.

Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent a1b29c9a
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -453,6 +453,41 @@ static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
    tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
}

static void tcg_out_vex_modrm(TCGContext *s, int opc, int r, int v, int rm)
{
    int tmp;

    if ((opc & (P_REXW | P_EXT | P_EXT38)) || (rm & 8)) {
        /* Three byte VEX prefix.  */
        tcg_out8(s, 0xc4);

        /* VEX.m-mmmm */
        if (opc & P_EXT38) {
            tmp = 2;
        } else if (opc & P_EXT) {
            tmp = 1;
        } else {
            tcg_abort();
        }
        tmp |= 0x40;                       /* VEX.X */
        tmp |= (r & 8 ? 0 : 0x80);         /* VEX.R */
        tmp |= (rm & 8 ? 0 : 0x20);        /* VEX.B */
        tcg_out8(s, tmp);

        tmp = (opc & P_REXW ? 0x80 : 0);   /* VEX.W */
    } else {
        /* Two byte VEX prefix.  */
        tcg_out8(s, 0xc5);

        tmp = (r & 8 ? 0 : 0x80);          /* VEX.R */
    }
    tmp |= (opc & P_DATA16 ? 1 : 0);       /* VEX.pp */
    tmp |= (~v & 15) << 3;                 /* VEX.vvvv */
    tcg_out8(s, tmp);
    tcg_out8(s, opc);
    tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
}

/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
   We handle either RM and INDEX missing with a negative value.  In 64-bit
   mode for absolute addresses, ~RM is the size of the immediate operand