[PULL 13/25] target/i386: convert MOV from/to CR and DR to new decoder
Complete implementation of C and D operand types, then the operations are just MOVs. Signed-off-by: Paolo Bonzini --- target/i386/tcg/decode-new.h | 1 + target/i386/tcg/translate.c | 79 target/i386/tcg/decode-new.c.inc | 61 ++-- target/i386/tcg/emit.c.inc | 24 +- 4 files changed, 81 insertions(+), 84 deletions(-) diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h index 8465717ea21..60a191ee763 100644 --- a/target/i386/tcg/decode-new.h +++ b/target/i386/tcg/decode-new.h @@ -90,6 +90,7 @@ typedef enum X86OpSize { X86_SIZE_w, /* 16-bit */ X86_SIZE_x, /* 128/256-bit, based on operand size */ X86_SIZE_y, /* 32/64-bit, based on operand size */ +X86_SIZE_y_d64, /* 32/64-bit, based on 64-bit mode */ X86_SIZE_z, /* 16-bit for 16-bit operand size, else 32-bit */ X86_SIZE_z_f64, /* 32-bit for 32-bit operand size or 64-bit mode, else 16-bit */ diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index fcba9c155f9..4958f4c45d5 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -247,9 +247,6 @@ STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(rdmsr, TCGv_env env) -STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) -STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg) -STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) STUB_HELPER(stgi, TCGv_env env) STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) @@ -4192,82 +4189,6 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) gen_nop_modrm(env, s, modrm); break; -case 0x120: /* mov reg, crN */ -case 0x122: /* mov crN, reg */ -if (!check_cpl0(s)) { -break; -} -modrm = x86_ldub_code(env, s); -/* - * Ignore the mod bits (assume (modrm&0xc0)==0xc0). - * AMD documentation (24594.pdf) and testing of Intel 386 and 486 - * processors all show that the mod bits are assumed to be 1's, - * regardless of actual values. - */ -rm = (modrm & 7) | REX_B(s); -reg = ((modrm >> 3) & 7) | REX_R(s); -switch (reg) { -case 0: -if ((prefixes & PREFIX_LOCK) && -(s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { -reg = 8; -} -break; -case 2: -case 3: -case 4: -case 8: -break; -default: -goto unknown_op; -} -ot = (CODE64(s) ? MO_64 : MO_32); - -translator_io_start(&s->base); -if (b & 2) { -gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); -gen_op_mov_v_reg(s, ot, s->T0, rm); -gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0); -s->base.is_jmp = DISAS_EOB_NEXT; -} else { -gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); -gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg)); -gen_op_mov_reg_v(s, ot, rm, s->T0); -} -break; - -case 0x121: /* mov reg, drN */ -case 0x123: /* mov drN, reg */ -if (check_cpl0(s)) { -modrm = x86_ldub_code(env, s); -/* Ignore the mod bits (assume (modrm&0xc0)==0xc0). - * AMD documentation (24594.pdf) and testing of - * intel 386 and 486 processors all show that the mod bits - * are assumed to be 1's, regardless of actual values. - */ -rm = (modrm & 7) | REX_B(s); -reg = ((modrm >> 3) & 7) | REX_R(s); -if (CODE64(s)) -ot = MO_64; -else -ot = MO_32; -if (reg >= 8) { -goto illegal_op; -} -if (b & 2) { -gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); -gen_op_mov_v_reg(s, ot, s->T0, rm); -tcg_gen_movi_i32(s->tmp2_i32, reg); -gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0); -s->base.is_jmp = DISAS_EOB_NEXT; -} else { -gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); -tcg_gen_movi_i32(s->tmp2_i32, reg); -gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32); -gen_op_mov_reg_v(s, ot, rm, s->T0); -} -} -break; case 0x106: /* clts */ if (check_cpl0(s)) { gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index cd925fe3589..0f31e1f455d 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -151,
[PULL 13/25] target/i386: convert MOV from/to CR and DR to new decoder
Complete implementation of C and D operand types, then the operations are just MOVs. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target/i386/tcg/translate.c | 79 target/i386/tcg/decode-new.c.inc | 53 +++-- target/i386/tcg/emit.c.inc | 20 +++- 3 files changed, 68 insertions(+), 84 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index fcba9c155f9..4958f4c45d5 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -247,9 +247,6 @@ STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val) STUB_HELPER(rdmsr, TCGv_env env) -STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) -STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg) -STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) STUB_HELPER(stgi, TCGv_env env) STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) @@ -4192,82 +4189,6 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) gen_nop_modrm(env, s, modrm); break; -case 0x120: /* mov reg, crN */ -case 0x122: /* mov crN, reg */ -if (!check_cpl0(s)) { -break; -} -modrm = x86_ldub_code(env, s); -/* - * Ignore the mod bits (assume (modrm&0xc0)==0xc0). - * AMD documentation (24594.pdf) and testing of Intel 386 and 486 - * processors all show that the mod bits are assumed to be 1's, - * regardless of actual values. - */ -rm = (modrm & 7) | REX_B(s); -reg = ((modrm >> 3) & 7) | REX_R(s); -switch (reg) { -case 0: -if ((prefixes & PREFIX_LOCK) && -(s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { -reg = 8; -} -break; -case 2: -case 3: -case 4: -case 8: -break; -default: -goto unknown_op; -} -ot = (CODE64(s) ? MO_64 : MO_32); - -translator_io_start(&s->base); -if (b & 2) { -gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg); -gen_op_mov_v_reg(s, ot, s->T0, rm); -gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0); -s->base.is_jmp = DISAS_EOB_NEXT; -} else { -gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg); -gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg)); -gen_op_mov_reg_v(s, ot, rm, s->T0); -} -break; - -case 0x121: /* mov reg, drN */ -case 0x123: /* mov drN, reg */ -if (check_cpl0(s)) { -modrm = x86_ldub_code(env, s); -/* Ignore the mod bits (assume (modrm&0xc0)==0xc0). - * AMD documentation (24594.pdf) and testing of - * intel 386 and 486 processors all show that the mod bits - * are assumed to be 1's, regardless of actual values. - */ -rm = (modrm & 7) | REX_B(s); -reg = ((modrm >> 3) & 7) | REX_R(s); -if (CODE64(s)) -ot = MO_64; -else -ot = MO_32; -if (reg >= 8) { -goto illegal_op; -} -if (b & 2) { -gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg); -gen_op_mov_v_reg(s, ot, s->T0, rm); -tcg_gen_movi_i32(s->tmp2_i32, reg); -gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0); -s->base.is_jmp = DISAS_EOB_NEXT; -} else { -gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg); -tcg_gen_movi_i32(s->tmp2_i32, reg); -gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32); -gen_op_mov_reg_v(s, ot, rm, s->T0); -} -} -break; case 0x106: /* clts */ if (check_cpl0(s)) { gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0); diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index cd925fe3589..4c567911f41 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -151,6 +151,8 @@ X86_OP_GROUP3(op, op0, s0, 2op, s0, op1, s1, ## __VA_ARGS__) #define X86_OP_GROUPw(op, op0, s0, ...) \ X86_OP_GROUP3(op, op0, s0, None, None, None, None, ## __VA_ARGS__) +#define X86_OP_GROUPwr(op, op0, s0, op1, s1, ...) \ +X86_OP_GROUP3(op, op0, s0, op1, s1, None, None, ## __VA_ARGS__) #define X86_OP_GROUP0(op, ...)\ X86_OP_GROUP3(op, None, None, None, None, None, None, ## __VA_ARGS__) @@ -985,6 +987,24 @@ static void decode_0FE6(DisasContext *s, CPUX86State *env, X86OpEntry *entry,