diff options
author | Richard Henderson <rth@twiddle.net> | 2013-01-23 18:09:43 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-02-18 15:52:32 -0800 |
commit | 0592f74a75ab695efd48a151219667adc0fa7cc4 (patch) | |
tree | d6997522a82b9277e269005cd4fa1f97fbe65b35 /target-i386/translate.c | |
parent | 5f1f4b177152286102475f9bffc359002a14d9c9 (diff) |
target-i386: Implement PDEP, PEXT
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r-- | target-i386/translate.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 3017d63163..51016fedd5 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -4138,6 +4138,42 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } break; + case 0x3f5: /* pdep Gy, By, Ey */ + if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) + || !(s->prefix & PREFIX_VEX) + || s->vex_l != 0) { + goto illegal_op; + } + ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); + /* Note that by zero-extending the mask operand, we + automatically handle zero-extending the result. */ + if (s->dflag == 2) { + tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]); + } else { + tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]); + } + gen_helper_pdep(cpu_regs[reg], cpu_T[0], cpu_T[1]); + break; + + case 0x2f5: /* pext Gy, By, Ey */ + if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) + || !(s->prefix & PREFIX_VEX) + || s->vex_l != 0) { + goto illegal_op; + } + ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); + /* Note that by zero-extending the mask operand, we + automatically handle zero-extending the result. */ + if (s->dflag == 2) { + tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]); + } else { + tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]); + } + gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]); + break; + case 0x0f3: case 0x1f3: case 0x2f3: |