Patchwork [51/57] target-i386: Implement PDEP, PEXT

login
register
mail settings
Submitter Richard Henderson
Date Jan. 24, 2013, 4:03 a.m.
Message ID <1359000221-19834-52-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/215208/
State New
Headers show

Comments

Richard Henderson - Jan. 24, 2013, 4:03 a.m.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-i386/helper.h     |  3 +++
 target-i386/int_helper.c | 32 ++++++++++++++++++++++++++++++++
 target-i386/translate.c  | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

Patch

diff --git a/target-i386/helper.h b/target-i386/helper.h
index b1bae6c..1bb5dcf 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -193,9 +193,12 @@  DEF_HELPER_3(fsave, void, env, tl, int)
 DEF_HELPER_3(frstor, void, env, tl, int)
 DEF_HELPER_3(fxsave, void, env, tl, int)
 DEF_HELPER_3(fxrstor, void, env, tl, int)
+
 DEF_HELPER_1(bsf, tl, tl)
 DEF_HELPER_1(bsr, tl, tl)
 DEF_HELPER_2(lzcnt, tl, tl, int)
+DEF_HELPER_FLAGS_2(pdep, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(pext, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 
 /* MMX/SSE */
 
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index 4ec8cb7..527af40 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -488,6 +488,38 @@  target_ulong helper_bsr(target_ulong t0)
     return helper_lzcnt(t0, 0);
 }
 
+#if TARGET_LONG_BITS == 32
+# define ctztl  ctz32
+#else
+# define ctztl  ctz64
+#endif
+
+target_ulong helper_pdep(target_ulong src, target_ulong mask)
+{
+    target_ulong dest = 0;
+    int i, o;
+
+    for (i = 0; mask != 0; i++) {
+        o = ctztl(mask);
+        mask &= mask - 1;
+        dest |= ((src >> i) & 1) << o;
+    }
+    return dest;
+}
+
+target_ulong helper_pext(target_ulong src, target_ulong mask)
+{
+    target_ulong dest = 0;
+    int i, o;
+
+    for (o = 0; mask != 0; o++) {
+        i = ctztl(mask);
+        mask &= mask - 1;
+        dest |= ((src >> i) & 1) << o;
+    }
+    return dest;
+}
+
 #define SHIFT 0
 #include "shift_helper_template.h"
 #undef SHIFT
diff --git a/target-i386/translate.c b/target-i386/translate.c
index dc43ccf..5e1ee03 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4135,6 +4135,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: