diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index b00113ab..82f5f0fe 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -8187,6 +8187,36 @@ case 0x101: /* bnd registers are now in-use */ gen_set_hflag(s, HF_MPX_IU_MASK); } + } else if (mod != 3) { + /* bndldx */ + AddressParts a = gen_lea_modrm_0(env, s, modrm); + if (reg >= 4 + || (prefixes & PREFIX_LOCK) + || s->aflag == MO_16 + || a.base < -1) { + goto illegal_op; + } + if (a.base >= 0) { + tcg_gen_addi_tl(tcg_ctx, cpu_A0, *cpu_regs[a.base], a.disp); + } else { + tcg_gen_movi_tl(tcg_ctx, cpu_A0, 0); + } + gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override); + if (a.index >= 0) { + tcg_gen_mov_tl(tcg_ctx, cpu_T0, *cpu_regs[a.index]); + } else { + tcg_gen_movi_tl(tcg_ctx, cpu_T0, 0); + } + if (CODE64(s)) { + gen_helper_bndldx64(tcg_ctx, tcg_ctx->cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0); + tcg_gen_ld_i64(tcg_ctx, tcg_ctx->cpu_bndu[reg], cpu_env, + offsetof(CPUX86State, mmx_t0.MMX_Q(0))); + } else { + gen_helper_bndldx32(tcg_ctx, tcg_ctx->cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0); + tcg_gen_ext32u_i64(tcg_ctx, tcg_ctx->cpu_bndl[reg], tcg_ctx->cpu_bndu[reg]); + tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_bndu[reg], tcg_ctx->cpu_bndu[reg], 32); + } + gen_set_hflag(s, HF_MPX_IU_MASK); } } gen_nop_modrm(env, s, modrm); @@ -8262,6 +8292,33 @@ case 0x101: s->mem_index, MO_LEUL); } } + } else if (mod != 3) { + /* bndstx */ + AddressParts a = gen_lea_modrm_0(env, s, modrm); + if (reg >= 4 + || (prefixes & PREFIX_LOCK) + || s->aflag == MO_16 + || a.base < -1) { + goto illegal_op; + } + if (a.base >= 0) { + tcg_gen_addi_tl(tcg_ctx, cpu_A0, *cpu_regs[a.base], a.disp); + } else { + tcg_gen_movi_tl(tcg_ctx, cpu_A0, 0); + } + gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override); + if (a.index >= 0) { + tcg_gen_mov_tl(tcg_ctx, cpu_T0, *cpu_regs[a.index]); + } else { + tcg_gen_movi_tl(tcg_ctx, cpu_T0, 0); + } + if (CODE64(s)) { + gen_helper_bndstx64(tcg_ctx, cpu_env, cpu_A0, cpu_T0, + tcg_ctx->cpu_bndl[reg], tcg_ctx->cpu_bndu[reg]); + } else { + gen_helper_bndstx32(tcg_ctx, cpu_env, cpu_A0, cpu_T0, + tcg_ctx->cpu_bndl[reg], tcg_ctx->cpu_bndu[reg]); + } } } gen_nop_modrm(env, s, modrm);