All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation
@ 2019-08-10  4:12 Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 01/39] target/i386: Push rex_r into DisasContext Jan Bobek
                   ` (40 more replies)
  0 siblings, 41 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

This is a v2 of the patch series posted in [1]. Patches 1-9 are just
cleanups; patches 10-39 are something actually interesting. Compared
to v1, I started using preprocessor more extensively to generate
repetitive boilerplate code; opinions/alternatives are welcome and
appreciated.

I tried to eliminate as many errors reported by scripts/checkpatch.pl
as I could, but there are still some left; AFAICT they appear to be
non-applicable false positives caused by preprocessor macros.

There is a known flaw of M* operands documented in patches 25 and 39;
it will be addressed in v3. (It has some design implications which
require larger changes, so that's why I'm not including them right
away, but I already have a good idea of how to address this.)

Cheers,
  -Jan

Changes from v1:
  There is in fact little overlap with v1, apart from the minor
  cleanup patches; I tried a different approach this time.

References:
  1. https://lists.nongnu.org/archive/html/qemu-devel/2019-07/msg07041.html

Jan Bobek (36):
  target/i386: reduce scope of variable aflag
  target/i386: use dflag from DisasContext
  target/i386: use prefix from DisasContext
  target/i386: use pc_start from DisasContext
  target/i386: make variable b1 const
  target/i386: make variable is_xmm const
  target/i386: add vector register file alignment constraints
  target/i386: introduce gen_(ld,st)d_env_A0
  target/i386: introduce gen_sse_ng
  target/i386: disable unused function warning temporarily
  target/i386: introduce mnemonic aliases for several gvec operations
  target/i386: introduce function ck_cpuid
  target/i386: introduce instruction operand infrastructure
  target/i386: introduce helpers for decoding modrm fields
  target/i386: introduce modifier for direct-only operand decoding
  target/i386: introduce generic operand alias
  target/i386: introduce generic load-store operand
  target/i386: introduce insn.h
  target/i386: introduce code generators
  target/i386: introduce instruction translator macros
  target/i386: introduce Ib (immediate) operand
  target/i386: introduce M* (memptr) operands
  target/i386: introduce G*, R*, E* (general register) operands
  target/i386: introduce RdMw operand
  target/i386: introduce P*, N*, Q* (MMX) operands
  target/i386: introduce helper-based code generator macros
  target/i386: introduce gvec-based code generator macros
  target/i386: introduce MMX translators
  target/i386: introduce MMX code generators
  target/i386: introduce MMX instructions to insn.h
  target/i386: introduce V*, U*, W* (SSE/AVX) operands
  target/i386: introduce UdqMq operand
  target/i386: introduce SSE translators
  target/i386: introduce SSE code generators
  target/i386: introduce SSE instructions to insn.h
  target/i386: introduce memory-pointer operand read/write workarounds

Richard Henderson (3):
  target/i386: Push rex_r into DisasContext
  target/i386: Push rex_w into DisasContext
  target/i386: Simplify gen_exception arguments

 target/i386/cpu.h       |    6 +-
 target/i386/insn.h      |  381 ++++++++
 target/i386/translate.c | 2032 ++++++++++++++++++++++++++++++++-------
 3 files changed, 2095 insertions(+), 324 deletions(-)
 create mode 100644 target/i386/insn.h

-- 
2.20.1



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 01/39] target/i386: Push rex_r into DisasContext
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 02/39] target/i386: Push rex_w " Jan Bobek
                   ` (39 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Richard Henderson, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Treat this value the same as we do for rex_b and rex_x.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/i386/translate.c | 85 +++++++++++++++++++++--------------------
 1 file changed, 44 insertions(+), 41 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 03150a86e2..d74dbfd585 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -43,10 +43,12 @@
 #define CODE64(s) ((s)->code64)
 #define REX_X(s) ((s)->rex_x)
 #define REX_B(s) ((s)->rex_b)
+#define REX_R(s) ((s)->rex_r)
 #else
 #define CODE64(s) 0
 #define REX_X(s) 0
 #define REX_B(s) 0
+#define REX_R(s) 0
 #endif
 
 #ifdef TARGET_X86_64
@@ -98,7 +100,7 @@ typedef struct DisasContext {
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
     int code64; /* 64 bit code segment */
-    int rex_x, rex_b;
+    int rex_x, rex_b, rex_r;
 #endif
     int vex_l;  /* vex vector length */
     int vex_v;  /* vex vvvv register, without 1's complement.  */
@@ -3037,7 +3039,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
 };
 
 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
-                    target_ulong pc_start, int rex_r)
+                    target_ulong pc_start)
 {
     int b1, op1_offset, op2_offset, is_xmm, val;
     int modrm, mod, rm, reg;
@@ -3107,8 +3109,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
 
     modrm = x86_ldub_code(env, s);
     reg = ((modrm >> 3) & 7);
-    if (is_xmm)
-        reg |= rex_r;
+    if (is_xmm) {
+        reg |= REX_R(s);
+    }
     mod = (modrm >> 6) & 3;
     if (sse_fn_epp == SSE_SPECIAL) {
         b |= (b1 << 8);
@@ -3642,7 +3645,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                 tcg_gen_ld16u_tl(s->T0, cpu_env,
                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
             }
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             gen_op_mov_reg_v(s, ot, reg, s->T0);
             break;
         case 0x1d6: /* movq ea, xmm */
@@ -3686,7 +3689,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                                  offsetof(CPUX86State, fpregs[rm].mmx));
                 gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0);
             }
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
             break;
 
@@ -3698,7 +3701,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             }
             modrm = x86_ldub_code(env, s);
             rm = modrm & 7;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             if (b1 >= 2) {
                 goto unknown_op;
@@ -3774,7 +3777,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             /* Various integer extensions at 0f 38 f[0-f].  */
             b = modrm | (b1 << 8);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
 
             switch (b) {
             case 0x3f0: /* crc32 Gd,Eb */
@@ -4128,7 +4131,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             b = modrm;
             modrm = x86_ldub_code(env, s);
             rm = modrm & 7;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             if (b1 >= 2) {
                 goto unknown_op;
@@ -4148,7 +4151,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3)
                     gen_lea_modrm(env, s, modrm);
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 val = x86_ldub_code(env, s);
                 switch (b) {
                 case 0x14: /* pextrb */
@@ -4317,7 +4320,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             /* Various integer extensions at 0f 3a f[0-f].  */
             b = modrm | (b1 << 8);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
 
             switch (b) {
             case 0x3f0: /* rorx Gy,Ey, Ib */
@@ -4491,14 +4494,15 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     TCGMemOp ot, aflag, dflag;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
-    int rex_w, rex_r;
     target_ulong pc_start = s->base.pc_next;
+    int rex_w;
 
     s->pc_start = s->pc = pc_start;
     s->override = -1;
 #ifdef TARGET_X86_64
     s->rex_x = 0;
     s->rex_b = 0;
+    s->rex_r = 0;
     s->x86_64_hregs = false;
 #endif
     s->rip_offset = 0; /* for relative ip address */
@@ -4511,7 +4515,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     prefixes = 0;
     rex_w = -1;
-    rex_r = 0;
 
  next_byte:
     b = x86_ldub_code(env, s);
@@ -4555,9 +4558,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s)) {
             /* REX prefix */
             rex_w = (b >> 3) & 1;
-            rex_r = (b & 0x4) << 1;
+            s->rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
-            REX_B(s) = (b & 0x1) << 3;
+            s->rex_b = (b & 0x1) << 3;
             /* select uniform byte register addressing */
             s->x86_64_hregs = true;
             goto next_byte;
@@ -4590,8 +4593,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->x86_64_hregs) {
                 goto illegal_op;
             }
+            s->rex_r = (~vex2 >> 4) & 8;
 #endif
-            rex_r = (~vex2 >> 4) & 8;
             if (b == 0xc5) {
                 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
                 vex3 = vex2;
@@ -4681,7 +4684,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             switch(f) {
             case 0: /* OP Ev, Gv */
                 modrm = x86_ldub_code(env, s);
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 mod = (modrm >> 6) & 3;
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
@@ -4703,7 +4706,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             case 1: /* OP Gv, Ev */
                 modrm = x86_ldub_code(env, s);
                 mod = (modrm >> 6) & 3;
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
                     gen_lea_modrm(env, s, modrm);
@@ -5123,7 +5126,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d(b, dflag);
 
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_op_mov_v_reg(s, ot, s->T1, reg);
@@ -5195,7 +5198,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6b:
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         if (b == 0x69)
             s->rip_offset = insn_const_size(ot);
         else if (b == 0x6b)
@@ -5247,7 +5250,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c1: /* xadd Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         gen_op_mov_v_reg(s, ot, s->T0, reg);
         if (mod == 3) {
@@ -5279,7 +5282,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
             ot = mo_b_d(b, dflag);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             oldv = tcg_temp_new();
             newv = tcg_temp_new();
@@ -5502,7 +5505,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x89: /* mov Gv, Ev */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         /* generate a generic store */
         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
@@ -5528,7 +5531,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x8b: /* mov Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_op_mov_reg_v(s, ot, reg, s->T0);
@@ -5578,7 +5581,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             s_ot = b & 8 ? MO_SIGN | ot : ot;
 
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             rm = (modrm & 7) | REX_B(s);
 
@@ -5617,7 +5620,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         {
             AddressParts a = gen_lea_modrm_0(env, s, modrm);
             TCGv ea = gen_lea_modrm_1(s, a);
@@ -5699,7 +5702,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x87: /* xchg Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
@@ -5736,7 +5739,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_lxx:
         ot = dflag != MO_16 ? MO_32 : MO_16;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
@@ -5819,7 +5822,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         if (mod != 3) {
             gen_lea_modrm(env, s, modrm);
             opreg = OR_TMP0;
@@ -6674,7 +6677,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_cmovcc1(env, s, ot, b, modrm, reg);
         break;
 
@@ -6824,7 +6827,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_btx:
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
@@ -6929,7 +6932,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1bd: /* bsr / lzcnt */
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_extu(ot, s->T0);
 
@@ -7693,7 +7696,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             d_ot = dflag;
 
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             rm = (modrm & 7) | REX_B(s);
 
@@ -7767,7 +7770,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             ot = dflag != MO_16 ? MO_32 : MO_16;
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             t0 = tcg_temp_local_new();
             gen_update_cc_op(s);
@@ -7808,7 +7811,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (prefixes & PREFIX_REPZ) {
                 /* bndcl */
                 if (reg >= 4
@@ -7898,7 +7901,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
                 /* bndmk */
                 if (reg >= 4
@@ -8012,7 +8015,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
              * are assumed to be 1's, regardless of actual values.
              */
             rm = (modrm & 7) | REX_B(s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (CODE64(s))
                 ot = MO_64;
             else
@@ -8069,7 +8072,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
              * are assumed to be 1's, regardless of actual values.
              */
             rm = (modrm & 7) | REX_B(s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (CODE64(s))
                 ot = MO_64;
             else
@@ -8112,7 +8115,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         /* generate a generic store */
         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
         break;
@@ -8338,7 +8341,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             goto illegal_op;
 
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         if (s->prefix & PREFIX_DATA) {
             ot = MO_16;
@@ -8366,7 +8369,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c2:
     case 0x1c4 ... 0x1c6:
     case 0x1d0 ... 0x1fe:
-        gen_sse(env, s, b, pc_start, rex_r);
+        gen_sse(env, s, b, pc_start);
         break;
     default:
         goto unknown_op;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 02/39] target/i386: Push rex_w into DisasContext
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 01/39] target/i386: Push rex_r into DisasContext Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag Jan Bobek
                   ` (38 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Richard Henderson, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Treat this the same as we already do for other rex bits.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/i386/translate.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index d74dbfd585..c0866c2797 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -44,11 +44,13 @@
 #define REX_X(s) ((s)->rex_x)
 #define REX_B(s) ((s)->rex_b)
 #define REX_R(s) ((s)->rex_r)
+#define REX_W(s) ((s)->rex_w)
 #else
 #define CODE64(s) 0
 #define REX_X(s) 0
 #define REX_B(s) 0
 #define REX_R(s) 0
+#define REX_W(s) -1
 #endif
 
 #ifdef TARGET_X86_64
@@ -100,7 +102,7 @@ typedef struct DisasContext {
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
     int code64; /* 64 bit code segment */
-    int rex_x, rex_b, rex_r;
+    int rex_x, rex_b, rex_r, rex_w;
 #endif
     int vex_l;  /* vex vector length */
     int vex_v;  /* vex vvvv register, without 1's complement.  */
@@ -4495,7 +4497,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
     target_ulong pc_start = s->base.pc_next;
-    int rex_w;
 
     s->pc_start = s->pc = pc_start;
     s->override = -1;
@@ -4503,6 +4504,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     s->rex_x = 0;
     s->rex_b = 0;
     s->rex_r = 0;
+    s->rex_w = -1;
     s->x86_64_hregs = false;
 #endif
     s->rip_offset = 0; /* for relative ip address */
@@ -4514,7 +4516,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     }
 
     prefixes = 0;
-    rex_w = -1;
 
  next_byte:
     b = x86_ldub_code(env, s);
@@ -4557,7 +4558,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x40 ... 0x4f:
         if (CODE64(s)) {
             /* REX prefix */
-            rex_w = (b >> 3) & 1;
+            s->rex_w = (b >> 3) & 1;
             s->rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
             s->rex_b = (b & 0x1) << 3;
@@ -4606,7 +4607,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 s->rex_b = (~vex2 >> 2) & 8;
 #endif
                 vex3 = x86_ldub_code(env, s);
-                rex_w = (vex3 >> 7) & 1;
+#ifdef TARGET_X86_64
+                s->rex_w = (vex3 >> 7) & 1;
+#endif
                 switch (vex2 & 0x1f) {
                 case 0x01: /* Implied 0f leading opcode bytes.  */
                     b = x86_ldub_code(env, s) | 0x100;
@@ -4631,9 +4634,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     /* Post-process prefixes.  */
     if (CODE64(s)) {
         /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
-           data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
+           data with REX_W, and 16-bit data with 0x66; REX_W takes precedence
            over 0x66 if both are present.  */
-        dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
+        dflag = (REX_W(s) > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
         /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
     } else {
@@ -5029,7 +5032,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* operand size for jumps is 64 bit */
                 ot = MO_64;
             } else if (op == 3 || op == 5) {
-                ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
+                ot = dflag != MO_16 ? MO_32 + (REX_W(s) == 1) : MO_16;
             } else if (op == 6) {
                 /* default push size is 64 bit */
                 ot = mo_pushpop(s, dflag);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 01/39] target/i386: Push rex_r into DisasContext Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 02/39] target/i386: Push rex_w " Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:47   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext Jan Bobek
                   ` (37 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Jan Bobek, Alex Bennée, Richard Henderson, Richard Henderson

The variable aflag is not used in most of disas_insn; make this clear
by explicitly reducing its scope to the block where it is used.

Suggested-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index c0866c2797..bda96277e4 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4493,11 +4493,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     CPUX86State *env = cpu->env_ptr;
     int b, prefixes;
     int shift;
-    TCGMemOp ot, aflag, dflag;
+    TCGMemOp ot, dflag;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
     target_ulong pc_start = s->base.pc_next;
 
+    {
+    TCGMemOp aflag;
+
     s->pc_start = s->pc = pc_start;
     s->override = -1;
 #ifdef TARGET_X86_64
@@ -4657,6 +4660,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     s->prefix = prefixes;
     s->aflag = aflag;
     s->dflag = dflag;
+    }
 
     /* now check op code */
  reswitch:
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (2 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:48   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix " Jan Bobek
                   ` (36 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Jan Bobek, Alex Bennée, Richard Henderson, Richard Henderson

There already is a variable dflag in DisasContext, so reduce the scope
of the local variable dflag to enforce use of the one in DisasContext.

Suggested-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 184 ++++++++++++++++++++--------------------
 1 file changed, 92 insertions(+), 92 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index bda96277e4..bb13877df7 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4493,13 +4493,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     CPUX86State *env = cpu->env_ptr;
     int b, prefixes;
     int shift;
-    TCGMemOp ot, dflag;
+    TCGMemOp ot;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
     target_ulong pc_start = s->base.pc_next;
 
     {
-    TCGMemOp aflag;
+    TCGMemOp aflag, dflag;
 
     s->pc_start = s->pc = pc_start;
     s->override = -1;
@@ -4686,7 +4686,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             op = (b >> 3) & 7;
             f = (b >> 1) & 3;
 
-            ot = mo_b_d(b, dflag);
+            ot = mo_b_d(b, s->dflag);
 
             switch(f) {
             case 0: /* OP Ev, Gv */
@@ -4744,7 +4744,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         {
             int val;
 
-            ot = mo_b_d(b, dflag);
+            ot = mo_b_d(b, s->dflag);
 
             modrm = x86_ldub_code(env, s);
             mod = (modrm >> 6) & 3;
@@ -4781,16 +4781,16 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /**************************/
         /* inc, dec, and other misc arith */
     case 0x40 ... 0x47: /* inc Gv */
-        ot = dflag;
+        ot = s->dflag;
         gen_inc(s, ot, OR_EAX + (b & 7), 1);
         break;
     case 0x48 ... 0x4f: /* dec Gv */
-        ot = dflag;
+        ot = s->dflag;
         gen_inc(s, ot, OR_EAX + (b & 7), -1);
         break;
     case 0xf6: /* GRP3 */
     case 0xf7:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
 
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
@@ -5022,7 +5022,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xfe: /* GRP4 */
     case 0xff: /* GRP5 */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
 
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
@@ -5036,10 +5036,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* operand size for jumps is 64 bit */
                 ot = MO_64;
             } else if (op == 3 || op == 5) {
-                ot = dflag != MO_16 ? MO_32 + (REX_W(s) == 1) : MO_16;
+                ot = s->dflag != MO_16 ? MO_32 + (REX_W(s) == 1) : MO_16;
             } else if (op == 6) {
                 /* default push size is 64 bit */
-                ot = mo_pushpop(s, dflag);
+                ot = mo_pushpop(s, s->dflag);
             }
         }
         if (mod != 3) {
@@ -5067,7 +5067,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
         case 2: /* call Ev */
             /* XXX: optimize if memory (no 'and' is necessary) */
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_ext16u_tl(s->T0, s->T0);
             }
             next_eip = s->pc - s->cs_base;
@@ -5085,19 +5085,19 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->pe && !s->vm86) {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
-                                           tcg_const_i32(dflag - 1),
+                                           tcg_const_i32(s->dflag - 1),
                                            tcg_const_tl(s->pc - s->cs_base));
             } else {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->T1,
-                                      tcg_const_i32(dflag - 1),
+                                      tcg_const_i32(s->dflag - 1),
                                       tcg_const_i32(s->pc - s->cs_base));
             }
             tcg_gen_ld_tl(s->tmp4, cpu_env, offsetof(CPUX86State, eip));
             gen_jr(s, s->tmp4);
             break;
         case 4: /* jmp Ev */
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_ext16u_tl(s->T0, s->T0);
             }
             gen_op_jmp_v(s->T0);
@@ -5130,7 +5130,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0x84: /* test Ev, Gv */
     case 0x85:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
 
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
@@ -5143,7 +5143,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xa8: /* test eAX, Iv */
     case 0xa9:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         val = insn_get(env, s, ot);
 
         gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
@@ -5153,7 +5153,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
 
     case 0x98: /* CWDE/CBW */
-        switch (dflag) {
+        switch (s->dflag) {
 #ifdef TARGET_X86_64
         case MO_64:
             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
@@ -5176,7 +5176,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         break;
     case 0x99: /* CDQ/CWD */
-        switch (dflag) {
+        switch (s->dflag) {
 #ifdef TARGET_X86_64
         case MO_64:
             gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
@@ -5203,7 +5203,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1af: /* imul Gv, Ev */
     case 0x69: /* imul Gv, Ev, I */
     case 0x6b:
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         if (b == 0x69)
@@ -5255,7 +5255,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x1c0:
     case 0x1c1: /* xadd Ev, Gv */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
@@ -5287,7 +5287,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         {
             TCGv oldv, newv, cmpv;
 
-            ot = mo_b_d(b, dflag);
+            ot = mo_b_d(b, s->dflag);
             modrm = x86_ldub_code(env, s);
             reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
@@ -5348,7 +5348,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
 #ifdef TARGET_X86_64
-            if (dflag == MO_64) {
+            if (s->dflag == MO_64) {
                 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
                     goto illegal_op;
                 }
@@ -5388,7 +5388,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             }
             gen_helper_rdrand(s->T0, cpu_env);
             rm = (modrm & 7) | REX_B(s);
-            gen_op_mov_reg_v(s, dflag, rm, s->T0);
+            gen_op_mov_reg_v(s, s->dflag, rm, s->T0);
             set_cc_op(s, CC_OP_EFLAGS);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
                 gen_io_end();
@@ -5425,7 +5425,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x68: /* push Iv */
     case 0x6a:
-        ot = mo_pushpop(s, dflag);
+        ot = mo_pushpop(s, s->dflag);
         if (b == 0x68)
             val = insn_get(env, s, ot);
         else
@@ -5510,7 +5510,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* mov */
     case 0x88:
     case 0x89: /* mov Gv, Ev */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
 
@@ -5519,7 +5519,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xc6:
     case 0xc7: /* mov Ev, Iv */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
         if (mod != 3) {
@@ -5536,7 +5536,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x8a:
     case 0x8b: /* mov Ev, Gv */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
 
@@ -5568,7 +5568,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (reg >= 6)
             goto illegal_op;
         gen_op_movl_T0_seg(s, reg);
-        ot = mod == 3 ? dflag : MO_16;
+        ot = mod == 3 ? s->dflag : MO_16;
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
         break;
 
@@ -5581,7 +5581,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             TCGMemOp s_ot;
 
             /* d_ot is the size of destination */
-            d_ot = dflag;
+            d_ot = s->dflag;
             /* ot is the size of source */
             ot = (b & 1) + MO_8;
             /* s_ot is the sign+size of source */
@@ -5632,7 +5632,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             AddressParts a = gen_lea_modrm_0(env, s, modrm);
             TCGv ea = gen_lea_modrm_1(s, a);
             gen_lea_v_seg(s, s->aflag, ea, -1, -1);
-            gen_op_mov_reg_v(s, dflag, reg, s->A0);
+            gen_op_mov_reg_v(s, s->dflag, reg, s->A0);
         }
         break;
 
@@ -5643,7 +5643,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         {
             target_ulong offset_addr;
 
-            ot = mo_b_d(b, dflag);
+            ot = mo_b_d(b, s->dflag);
             switch (s->aflag) {
 #ifdef TARGET_X86_64
             case MO_64:
@@ -5681,7 +5681,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xb8 ... 0xbf: /* mov R, Iv */
 #ifdef TARGET_X86_64
-        if (dflag == MO_64) {
+        if (s->dflag == MO_64) {
             uint64_t tmp;
             /* 64 bit case */
             tmp = x86_ldq_code(env, s);
@@ -5691,7 +5691,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         } else
 #endif
         {
-            ot = dflag;
+            ot = s->dflag;
             val = insn_get(env, s, ot);
             reg = (b & 7) | REX_B(s);
             tcg_gen_movi_tl(s->T0, val);
@@ -5701,13 +5701,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0x91 ... 0x97: /* xchg R, EAX */
     do_xchg_reg_eax:
-        ot = dflag;
+        ot = s->dflag;
         reg = (b & 7) | REX_B(s);
         rm = R_EAX;
         goto do_xchg_reg;
     case 0x86:
     case 0x87: /* xchg Ev, Gv */
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
@@ -5744,7 +5744,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1b5: /* lgs Gv */
         op = R_GS;
     do_lxx:
-        ot = dflag != MO_16 ? MO_32 : MO_16;
+        ot = s->dflag != MO_16 ? MO_32 : MO_16;
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
@@ -5772,7 +5772,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         shift = 2;
     grp2:
         {
-            ot = mo_b_d(b, dflag);
+            ot = mo_b_d(b, s->dflag);
             modrm = x86_ldub_code(env, s);
             mod = (modrm >> 6) & 3;
             op = (modrm >> 3) & 7;
@@ -5825,7 +5825,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         op = 1;
         shift = 0;
     do_shiftd:
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
@@ -5987,7 +5987,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 }
                 break;
             case 0x0c: /* fldenv mem */
-                gen_helper_fldenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
+                gen_helper_fldenv(cpu_env, s->A0, tcg_const_i32(s->dflag - 1));
                 break;
             case 0x0d: /* fldcw mem */
                 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
@@ -5995,7 +5995,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_helper_fldcw(cpu_env, s->tmp2_i32);
                 break;
             case 0x0e: /* fnstenv mem */
-                gen_helper_fstenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
+                gen_helper_fstenv(cpu_env, s->A0, tcg_const_i32(s->dflag - 1));
                 break;
             case 0x0f: /* fnstcw mem */
                 gen_helper_fnstcw(s->tmp2_i32, cpu_env);
@@ -6010,10 +6010,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_helper_fpop(cpu_env);
                 break;
             case 0x2c: /* frstor mem */
-                gen_helper_frstor(cpu_env, s->A0, tcg_const_i32(dflag - 1));
+                gen_helper_frstor(cpu_env, s->A0, tcg_const_i32(s->dflag - 1));
                 break;
             case 0x2e: /* fnsave mem */
-                gen_helper_fsave(cpu_env, s->A0, tcg_const_i32(dflag - 1));
+                gen_helper_fsave(cpu_env, s->A0, tcg_const_i32(s->dflag - 1));
                 break;
             case 0x2f: /* fnstsw mem */
                 gen_helper_fnstsw(s->tmp2_i32, cpu_env);
@@ -6355,7 +6355,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xa4: /* movsS */
     case 0xa5:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
@@ -6365,7 +6365,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xaa: /* stosS */
     case 0xab:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
@@ -6374,7 +6374,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xac: /* lodsS */
     case 0xad:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
@@ -6383,7 +6383,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xae: /* scasS */
     case 0xaf:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         if (prefixes & PREFIX_REPNZ) {
             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
         } else if (prefixes & PREFIX_REPZ) {
@@ -6395,7 +6395,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xa6: /* cmpsS */
     case 0xa7:
-        ot = mo_b_d(b, dflag);
+        ot = mo_b_d(b, s->dflag);
         if (prefixes & PREFIX_REPNZ) {
             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
         } else if (prefixes & PREFIX_REPZ) {
@@ -6406,7 +6406,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x6c: /* insS */
     case 0x6d:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base, 
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
@@ -6421,7 +6421,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x6e: /* outsS */
     case 0x6f:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      svm_is_rep(prefixes) | 4);
@@ -6440,7 +6440,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0xe4:
     case 0xe5:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
         gen_check_io(s, ot, pc_start - s->cs_base,
@@ -6459,7 +6459,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xe6:
     case 0xe7:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
         gen_check_io(s, ot, pc_start - s->cs_base,
@@ -6480,7 +6480,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xec:
     case 0xed:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
@@ -6498,7 +6498,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xee:
     case 0xef:
-        ot = mo_b_d32(b, dflag);
+        ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      svm_is_rep(prefixes));
@@ -6542,21 +6542,21 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->pe && !s->vm86) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
+            gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag - 1),
                                       tcg_const_i32(val));
         } else {
             gen_stack_A0(s);
             /* pop offset */
-            gen_op_ld_v(s, dflag, s->T0, s->A0);
+            gen_op_ld_v(s, s->dflag, s->T0, s->A0);
             /* NOTE: keeping EIP updated is not a problem in case of
                exception */
             gen_op_jmp_v(s->T0);
             /* pop selector */
-            gen_add_A0_im(s, 1 << dflag);
-            gen_op_ld_v(s, dflag, s->T0, s->A0);
+            gen_add_A0_im(s, 1 << s->dflag);
+            gen_op_ld_v(s, s->dflag, s->T0, s->A0);
             gen_op_movl_seg_T0_vm(s, R_CS);
             /* add stack offset */
-            gen_stack_update(s, val + (2 << dflag));
+            gen_stack_update(s, val + (2 << s->dflag));
         }
         gen_eob(s);
         break;
@@ -6567,17 +6567,17 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
         if (!s->pe) {
             /* real mode */
-            gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
+            gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag - 1));
             set_cc_op(s, CC_OP_EFLAGS);
         } else if (s->vm86) {
             if (s->iopl != 3) {
                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             } else {
-                gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
+                gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag - 1));
                 set_cc_op(s, CC_OP_EFLAGS);
             }
         } else {
-            gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
+            gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag - 1),
                                       tcg_const_i32(s->pc - s->cs_base));
             set_cc_op(s, CC_OP_EFLAGS);
         }
@@ -6585,14 +6585,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xe8: /* call im */
         {
-            if (dflag != MO_16) {
+            if (s->dflag != MO_16) {
                 tval = (int32_t)insn_get(env, s, MO_32);
             } else {
                 tval = (int16_t)insn_get(env, s, MO_16);
             }
             next_eip = s->pc - s->cs_base;
             tval += next_eip;
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tval &= 0xffff;
             } else if (!CODE64(s)) {
                 tval &= 0xffffffff;
@@ -6609,7 +6609,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
             if (CODE64(s))
                 goto illegal_op;
-            ot = dflag;
+            ot = s->dflag;
             offset = insn_get(env, s, ot);
             selector = insn_get(env, s, MO_16);
 
@@ -6618,13 +6618,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         goto do_lcall;
     case 0xe9: /* jmp im */
-        if (dflag != MO_16) {
+        if (s->dflag != MO_16) {
             tval = (int32_t)insn_get(env, s, MO_32);
         } else {
             tval = (int16_t)insn_get(env, s, MO_16);
         }
         tval += s->pc - s->cs_base;
-        if (dflag == MO_16) {
+        if (s->dflag == MO_16) {
             tval &= 0xffff;
         } else if (!CODE64(s)) {
             tval &= 0xffffffff;
@@ -6638,7 +6638,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
             if (CODE64(s))
                 goto illegal_op;
-            ot = dflag;
+            ot = s->dflag;
             offset = insn_get(env, s, ot);
             selector = insn_get(env, s, MO_16);
 
@@ -6649,7 +6649,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xeb: /* jmp Jb */
         tval = (int8_t)insn_get(env, s, MO_8);
         tval += s->pc - s->cs_base;
-        if (dflag == MO_16) {
+        if (s->dflag == MO_16) {
             tval &= 0xffff;
         }
         gen_jmp(s, tval);
@@ -6658,7 +6658,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         tval = (int8_t)insn_get(env, s, MO_8);
         goto do_jcc;
     case 0x180 ... 0x18f: /* jcc Jv */
-        if (dflag != MO_16) {
+        if (s->dflag != MO_16) {
             tval = (int32_t)insn_get(env, s, MO_32);
         } else {
             tval = (int16_t)insn_get(env, s, MO_16);
@@ -6666,7 +6666,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_jcc:
         next_eip = s->pc - s->cs_base;
         tval += next_eip;
-        if (dflag == MO_16) {
+        if (s->dflag == MO_16) {
             tval &= 0xffff;
         }
         gen_bnd_jmp(s);
@@ -6682,7 +6682,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (!(s->cpuid_features & CPUID_CMOV)) {
             goto illegal_op;
         }
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_cmovcc1(env, s, ot, b, modrm, reg);
@@ -6707,7 +6707,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         } else {
             ot = gen_pop_T0(s);
             if (s->cpl == 0) {
-                if (dflag != MO_16) {
+                if (s->dflag != MO_16) {
                     gen_helper_write_eflags(cpu_env, s->T0,
                                             tcg_const_i32((TF_MASK | AC_MASK |
                                                            ID_MASK | NT_MASK |
@@ -6722,7 +6722,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 }
             } else {
                 if (s->cpl <= s->iopl) {
-                    if (dflag != MO_16) {
+                    if (s->dflag != MO_16) {
                         gen_helper_write_eflags(cpu_env, s->T0,
                                                 tcg_const_i32((TF_MASK |
                                                                AC_MASK |
@@ -6739,7 +6739,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                                                               & 0xffff));
                     }
                 } else {
-                    if (dflag != MO_16) {
+                    if (s->dflag != MO_16) {
                         gen_helper_write_eflags(cpu_env, s->T0,
                                            tcg_const_i32((TF_MASK | AC_MASK |
                                                           ID_MASK | NT_MASK)));
@@ -6799,7 +6799,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /************************/
         /* bit operations */
     case 0x1ba: /* bt/bts/btr/btc Gv, im */
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         op = (modrm >> 3) & 7;
         mod = (modrm >> 6) & 3;
@@ -6832,7 +6832,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1bb: /* btc */
         op = 3;
     do_btx:
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
@@ -6937,7 +6937,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x1bc: /* bsf / tzcnt */
     case 0x1bd: /* bsr / lzcnt */
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
@@ -7111,7 +7111,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x62: /* bound */
         if (CODE64(s))
             goto illegal_op;
-        ot = dflag;
+        ot = s->dflag;
         modrm = x86_ldub_code(env, s);
         reg = (modrm >> 3) & 7;
         mod = (modrm >> 6) & 3;
@@ -7129,7 +7129,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c8 ... 0x1cf: /* bswap reg */
         reg = (b & 7) | REX_B(s);
 #ifdef TARGET_X86_64
-        if (dflag == MO_64) {
+        if (s->dflag == MO_64) {
             gen_op_mov_v_reg(s, MO_64, s->T0, reg);
             tcg_gen_bswap64_i64(s->T0, s->T0);
             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
@@ -7159,7 +7159,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             tval = (int8_t)insn_get(env, s, MO_8);
             next_eip = s->pc - s->cs_base;
             tval += next_eip;
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tval &= 0xffff;
             }
 
@@ -7243,7 +7243,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (!s->pe) {
             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
         } else {
-            gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
+            gen_helper_sysexit(cpu_env, tcg_const_i32(s->dflag - 1));
             gen_eob(s);
         }
         break;
@@ -7262,7 +7262,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (!s->pe) {
             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
         } else {
-            gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
+            gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag - 1));
             /* condition codes are modified only in long mode */
             if (s->lma) {
                 set_cc_op(s, CC_OP_EFLAGS);
@@ -7301,7 +7301,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, ldt.selector));
-            ot = mod == 3 ? dflag : MO_16;
+            ot = mod == 3 ? s->dflag : MO_16;
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 2: /* lldt */
@@ -7322,7 +7322,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, tr.selector));
-            ot = mod == 3 ? dflag : MO_16;
+            ot = mod == 3 ? s->dflag : MO_16;
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 3: /* ltr */
@@ -7366,7 +7366,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_op_st_v(s, MO_16, s->T0, s->A0);
             gen_add_A0_im(s, 2);
             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
             }
             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
@@ -7421,7 +7421,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_op_st_v(s, MO_16, s->T0, s->A0);
             gen_add_A0_im(s, 2);
             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
             }
             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
@@ -7571,7 +7571,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
             }
             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
@@ -7588,7 +7588,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
-            if (dflag == MO_16) {
+            if (s->dflag == MO_16) {
                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
             }
             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
@@ -7700,7 +7700,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s)) {
             int d_ot;
             /* d_ot is the size of destination */
-            d_ot = dflag;
+            d_ot = s->dflag;
 
             modrm = x86_ldub_code(env, s);
             reg = ((modrm >> 3) & 7) | REX_R(s);
@@ -7775,7 +7775,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             TCGv t0;
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            ot = dflag != MO_16 ? MO_32 : MO_16;
+            ot = s->dflag != MO_16 ? MO_32 : MO_16;
             modrm = x86_ldub_code(env, s);
             reg = ((modrm >> 3) & 7) | REX_R(s);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
@@ -8117,7 +8117,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c3: /* MOVNTI reg, mem */
         if (!(s->cpuid_features & CPUID_SSE2))
             goto illegal_op;
-        ot = mo_64_32(dflag);
+        ot = mo_64_32(s->dflag);
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
         if (mod == 3)
@@ -8353,7 +8353,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->prefix & PREFIX_DATA) {
             ot = MO_16;
         } else {
-            ot = mo_64_32(dflag);
+            ot = mo_64_32(s->dflag);
         }
 
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix from DisasContext
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (3 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:48   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 06/39] target/i386: Simplify gen_exception arguments Jan Bobek
                   ` (35 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Reduce scope of the local variable prefixes to enforce use of prefix
from DisasContext instead.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 113 ++++++++++++++++++++--------------------
 1 file changed, 57 insertions(+), 56 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index bb13877df7..40a4844b64 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4491,7 +4491,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 {
     CPUX86State *env = cpu->env_ptr;
-    int b, prefixes;
+    int b;
     int shift;
     TCGMemOp ot;
     int modrm, reg, rm, mod, op, opreg, val;
@@ -4499,6 +4499,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     target_ulong pc_start = s->base.pc_next;
 
     {
+    int prefixes;
     TCGMemOp aflag, dflag;
 
     s->pc_start = s->pc = pc_start;
@@ -6356,7 +6357,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xa4: /* movsS */
     case 0xa5:
         ot = mo_b_d(b, s->dflag);
-        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_movs(s, ot);
@@ -6366,7 +6367,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xaa: /* stosS */
     case 0xab:
         ot = mo_b_d(b, s->dflag);
-        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_stos(s, ot);
@@ -6375,7 +6376,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xac: /* lodsS */
     case 0xad:
         ot = mo_b_d(b, s->dflag);
-        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_lods(s, ot);
@@ -6384,9 +6385,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xae: /* scasS */
     case 0xaf:
         ot = mo_b_d(b, s->dflag);
-        if (prefixes & PREFIX_REPNZ) {
+        if (s->prefix & PREFIX_REPNZ) {
             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
-        } else if (prefixes & PREFIX_REPZ) {
+        } else if (s->prefix & PREFIX_REPZ) {
             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
         } else {
             gen_scas(s, ot);
@@ -6396,9 +6397,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xa6: /* cmpsS */
     case 0xa7:
         ot = mo_b_d(b, s->dflag);
-        if (prefixes & PREFIX_REPNZ) {
+        if (s->prefix & PREFIX_REPNZ) {
             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
-        } else if (prefixes & PREFIX_REPZ) {
+        } else if (s->prefix & PREFIX_REPZ) {
             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
         } else {
             gen_cmps(s, ot);
@@ -6409,8 +6410,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base, 
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
-        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
+                     SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix) | 4);
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_ins(s, ot);
@@ -6424,8 +6425,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes) | 4);
-        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
+                     svm_is_rep(s->prefix) | 4);
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_outs(s, ot);
@@ -6444,7 +6445,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
         gen_check_io(s, ot, pc_start - s->cs_base,
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
+                     SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix));
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6463,7 +6464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
         gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes));
+                     svm_is_rep(s->prefix));
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6483,7 +6484,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
+                     SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix));
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6501,7 +6502,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes));
+                     svm_is_rep(s->prefix));
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6944,7 +6945,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_extu(ot, s->T0);
 
         /* Note that lzcnt and tzcnt are in different extensions.  */
-        if ((prefixes & PREFIX_REPZ)
+        if ((s->prefix & PREFIX_REPZ)
             && (b & 1
                 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
                 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
@@ -7037,14 +7038,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* misc */
     case 0x90: /* nop */
         /* XXX: correct lock test for all insn */
-        if (prefixes & PREFIX_LOCK) {
+        if (s->prefix & PREFIX_LOCK) {
             goto illegal_op;
         }
         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
         if (REX_B(s)) {
             goto do_xchg_reg_eax;
         }
-        if (prefixes & PREFIX_REPZ) {
+        if (s->prefix & PREFIX_REPZ) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
@@ -7607,7 +7608,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 0xee: /* rdpkru */
-            if (prefixes & PREFIX_LOCK) {
+            if (s->prefix & PREFIX_LOCK) {
                 goto illegal_op;
             }
             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
@@ -7615,7 +7616,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
             break;
         case 0xef: /* wrpkru */
-            if (prefixes & PREFIX_LOCK) {
+            if (s->prefix & PREFIX_LOCK) {
                 goto illegal_op;
             }
             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
@@ -7819,18 +7820,18 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
             reg = ((modrm >> 3) & 7) | REX_R(s);
-            if (prefixes & PREFIX_REPZ) {
+            if (s->prefix & PREFIX_REPZ) {
                 /* bndcl */
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16) {
                     goto illegal_op;
                 }
                 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
-            } else if (prefixes & PREFIX_REPNZ) {
+            } else if (s->prefix & PREFIX_REPNZ) {
                 /* bndcu */
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16) {
                     goto illegal_op;
                 }
@@ -7838,14 +7839,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 tcg_gen_not_i64(notu, cpu_bndu[reg]);
                 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
                 tcg_temp_free_i64(notu);
-            } else if (prefixes & PREFIX_DATA) {
+            } else if (s->prefix & PREFIX_DATA) {
                 /* bndmov -- from reg/mem */
                 if (reg >= 4 || s->aflag == MO_16) {
                     goto illegal_op;
                 }
                 if (mod == 3) {
                     int reg2 = (modrm & 7) | REX_B(s);
-                    if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
+                    if (reg2 >= 4 || (s->prefix & PREFIX_LOCK)) {
                         goto illegal_op;
                     }
                     if (s->flags & HF_MPX_IU_MASK) {
@@ -7874,7 +7875,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* bndldx */
                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16
                     || a.base < -1) {
                     goto illegal_op;
@@ -7909,10 +7910,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
             reg = ((modrm >> 3) & 7) | REX_R(s);
-            if (mod != 3 && (prefixes & PREFIX_REPZ)) {
+            if (mod != 3 && (s->prefix & PREFIX_REPZ)) {
                 /* bndmk */
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16) {
                     goto illegal_op;
                 }
@@ -7937,22 +7938,22 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* bnd registers are now in-use */
                 gen_set_hflag(s, HF_MPX_IU_MASK);
                 break;
-            } else if (prefixes & PREFIX_REPNZ) {
+            } else if (s->prefix & PREFIX_REPNZ) {
                 /* bndcn */
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16) {
                     goto illegal_op;
                 }
                 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
-            } else if (prefixes & PREFIX_DATA) {
+            } else if (s->prefix & PREFIX_DATA) {
                 /* bndmov -- to reg/mem */
                 if (reg >= 4 || s->aflag == MO_16) {
                     goto illegal_op;
                 }
                 if (mod == 3) {
                     int reg2 = (modrm & 7) | REX_B(s);
-                    if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
+                    if (reg2 >= 4 || (s->prefix & PREFIX_LOCK)) {
                         goto illegal_op;
                     }
                     if (s->flags & HF_MPX_IU_MASK) {
@@ -7979,7 +7980,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* bndstx */
                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
                 if (reg >= 4
-                    || (prefixes & PREFIX_LOCK)
+                    || (s->prefix & PREFIX_LOCK)
                     || s->aflag == MO_16
                     || a.base < -1) {
                     goto illegal_op;
@@ -8027,7 +8028,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 ot = MO_64;
             else
                 ot = MO_32;
-            if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
+            if ((s->prefix & PREFIX_LOCK) && (reg == 0) &&
                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
                 reg = 8;
             }
@@ -8131,7 +8132,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         switch (modrm) {
         CASE_MODRM_MEM_OP(0): /* fxsave */
             if (!(s->cpuid_features & CPUID_FXSR)
-                || (prefixes & PREFIX_LOCK)) {
+                || (s->prefix & PREFIX_LOCK)) {
                 goto illegal_op;
             }
             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
@@ -8144,7 +8145,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(1): /* fxrstor */
             if (!(s->cpuid_features & CPUID_FXSR)
-                || (prefixes & PREFIX_LOCK)) {
+                || (s->prefix & PREFIX_LOCK)) {
                 goto illegal_op;
             }
             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
@@ -8183,8 +8184,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(4): /* xsave */
             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
-                || (prefixes & (PREFIX_LOCK | PREFIX_DATA
-                                | PREFIX_REPZ | PREFIX_REPNZ))) {
+                || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
+                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
                 goto illegal_op;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8195,8 +8196,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(5): /* xrstor */
             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
-                || (prefixes & (PREFIX_LOCK | PREFIX_DATA
-                                | PREFIX_REPZ | PREFIX_REPNZ))) {
+                || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
+                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
                 goto illegal_op;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8211,10 +8212,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
-            if (prefixes & PREFIX_LOCK) {
+            if (s->prefix & PREFIX_LOCK) {
                 goto illegal_op;
             }
-            if (prefixes & PREFIX_DATA) {
+            if (s->prefix & PREFIX_DATA) {
                 /* clwb */
                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
                     goto illegal_op;
@@ -8224,7 +8225,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* xsaveopt */
                 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
                     || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
-                    || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
+                    || (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))) {
                     goto illegal_op;
                 }
                 gen_lea_modrm(env, s, modrm);
@@ -8235,10 +8236,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
-            if (prefixes & PREFIX_LOCK) {
+            if (s->prefix & PREFIX_LOCK) {
                 goto illegal_op;
             }
-            if (prefixes & PREFIX_DATA) {
+            if (s->prefix & PREFIX_DATA) {
                 /* clflushopt */
                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
                     goto illegal_op;
@@ -8258,8 +8259,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
         case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
             if (CODE64(s)
-                && (prefixes & PREFIX_REPZ)
-                && !(prefixes & PREFIX_LOCK)
+                && (s->prefix & PREFIX_REPZ)
+                && !(s->prefix & PREFIX_LOCK)
                 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
                 TCGv base, treg, src, dst;
 
@@ -8288,10 +8289,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             goto unknown_op;
 
         case 0xf8: /* sfence / pcommit */
-            if (prefixes & PREFIX_DATA) {
+            if (s->prefix & PREFIX_DATA) {
                 /* pcommit */
                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
-                    || (prefixes & PREFIX_LOCK)) {
+                    || (s->prefix & PREFIX_LOCK)) {
                     goto illegal_op;
                 }
                 break;
@@ -8299,21 +8300,21 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             /* fallthru */
         case 0xf9 ... 0xff: /* sfence */
             if (!(s->cpuid_features & CPUID_SSE)
-                || (prefixes & PREFIX_LOCK)) {
+                || (s->prefix & PREFIX_LOCK)) {
                 goto illegal_op;
             }
             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
             break;
         case 0xe8 ... 0xef: /* lfence */
             if (!(s->cpuid_features & CPUID_SSE)
-                || (prefixes & PREFIX_LOCK)) {
+                || (s->prefix & PREFIX_LOCK)) {
                 goto illegal_op;
             }
             tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
             break;
         case 0xf0 ... 0xf7: /* mfence */
             if (!(s->cpuid_features & CPUID_SSE2)
-                || (prefixes & PREFIX_LOCK)) {
+                || (s->prefix & PREFIX_LOCK)) {
                 goto illegal_op;
             }
             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
@@ -8341,8 +8342,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_eob(s);
         break;
     case 0x1b8: /* SSE4.2 popcnt */
-        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
-             PREFIX_REPZ)
+        if ((s->prefix & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
+            PREFIX_REPZ)
             goto illegal_op;
         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
             goto illegal_op;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 06/39] target/i386: Simplify gen_exception arguments
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (4 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix " Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext Jan Bobek
                   ` (34 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Richard Henderson, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

We can compute cur_eip from values present within DisasContext.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/i386/translate.c | 89 ++++++++++++++++++++---------------------
 1 file changed, 44 insertions(+), 45 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 40a4844b64..7532d65778 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -1272,10 +1272,10 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
     }
 }
 
-static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
+static void gen_exception(DisasContext *s, int trapno)
 {
     gen_update_cc_op(s);
-    gen_jmp_im(s, cur_eip);
+    gen_jmp_im(s, s->pc_start - s->cs_base);
     gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
     s->base.is_jmp = DISAS_NORETURN;
 }
@@ -1284,7 +1284,7 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
    the instruction is known, but it isn't allowed in the current cpu mode.  */
 static void gen_illegal_opcode(DisasContext *s)
 {
-    gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
+    gen_exception(s, EXCP06_ILLOP);
 }
 
 /* if d == OR_TMP0, it means memory operand (address in A0) */
@@ -3040,8 +3040,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
     [0xdf] = AESNI_OP(aeskeygenassist),
 };
 
-static void gen_sse(CPUX86State *env, DisasContext *s, int b,
-                    target_ulong pc_start)
+static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 {
     int b1, op1_offset, op2_offset, is_xmm, val;
     int modrm, mod, rm, reg;
@@ -3076,7 +3075,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
     }
     /* simple MMX/SSE operation */
     if (s->flags & HF_TS_MASK) {
-        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+        gen_exception(s, EXCP07_PREX);
         return;
     }
     if (s->flags & HF_EM_MASK) {
@@ -4515,7 +4514,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     s->vex_l = 0;
     s->vex_v = 0;
     if (sigsetjmp(s->jmpbuf, 0) != 0) {
-        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+        gen_exception(s, EXCP0D_GPF);
         return s->pc;
     }
 
@@ -5854,7 +5853,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
             /* XXX: what to do if illegal op ? */
-            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+            gen_exception(s, EXCP07_PREX);
             break;
         }
         modrm = x86_ldub_code(env, s);
@@ -6572,7 +6571,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             set_cc_op(s, CC_OP_EFLAGS);
         } else if (s->vm86) {
             if (s->iopl != 3) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
             } else {
                 gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag - 1));
                 set_cc_op(s, CC_OP_EFLAGS);
@@ -6694,7 +6693,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x9c: /* pushf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_update_cc_op(s);
             gen_helper_read_eflags(s->T0, cpu_env);
@@ -6704,7 +6703,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x9d: /* popf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             ot = gen_pop_T0(s);
             if (s->cpl == 0) {
@@ -7021,7 +7020,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             goto illegal_op;
         val = x86_ldub_code(env, s);
         if (val == 0) {
-            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
+            gen_exception(s, EXCP00_DIVZ);
         } else {
             gen_helper_aam(cpu_env, tcg_const_i32(val));
             set_cc_op(s, CC_OP_LOGICB);
@@ -7055,7 +7054,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x9b: /* fwait */
         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
             (HF_MP_MASK | HF_TS_MASK)) {
-            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+            gen_exception(s, EXCP07_PREX);
         } else {
             gen_helper_fwait(cpu_env);
         }
@@ -7066,7 +7065,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xcd: /* int N */
         val = x86_ldub_code(env, s);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
         }
@@ -7089,13 +7088,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->cpl <= s->iopl) {
                 gen_helper_cli(cpu_env);
             } else {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
             }
         } else {
             if (s->iopl == 3) {
                 gen_helper_cli(cpu_env);
             } else {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
             }
         }
         break;
@@ -7106,7 +7105,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_jmp_im(s, s->pc - s->cs_base);
             gen_eob_inhibit_irq(s, true);
         } else {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         }
         break;
     case 0x62: /* bound */
@@ -7198,7 +7197,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x130: /* wrmsr */
     case 0x132: /* rdmsr */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
@@ -7231,7 +7230,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_helper_sysenter(cpu_env);
             gen_eob(s);
@@ -7242,7 +7241,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_helper_sysexit(cpu_env, tcg_const_i32(s->dflag - 1));
             gen_eob(s);
@@ -7261,7 +7260,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x107: /* sysret */
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag - 1));
             /* condition codes are modified only in long mode */
@@ -7283,7 +7282,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xf4: /* hlt */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
@@ -7309,7 +7308,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!s->pe || s->vm86)
                 goto illegal_op;
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
@@ -7330,7 +7329,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!s->pe || s->vm86)
                 goto illegal_op;
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
@@ -7446,7 +7445,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
@@ -7463,7 +7462,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7488,7 +7487,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7501,7 +7500,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7516,7 +7515,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7530,7 +7529,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7554,7 +7553,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7564,7 +7563,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(2): /* lgdt */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
@@ -7581,7 +7580,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(3): /* lidt */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
@@ -7626,7 +7625,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
         CASE_MODRM_OP(6): /* lmsw */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
@@ -7638,7 +7637,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(7): /* invlpg */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception(s, EXCP0D_GPF);
                 break;
             }
             gen_update_cc_op(s);
@@ -7653,7 +7652,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #ifdef TARGET_X86_64
             if (CODE64(s)) {
                 if (s->cpl != 0) {
-                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                    gen_exception(s, EXCP0D_GPF);
                 } else {
                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
@@ -7690,7 +7689,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x108: /* invd */
     case 0x109: /* wbinvd */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
             /* nothing to do */
@@ -8014,7 +8013,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x120: /* mov reg, crN */
     case 0x122: /* mov crN, reg */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
@@ -8071,7 +8070,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x121: /* mov reg, drN */
     case 0x123: /* mov drN, reg */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
@@ -8105,7 +8104,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x106: /* clts */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception(s, EXCP0D_GPF);
         } else {
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
             gen_helper_clts(cpu_env);
@@ -8136,7 +8135,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
-                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+                gen_exception(s, EXCP07_PREX);
                 break;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8149,7 +8148,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
-                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+                gen_exception(s, EXCP07_PREX);
                 break;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8161,7 +8160,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->flags & HF_TS_MASK) {
-                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+                gen_exception(s, EXCP07_PREX);
                 break;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8174,7 +8173,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->flags & HF_TS_MASK) {
-                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+                gen_exception(s, EXCP07_PREX);
                 break;
             }
             gen_lea_modrm(env, s, modrm);
@@ -8377,7 +8376,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c2:
     case 0x1c4 ... 0x1c6:
     case 0x1d0 ... 0x1fe:
-        gen_sse(env, s, b, pc_start);
+        gen_sse(env, s, b);
         break;
     default:
         goto unknown_op;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (5 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 06/39] target/i386: Simplify gen_exception arguments Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:47   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const Jan Bobek
                   ` (33 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The variable pc_start is already a member of DisasContext. Remove the
superfluous local variable.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 131 ++++++++++++++++++++--------------------
 1 file changed, 65 insertions(+), 66 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 7532d65778..b1ba2fc3e5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4495,13 +4495,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     TCGMemOp ot;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
-    target_ulong pc_start = s->base.pc_next;
 
     {
     int prefixes;
     TCGMemOp aflag, dflag;
 
-    s->pc_start = s->pc = pc_start;
+    s->pc_start = s->pc = s->base.pc_next;
     s->override = -1;
 #ifdef TARGET_X86_64
     s->rex_x = 0;
@@ -6357,7 +6356,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xa5:
         ot = mo_b_d(b, s->dflag);
         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
-            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_repz_movs(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_movs(s, ot);
         }
@@ -6367,7 +6366,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xab:
         ot = mo_b_d(b, s->dflag);
         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
-            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_repz_stos(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_stos(s, ot);
         }
@@ -6376,7 +6375,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xad:
         ot = mo_b_d(b, s->dflag);
         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
-            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_repz_lods(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_lods(s, ot);
         }
@@ -6385,9 +6384,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xaf:
         ot = mo_b_d(b, s->dflag);
         if (s->prefix & PREFIX_REPNZ) {
-            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
+            gen_repz_scas(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 1);
         } else if (s->prefix & PREFIX_REPZ) {
-            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
+            gen_repz_scas(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 0);
         } else {
             gen_scas(s, ot);
         }
@@ -6397,9 +6396,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xa7:
         ot = mo_b_d(b, s->dflag);
         if (s->prefix & PREFIX_REPNZ) {
-            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
+            gen_repz_cmps(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 1);
         } else if (s->prefix & PREFIX_REPZ) {
-            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
+            gen_repz_cmps(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 0);
         } else {
             gen_cmps(s, ot);
         }
@@ -6408,10 +6407,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6d:
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base, 
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix) | 4);
         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
-            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_repz_ins(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_ins(s, ot);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6423,10 +6422,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6f:
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      svm_is_rep(s->prefix) | 4);
         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
-            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_repz_outs(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_outs(s, ot);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6443,7 +6442,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
-        gen_check_io(s, ot, pc_start - s->cs_base,
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix));
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
@@ -6462,7 +6461,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, s->dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
-        gen_check_io(s, ot, pc_start - s->cs_base,
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      svm_is_rep(s->prefix));
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
@@ -6482,7 +6481,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xed:
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(s->prefix));
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
@@ -6500,7 +6499,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xef:
         ot = mo_b_d32(b, s->dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
+        gen_check_io(s, ot, s->pc_start - s->cs_base,
                      svm_is_rep(s->prefix));
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
@@ -6541,7 +6540,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_lret:
         if (s->pe && !s->vm86) {
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag - 1),
                                       tcg_const_i32(val));
         } else {
@@ -6564,7 +6563,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         val = 0;
         goto do_lret;
     case 0xcf: /* iret */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
+        gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_IRET);
         if (!s->pe) {
             /* real mode */
             gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag - 1));
@@ -6691,7 +6690,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /************************/
         /* flags */
     case 0x9c: /* pushf */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
+        gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_PUSHF);
         if (s->vm86 && s->iopl != 3) {
             gen_exception(s, EXCP0D_GPF);
         } else {
@@ -6701,7 +6700,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         break;
     case 0x9d: /* popf */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
+        gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_POPF);
         if (s->vm86 && s->iopl != 3) {
             gen_exception(s, EXCP0D_GPF);
         } else {
@@ -7046,8 +7045,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         if (s->prefix & PREFIX_REPZ) {
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
+            gen_jmp_im(s, s->pc_start - s->cs_base);
+            gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->pc_start));
             s->base.is_jmp = DISAS_NORETURN;
         }
         break;
@@ -7060,27 +7059,27 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         break;
     case 0xcc: /* int3 */
-        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
+        gen_interrupt(s, EXCP03_INT3, s->pc_start - s->cs_base, s->pc - s->cs_base);
         break;
     case 0xcd: /* int N */
         val = x86_ldub_code(env, s);
         if (s->vm86 && s->iopl != 3) {
             gen_exception(s, EXCP0D_GPF);
         } else {
-            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
+            gen_interrupt(s, val, s->pc_start - s->cs_base, s->pc - s->cs_base);
         }
         break;
     case 0xce: /* into */
         if (CODE64(s))
             goto illegal_op;
         gen_update_cc_op(s);
-        gen_jmp_im(s, pc_start - s->cs_base);
-        gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
+        gen_jmp_im(s, s->pc_start - s->cs_base);
+        gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->pc_start));
         break;
 #ifdef WANT_ICEBP
     case 0xf1: /* icebp (undocumented, exits to external debugger) */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
-        gen_debug(s, pc_start - s->cs_base);
+        gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_ICEBP);
+        gen_debug(s, s->pc_start - s->cs_base);
         break;
 #endif
     case 0xfa: /* cli */
@@ -7200,7 +7199,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_exception(s, EXCP0D_GPF);
         } else {
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             if (b & 2) {
                 gen_helper_rdmsr(cpu_env);
             } else {
@@ -7210,7 +7209,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x131: /* rdtsc */
         gen_update_cc_op(s);
-        gen_jmp_im(s, pc_start - s->cs_base);
+        gen_jmp_im(s, s->pc_start - s->cs_base);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -7222,7 +7221,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x133: /* rdpmc */
         gen_update_cc_op(s);
-        gen_jmp_im(s, pc_start - s->cs_base);
+        gen_jmp_im(s, s->pc_start - s->cs_base);
         gen_helper_rdpmc(cpu_env);
         break;
     case 0x134: /* sysenter */
@@ -7251,8 +7250,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x105: /* syscall */
         /* XXX: is it usable in real mode ? */
         gen_update_cc_op(s);
-        gen_jmp_im(s, pc_start - s->cs_base);
-        gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
+        gen_jmp_im(s, s->pc_start - s->cs_base);
+        gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->pc_start));
         /* TF handling for the syscall insn is different. The TF bit is  checked
            after the syscall insn completes. This allows #DB to not be
            generated after one has entered CPL0 if TF is set in FMASK.  */
@@ -7277,7 +7276,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #endif
     case 0x1a2: /* cpuid */
         gen_update_cc_op(s);
-        gen_jmp_im(s, pc_start - s->cs_base);
+        gen_jmp_im(s, s->pc_start - s->cs_base);
         gen_helper_cpuid(cpu_env);
         break;
     case 0xf4: /* hlt */
@@ -7285,8 +7284,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_exception(s, EXCP0D_GPF);
         } else {
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
+            gen_jmp_im(s, s->pc_start - s->cs_base);
+            gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->pc_start));
             s->base.is_jmp = DISAS_NORETURN;
         }
         break;
@@ -7298,7 +7297,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0: /* sldt */
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_LDTR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, ldt.selector));
             ot = mod == 3 ? s->dflag : MO_16;
@@ -7310,7 +7309,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->cpl != 0) {
                 gen_exception(s, EXCP0D_GPF);
             } else {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
+                gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_LDTR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lldt(cpu_env, s->tmp2_i32);
@@ -7319,7 +7318,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 1: /* str */
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_TR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, tr.selector));
             ot = mod == 3 ? s->dflag : MO_16;
@@ -7331,7 +7330,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->cpl != 0) {
                 gen_exception(s, EXCP0D_GPF);
             } else {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
+                gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_TR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_ltr(cpu_env, s->tmp2_i32);
@@ -7359,7 +7358,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         switch (modrm) {
         CASE_MODRM_MEM_OP(0): /* sgdt */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_GDTR_READ);
             gen_lea_modrm(env, s, modrm);
             tcg_gen_ld32u_tl(s->T0,
                              cpu_env, offsetof(CPUX86State, gdt.limit));
@@ -7377,7 +7376,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
             gen_extu(s->aflag, s->A0);
             gen_add_A0_ds_seg(s);
@@ -7389,8 +7388,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
+            gen_jmp_im(s, s->pc_start - s->cs_base);
+            gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->pc_start));
             gen_eob(s);
             break;
 
@@ -7415,7 +7414,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(1): /* sidt */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_IDTR_READ);
             gen_lea_modrm(env, s, modrm);
             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
             gen_op_st_v(s, MO_16, s->T0, s->A0);
@@ -7466,9 +7465,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
-                             tcg_const_i32(s->pc - pc_start));
+                             tcg_const_i32(s->pc - s->pc_start));
             tcg_gen_exit_tb(NULL, 0);
             s->base.is_jmp = DISAS_NORETURN;
             break;
@@ -7478,7 +7477,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_vmmcall(cpu_env);
             break;
 
@@ -7491,7 +7490,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
             break;
 
@@ -7504,7 +7503,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
             break;
 
@@ -7533,7 +7532,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_clgi(cpu_env);
             break;
 
@@ -7544,7 +7543,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_skinit(cpu_env);
             break;
 
@@ -7557,7 +7556,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
             break;
 
@@ -7566,7 +7565,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_exception(s, EXCP0D_GPF);
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_GDTR_WRITE);
             gen_lea_modrm(env, s, modrm);
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
@@ -7583,7 +7582,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_exception(s, EXCP0D_GPF);
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_IDTR_WRITE);
             gen_lea_modrm(env, s, modrm);
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
@@ -7596,7 +7595,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_OP(4): /* smsw */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_READ_CR0);
             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
             if (CODE64(s)) {
                 mod = (modrm >> 6) & 3;
@@ -7628,7 +7627,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_exception(s, EXCP0D_GPF);
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_WRITE_CR0);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             gen_helper_lmsw(cpu_env, s->T0);
             gen_jmp_im(s, s->pc - s->cs_base);
@@ -7641,7 +7640,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 break;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             gen_lea_modrm(env, s, modrm);
             gen_helper_invlpg(cpu_env, s->A0);
             gen_jmp_im(s, s->pc - s->cs_base);
@@ -7670,7 +7669,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_jmp_im(s, s->pc_start - s->cs_base);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
                 gen_io_start();
             }
@@ -7691,7 +7690,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->cpl != 0) {
             gen_exception(s, EXCP0D_GPF);
         } else {
-            gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
+            gen_svm_check_intercept(s, s->pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
             /* nothing to do */
         }
         break;
@@ -8038,7 +8037,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             case 4:
             case 8:
                 gen_update_cc_op(s);
-                gen_jmp_im(s, pc_start - s->cs_base);
+                gen_jmp_im(s, s->pc_start - s->cs_base);
                 if (b & 2) {
                     if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
                         gen_io_start();
@@ -8088,14 +8087,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (b & 2) {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
+                gen_svm_check_intercept(s, s->pc_start, 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(cpu_env, s->tmp2_i32, s->T0);
                 gen_jmp_im(s, s->pc - s->cs_base);
                 gen_eob(s);
             } else {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
+                gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_READ_DR0 + reg);
                 tcg_gen_movi_i32(s->tmp2_i32, reg);
                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
                 gen_op_mov_reg_v(s, ot, rm, s->T0);
@@ -8106,7 +8105,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->cpl != 0) {
             gen_exception(s, EXCP0D_GPF);
         } else {
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
+            gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_WRITE_CR0);
             gen_helper_clts(cpu_env);
             /* abort block because static cpu state changed */
             gen_jmp_im(s, s->pc - s->cs_base);
@@ -8332,7 +8331,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_nop_modrm(env, s, modrm);
         break;
     case 0x1aa: /* rsm */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
+        gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_RSM);
         if (!(s->flags & HF_SMM_MASK))
             goto illegal_op;
         gen_update_cc_op(s);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (6 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:49   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const Jan Bobek
                   ` (32 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The variable b1 does not change value once assigned. Make this fact
explicit by marking it const.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index b1ba2fc3e5..8bf39b73c4 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -3042,7 +3042,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
 
 static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 {
-    int b1, op1_offset, op2_offset, is_xmm, val;
+    int op1_offset, op2_offset, is_xmm, val;
     int modrm, mod, rm, reg;
     SSEFunc_0_epp sse_fn_epp;
     SSEFunc_0_eppi sse_fn_eppi;
@@ -3051,14 +3051,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
     TCGMemOp ot;
 
     b &= 0xff;
-    if (s->prefix & PREFIX_DATA)
-        b1 = 1;
-    else if (s->prefix & PREFIX_REPZ)
-        b1 = 2;
-    else if (s->prefix & PREFIX_REPNZ)
-        b1 = 3;
-    else
-        b1 = 0;
+    const int b1 =
+        s->prefix & PREFIX_DATA ? 1
+        : s->prefix & PREFIX_REPZ ? 2
+        : s->prefix & PREFIX_REPNZ ? 3
+        : 0;
     sse_fn_epp = sse_op_table1[b][b1];
     if (!sse_fn_epp) {
         goto unknown_op;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (7 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:52   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 10/39] target/i386: add vector register file alignment constraints Jan Bobek
                   ` (31 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The variable is_xmm does not change value after assignment, so make
this fact explicit by marking it const.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 8bf39b73c4..c5ec309fe2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -3042,7 +3042,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
 
 static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 {
-    int op1_offset, op2_offset, is_xmm, val;
+    int op1_offset, op2_offset, val;
     int modrm, mod, rm, reg;
     SSEFunc_0_epp sse_fn_epp;
     SSEFunc_0_eppi sse_fn_eppi;
@@ -3056,20 +3056,15 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
         : s->prefix & PREFIX_REPZ ? 2
         : s->prefix & PREFIX_REPNZ ? 3
         : 0;
+    const int is_xmm =
+        (0x10 <= b && b <= 0x5f)
+        || b == 0xc6
+        || b == 0xc2
+        || !!b1;
     sse_fn_epp = sse_op_table1[b][b1];
     if (!sse_fn_epp) {
         goto unknown_op;
     }
-    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
-        is_xmm = 1;
-    } else {
-        if (b1 == 0) {
-            /* MMX case */
-            is_xmm = 0;
-        } else {
-            is_xmm = 1;
-        }
-    }
     /* simple MMX/SSE operation */
     if (s->flags & HF_TS_MASK) {
         gen_exception(s, EXCP07_PREX);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 10/39] target/i386: add vector register file alignment constraints
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (8 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0 Jan Bobek
                   ` (30 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

gvec operations require that all vectors be aligned on 16-byte
boundary; make sure the MM/XMM/YMM/ZMM register file is aligned as
neccessary.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/cpu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 8b3dc5533e..cb407b86ba 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1199,9 +1199,9 @@ typedef struct CPUX86State {
     float_status mmx_status; /* for 3DNow! float ops */
     float_status sse_status;
     uint32_t mxcsr;
-    ZMMReg xmm_regs[CPU_NB_REGS == 8 ? 8 : 32];
-    ZMMReg xmm_t0;
-    MMXReg mmx_t0;
+    ZMMReg xmm_regs[CPU_NB_REGS == 8 ? 8 : 32] QEMU_ALIGNED(16);
+    ZMMReg xmm_t0 QEMU_ALIGNED(16);
+    MMXReg mmx_t0 QEMU_ALIGNED(8);
 
     XMMReg ymmh_regs[CPU_NB_REGS];
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (9 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 10/39] target/i386: add vector register file alignment constraints Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  4:56   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng Jan Bobek
                   ` (29 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Similar in spirit to the already present gen_(ld,st)(q,o)_env_A0, it
will prove useful in later commits for smaller-sized vector loads.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index c5ec309fe2..258351fce3 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -2652,6 +2652,18 @@ static void gen_jmp(DisasContext *s, target_ulong eip)
     gen_jmp_tb(s, eip, 0);
 }
 
+static inline void gen_ldd_env_A0(DisasContext *s, int offset)
+{
+    tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
+    tcg_gen_st_i32(s->tmp2_i32, cpu_env, offset);
+}
+
+static inline void gen_std_env_A0(DisasContext *s, int offset)
+{
+    tcg_gen_ld_i32(s->tmp2_i32, cpu_env, offset);
+    tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
+}
+
 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
 {
     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (10 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0 Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  5:00   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 13/39] target/i386: disable unused function warning temporarily Jan Bobek
                   ` (28 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

This function serves as the point-of-intercept for all newly
implemented instructions. If no new implementation exists, fall back
to gen_sse.

Note: This changeset is intended for development only and shall not be
included in the final patch series.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 258351fce3..fbf10b57a2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4489,6 +4489,31 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
     }
 }
 
+static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
+{
+    enum {
+        P_66 = 1 << (0 + 8),
+        P_F3 = 1 << (1 + 8),
+        P_F2 = 1 << (2 + 8),
+        W_0  = 0 << (3 + 8),
+        W_1  = 1 << (3 + 8),
+        M_0F = 1 << (4 + 8),
+    };
+
+    switch (b | M_0F
+            | (s->prefix & PREFIX_DATA ? P_66 : 0)
+            | (s->prefix & PREFIX_REPZ ? P_F3 : 0)
+            | (s->prefix & PREFIX_REPNZ ? P_F2 : 0)
+            | (REX_W(s) > 0 ? W_1 : W_0)) {
+
+    default:
+        gen_sse(env, s, b);
+        return;
+    }
+
+    g_assert_not_reached();
+}
+
 /* convert one instruction. s->base.is_jmp is set if the translation must
    be stopped. Return the next pc value */
 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
@@ -8379,7 +8404,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c2:
     case 0x1c4 ... 0x1c6:
     case 0x1d0 ... 0x1fe:
-        gen_sse(env, s, b);
+        gen_sse_ng(env, s, b);
         break;
     default:
         goto unknown_op;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 13/39] target/i386: disable unused function warning temporarily
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (11 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations Jan Bobek
                   ` (27 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Some functions added later are generated by preprocessor macros and
end up being unused (e.g. not all operands can serve as a destination
operand). Disable unused function warnings for the new code until I
figure out how I want to solve this particular issue.

Note: This changeset is intended for development only and shall not be
included in the final patch series.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index fbf10b57a2..23550a21d3 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4489,6 +4489,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
     }
 }
 
+/* XXX TODO get rid of this eventually */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
@@ -4513,6 +4517,7 @@ static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 
     g_assert_not_reached();
 }
+#pragma GCC diagnostic pop
 
 /* convert one instruction. s->base.is_jmp is set if the translation must
    be stopped. Return the next pc value */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (12 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 13/39] target/i386: disable unused function warning temporarily Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  5:01   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid Jan Bobek
                   ` (26 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

It is helpful to introduce aliases for some general gvec operations as
it makes a couple of instruction code generators simpler (added
later).

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 23550a21d3..03b49411e5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4493,6 +4493,13 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-function"
 
+#define tcg_gen_gvec_andn(vece, dofs, aofs, bofs, oprsz, maxsz) \
+    tcg_gen_gvec_andc(vece, dofs, bofs, aofs, oprsz, maxsz)
+#define tcg_gen_gvec_cmpeq(vece, dofs, aofs, bofs, oprsz, maxsz)        \
+    tcg_gen_gvec_cmp(TCG_COND_EQ, vece, dofs, aofs, bofs, oprsz, maxsz)
+#define tcg_gen_gvec_cmpgt(vece, dofs, aofs, bofs, oprsz, maxsz)        \
+    tcg_gen_gvec_cmp(TCG_COND_GT, vece, dofs, aofs, bofs, oprsz, maxsz)
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (13 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  5:07   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure Jan Bobek
                   ` (25 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Introduce a helper function to take care of instruction CPUID checks.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 45 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 03b49411e5..508d584584 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4500,6 +4500,51 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 #define tcg_gen_gvec_cmpgt(vece, dofs, aofs, bofs, oprsz, maxsz)        \
     tcg_gen_gvec_cmp(TCG_COND_GT, vece, dofs, aofs, bofs, oprsz, maxsz)
 
+enum {
+    CK_CPUID_MMX = 1,
+    CK_CPUID_3DNOW,
+    CK_CPUID_SSE,
+    CK_CPUID_SSE2,
+    CK_CPUID_SSE3,
+    CK_CPUID_SSSE3,
+    CK_CPUID_SSE4_1,
+    CK_CPUID_SSE4_2,
+    CK_CPUID_SSE4A,
+    CK_CPUID_AVX,
+    CK_CPUID_AVX2,
+};
+
+static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
+{
+    switch (ck_cpuid_feat) {
+    case CK_CPUID_MMX:
+        return !(s->cpuid_features & CPUID_MMX)
+            || !(s->cpuid_ext2_features & CPUID_EXT2_MMX);
+    case CK_CPUID_3DNOW:
+        return !(s->cpuid_ext2_features & CPUID_EXT2_3DNOW);
+    case CK_CPUID_SSE:
+        return !(s->cpuid_features & CPUID_SSE);
+    case CK_CPUID_SSE2:
+        return !(s->cpuid_features & CPUID_SSE2);
+    case CK_CPUID_SSE3:
+        return !(s->cpuid_ext_features & CPUID_EXT_SSE3);
+    case CK_CPUID_SSSE3:
+        return !(s->cpuid_ext_features & CPUID_EXT_SSSE3);
+    case CK_CPUID_SSE4_1:
+        return !(s->cpuid_ext_features & CPUID_EXT_SSE41);
+    case CK_CPUID_SSE4_2:
+        return !(s->cpuid_ext_features & CPUID_EXT_SSE42);
+    case CK_CPUID_SSE4A:
+        return !(s->cpuid_ext3_features & CPUID_EXT3_SSE4A);
+    case CK_CPUID_AVX:
+        return !(s->cpuid_ext_features & CPUID_EXT_AVX);
+    case CK_CPUID_AVX2:
+        return !(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_AVX2);
+    default:
+        g_assert_not_reached();
+    }
+}
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (14 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  6:07   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 17/39] target/i386: introduce helpers for decoding modrm fields Jan Bobek
                   ` (24 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

insnop_t and the init, prepare and finalize functions form the basis
of instruction operand decoding. Introduce macros for defining a
generic instruction operand; use cases for operand decoding will be
introduced later with instruction translators.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 508d584584..109e4922eb 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4545,6 +4545,47 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
     }
 }
 
+/*
+ * Core instruction operand infrastructure
+ */
+#define insnop_t(opT)        insnop_ ## opT ## _t
+#define insnop_init(opT)     insnop_ ## opT ## _init
+#define insnop_prepare(opT)  insnop_ ## opT ## _prepare
+#define insnop_finalize(opT) insnop_ ## opT ## _finalize
+
+#define TYPEDEF_INSNOP_T(opT, type)             \
+    typedef type insnop_t(opT);
+#define INSNOP_INIT(opT, init_stmt)                                \
+    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
+                                int modrm, insnop_t(opT) *op)      \
+    {                                                              \
+        init_stmt;                                                 \
+    }
+#define INSNOP_PREPARE(opT, prepare_stmt)                               \
+    static void insnop_prepare(opT)(CPUX86State *env, DisasContext *s,  \
+                                    int modrm, insnop_t(opT) *op)       \
+    {                                                                   \
+        prepare_stmt;                                                   \
+    }
+#define INSNOP_FINALIZE(opT, finalize_stmt)                             \
+    static void insnop_finalize(opT)(CPUX86State *env, DisasContext *s, \
+                                     int modrm, insnop_t(opT) *op)      \
+    {                                                                   \
+        finalize_stmt;                                                  \
+    }
+#define INSNOP(opT, type, init_stmt, prepare_stmt, finalize_stmt)       \
+    TYPEDEF_INSNOP_T(opT, type)                                         \
+    INSNOP_INIT(opT, init_stmt)                                         \
+    INSNOP_PREPARE(opT, prepare_stmt)                                   \
+    INSNOP_FINALIZE(opT, finalize_stmt)
+
+#define INSNOP_INIT_FAIL        return 1
+#define INSNOP_INIT_OK(x)       return ((*(op) = (x)), 0)
+#define INSNOP_PREPARE_NOOP     /* no-op */
+#define INSNOP_PREPARE_INVALID  g_assert_not_reached()
+#define INSNOP_FINALIZE_NOOP    /* no-op */
+#define INSNOP_FINALIZE_INVALID g_assert_not_reached()
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 17/39] target/i386: introduce helpers for decoding modrm fields
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (15 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 18/39] target/i386: introduce modifier for direct-only operand decoding Jan Bobek
                   ` (23 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The old code uses bitshifts and bitwise-and all over the place for
decoding ModR/M fields. Avoid doing that by introducing proper
decoding macros.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 109e4922eb..4a2dae6238 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4500,6 +4500,21 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
 #define tcg_gen_gvec_cmpgt(vece, dofs, aofs, bofs, oprsz, maxsz)        \
     tcg_gen_gvec_cmp(TCG_COND_GT, vece, dofs, aofs, bofs, oprsz, maxsz)
 
+#define decode_modrm_mod(env, s, modrm)         \
+    (((modrm) >> 6) & 3)
+
+#define decode_modrm_reg_norexr(env, s, modrm)  \
+    (((modrm) >> 3) & 7)
+#define decode_modrm_reg_rexr(env, s, modrm)    \
+    (decode_modrm_reg_norexr(env, s, modrm)     \
+     | REX_R(s))
+
+#define decode_modrm_rm_norexb(env, s, modrm)   \
+    ((modrm) & 7)
+#define decode_modrm_rm_rexb(env, s, modrm)     \
+    (decode_modrm_rm_norexb(env, s, modrm)      \
+     | REX_B(s))
+
 enum {
     CK_CPUID_MMX = 1,
     CK_CPUID_3DNOW,
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 18/39] target/i386: introduce modifier for direct-only operand decoding
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (16 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 17/39] target/i386: introduce helpers for decoding modrm fields Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 19/39] target/i386: introduce generic operand alias Jan Bobek
                   ` (22 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Many operands can only decode successfully if the ModR/M byte has the
direct form (i.e. MOD=3). Capture this common aspect by introducing a
special operand-initialization statement wrapper.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 4a2dae6238..0bee7288e6 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4601,6 +4601,15 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
 #define INSNOP_FINALIZE_NOOP    /* no-op */
 #define INSNOP_FINALIZE_INVALID g_assert_not_reached()
 
+#define INSNOP_INIT_DIRECT_ONLY(init_stmt)              \
+    do {                                                \
+        if (decode_modrm_mod(env, s, modrm) == 3) {     \
+            init_stmt;                                  \
+        } else {                                        \
+            INSNOP_INIT_FAIL;                           \
+        }                                               \
+    } while (0)
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 19/39] target/i386: introduce generic operand alias
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (17 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 18/39] target/i386: introduce modifier for direct-only operand decoding Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand Jan Bobek
                   ` (21 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

It turns out it is useful to be able to declare operand name
aliases. Introduce a macro to capture this functionality.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 0bee7288e6..cd2467e6a5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4610,6 +4610,15 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
         }                                               \
     } while (0)
 
+/*
+ * "Alias" operand helper
+ */
+#define INSNOP_ALIAS(opT, opT2)                               \
+    INSNOP(opT, insnop_t(opT2),                               \
+           return insnop_init(opT2)(env, s, modrm, op),       \
+           insnop_prepare(opT2)(env, s, modrm, op),           \
+           insnop_finalize(opT2)(env, s, modrm, op))
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (18 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 19/39] target/i386: introduce generic operand alias Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h Jan Bobek
                   ` (20 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

This operand attempts to capture the "indirect" or "memory" operand in
a generic way. It significatly reduces the amount code that needs to
be written in order to read operands from memory to temporary storage
and write them back.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 78 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index cd2467e6a5..ebb68fef0b 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4619,6 +4619,84 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
            insnop_prepare(opT2)(env, s, modrm, op),           \
            insnop_finalize(opT2)(env, s, modrm, op))
 
+/*
+ * "Load-store" operand helper
+ */
+#define INSNOP_LDST(opT, opTr, opTm, scratch_op, ld_stmt, st_stmt)      \
+    INSNOP(                                                             \
+        opT,                                                            \
+        struct {                                                        \
+            bool is_mem;                                                \
+            insnop_t(opTr) op_reg;                                      \
+        },                                                              \
+        do {                                                            \
+            insnop_t(opTr) reg;                                         \
+            insnop_t(opTm) ptr;                                         \
+            if (!insnop_init(opTr)(env, s, modrm, &reg)) {              \
+                op->is_mem = 0;                                         \
+                op->op_reg = reg;                                       \
+                INSNOP_INIT_OK(*op);                                    \
+            } else if (!insnop_init(opTm)(env, s, modrm, &ptr)) {       \
+                op->is_mem = 1;                                         \
+                op->op_reg = (scratch_op);                              \
+                INSNOP_INIT_OK(*op);                                    \
+            }                                                           \
+            INSNOP_INIT_FAIL;                                           \
+        } while (0),                                                    \
+        do {                                                            \
+            insnop_t(opTr) reg = op->op_reg;                            \
+            if (op->is_mem) {                                           \
+                insnop_t(opTm) ptr;                                     \
+                const int ret = insnop_init(opTm)(env, s, modrm, &ptr); \
+                assert(!ret);                                           \
+                                                                        \
+                insnop_prepare(opTm)(env, s, modrm, &ptr);              \
+                ld_stmt;                                                \
+            } else {                                                    \
+                insnop_prepare(opTr)(env, s, modrm, &reg);              \
+            }                                                           \
+        } while (0),                                                    \
+        do {                                                            \
+            insnop_t(opTr) reg = op->op_reg;                            \
+            if (op->is_mem) {                                           \
+                insnop_t(opTm) ptr;                                     \
+                const int ret = insnop_init(opTm)(env, s, modrm, &ptr); \
+                assert(!ret);                                           \
+                                                                        \
+                insnop_prepare(opTm)(env, s, modrm, &ptr);              \
+                st_stmt;                                                \
+            } else {                                                    \
+                insnop_finalize(opTr)(env, s, modrm, &reg);             \
+            }                                                           \
+        } while (0))
+
+#define INSNOP_LDST_UNIFY(opT, opTr, opTrm)                             \
+    INSNOP(                                                             \
+        opT, insnop_t(opTr),                                            \
+        do {                                                            \
+            insnop_t(opTrm) rm;                                         \
+            if (!insnop_init(opTrm)(env, s, modrm, &rm)) {              \
+                INSNOP_INIT_OK(rm.op_reg);                              \
+            }                                                           \
+            INSNOP_INIT_FAIL;                                           \
+        } while (0),                                                    \
+        do {                                                            \
+            insnop_t(opTrm) rm;                                         \
+            const int ret = insnop_init(opTrm)(env, s, modrm, &rm);     \
+            assert(!ret);                                               \
+                                                                        \
+            rm.op_reg = *op;                                            \
+            insnop_prepare(opTrm)(env, s, modrm, &rm);                  \
+        } while (0),                                                    \
+        do {                                                            \
+            insnop_t(opTrm) rm;                                         \
+            const int ret = insnop_init(opTrm)(env, s, modrm, &rm);     \
+            assert(!ret);                                               \
+                                                                        \
+            rm.op_reg = *op;                                            \
+            insnop_finalize(opTrm)(env, s, modrm, &rm);                 \
+        } while (0))
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (19 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  6:00   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 22/39] target/i386: introduce code generators Jan Bobek
                   ` (19 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

This header is intended to eventually list all supported instructions
along with some useful details (e.g. mnemonics, opcode, operands etc.)
It shall be used (along with some preprocessor magic) anytime we need
to automatically generate code for every instruction.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/insn.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 target/i386/insn.h

diff --git a/target/i386/insn.h b/target/i386/insn.h
new file mode 100644
index 0000000000..4b48c0c0e1
--- /dev/null
+++ b/target/i386/insn.h
@@ -0,0 +1,87 @@
+#ifndef INSN
+#   define INSN(mnem, prefix, opcode, feat)
+#endif /* INSN */
+
+#ifndef INSN_R
+#   define INSN_R(mnem, prefix, opcode, feat, opR1)
+#endif /* INSN_R */
+
+#ifndef INSN_RR
+#   define INSN_RR(mnem, prefix, opcode, feat, opR1, opR2)
+#endif /* INSN_RR */
+
+#ifndef INSN_W
+#   define INSN_W(mnem, prefix, opcode, feat, opW1)
+#endif /* INSN_W */
+
+#ifndef INSN_WR
+#   define INSN_WR(mnem, prefix, opcode, feat, opW1, opR1)
+#endif /* INSN_WR */
+
+#ifndef INSN_WRR
+#   define INSN_WRR(mnem, prefix, opcode, feat, opW1, opR1, opR2)
+#endif /* INSN_WRR */
+
+#ifndef INSN_WRRR
+#   define INSN_WRRR(mnem, prefix, opcode, feat, opW1, opR1, opR2, opR3)
+#endif /* INSN_WRRR */
+
+#ifndef INSN_GRP
+#   define INSN_GRP(grpname, prefix, opcode)
+#endif /* INSN_GRP */
+
+#ifndef INSN_GRP_BEGIN
+#   define INSN_GRP_BEGIN(grpname)
+#endif /* INSN_GRP_BEGIN */
+
+#ifndef INSN_GRPMEMB
+#   define INSN_GRPMEMB(grpname, mnem, opcode, feat)
+#endif /* INSN_GRPMEMB */
+
+#ifndef INSN_GRPMEMB_R
+#   define INSN_GRPMEMB_R(grpname, mnem, opcode, feat, opR1)
+#endif /* INSN_GRPMEMB_R */
+
+#ifndef INSN_GRPMEMB_RR
+#   define INSN_GRPMEMB_RR(grpname, mnem, opcode, feat, opR1, opR2)
+#endif /* INSN_GRPMEMB_RR */
+
+#ifndef INSN_GRPMEMB_W
+#   define INSN_GRPMEMB_W(grpname, mnem, opcode, feat, opW1)
+#endif /* INSN_GRPMEMB_W */
+
+#ifndef INSN_GRPMEMB_WR
+#   define INSN_GRPMEMB_WR(grpname, mnem, opcode, feat, opW1, opR1)
+#endif /* INSN_GRPMEMB_WR */
+
+#ifndef INSN_GRPMEMB_WRR
+#   define INSN_GRPMEMB_WRR(grpname, mnem, opcode, feat, opW1, opR1, opR2)
+#endif /* INSN_GRPMEMB_WRR */
+
+#ifndef INSN_GRPMEMB_WRRR
+#   define INSN_GRPMEMB_WRRR(grpname, mnem, opcode, feat, opW1, opR1, opR2, opR3)
+#endif /* INSN_GRPMEMB_WRRR */
+
+#ifndef INSN_GRP_END
+#   define INSN_GRP_END(grpname)
+#endif /* INSN_GRP_END */
+
+#undef LEG
+#undef VEX
+#undef INSN
+#undef INSN_R
+#undef INSN_RR
+#undef INSN_W
+#undef INSN_WR
+#undef INSN_WRR
+#undef INSN_WRRR
+#undef INSN_GRP
+#undef INSN_GRP_BEGIN
+#undef INSN_GRPMEMB
+#undef INSN_GRPMEMB_R
+#undef INSN_GRPMEMB_RR
+#undef INSN_GRPMEMB_W
+#undef INSN_GRPMEMB_WR
+#undef INSN_GRPMEMB_WRR
+#undef INSN_GRPMEMB_WRRR
+#undef INSN_GRP_END
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 22/39] target/i386: introduce code generators
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (20 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros Jan Bobek
                   ` (18 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

In this context, "code generators" are functions that receive decoded
instruction operands and emit TCG ops implementing the correct
instruction functionality. Introduce the naming macros first, actual
generator macros will be added later.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index ebb68fef0b..30180d1c25 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4697,6 +4697,24 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
             insnop_finalize(opTrm)(env, s, modrm, &rm);                 \
         } while (0))
 
+/*
+ * Code generators
+ */
+#define gen_insn(mnem)                          \
+    gen_ ## mnem
+#define gen_insn_r(mnem, opR1)                  \
+    gen_ ## mnem ## _ ## opR1
+#define gen_insn_rr(mnem, opR1, opR2)           \
+    gen_ ## mnem ## _ ## opR1 ## opR2
+#define gen_insn_w(mnem, opW1)                  \
+    gen_ ## mnem ## _ ## opW1
+#define gen_insn_wr(mnem, opW1, opR1)           \
+    gen_ ## mnem ## _ ## opW1 ## opR1
+#define gen_insn_wrr(mnem, opW1, opR1, opR2)    \
+    gen_ ## mnem ## _ ## opW1 ## opR1 ## opR2
+#define gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3)     \
+    gen_ ## mnem ## _ ## opW1 ## opR1 ## opR2 ## opR3
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (21 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 22/39] target/i386: introduce code generators Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-13  6:30   ` Richard Henderson
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 24/39] target/i386: introduce Ib (immediate) operand Jan Bobek
                   ` (17 subsequent siblings)
  40 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Instruction "translators" are responsible for decoding and loading
instruction operands, calling the passed-in code generator, and
storing the operands back (if applicable). Once a translator returns,
the instruction has been translated to TCG ops, hence the name.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 288 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 288 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 30180d1c25..0da064d5fd 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4715,6 +4715,222 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
 #define gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3)     \
     gen_ ## mnem ## _ ## opW1 ## opR1 ## opR2 ## opR3
 
+/*
+ * Instruction translators
+ */
+#define translate_insn_r(opR1)                  \
+    translate_insn_r_ ## opR1
+#define translate_insn_rr(opR1, opR2)           \
+    translate_insn_rr_ ## opR1 ## opR2
+#define translate_insn_w(opW1)                  \
+    translate_insn_w_ ## opW1
+#define translate_insn_wr(opW1, opR1)           \
+    translate_insn_wr_ ## opW1 ## opR1
+#define translate_insn_wrr(opW1, opR1, opR2)    \
+    translate_insn_wrr_ ## opW1 ## opR1 ## opR2
+#define translate_insn_wrrr(opW1, opR1, opR2, opR3)             \
+    translate_insn_wrrr_ ## opW1 ## opR1 ## opR2 ## opR3
+#define translate_group(grpname)                \
+    translate_group_ ## grpname
+
+static void translate_insn(
+    CPUX86State *env, DisasContext *s, int ck_cpuid_feat,
+    void (*gen_insn_fp)(CPUX86State *, DisasContext *))
+{
+    if (ck_cpuid(env, s, ck_cpuid_feat)) {
+        gen_illegal_opcode(s);
+        return;
+    }
+
+    (*gen_insn_fp)(env, s);
+}
+
+#define TRANSLATE_INSN_R(opR1)                                          \
+    static void translate_insn_r(opR1)(                                 \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opR1))) \
+    {                                                                   \
+        insnop_t(opR1) arg1;                                            \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opR1)(env, s, modrm, &arg1)) {               \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        insnop_prepare(opR1)(env, s, modrm, &arg1);                     \
+        (*gen_insn_fp)(env, s, arg1);                                   \
+    }
+
+#define TRANSLATE_INSN_RR(opR1, opR2)                                   \
+    static void translate_insn_rr(opR1, opR2)(                          \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opR1), \
+                            insnop_t(opR2)))                            \
+    {                                                                   \
+        insnop_t(opR1) arg1;                                            \
+        insnop_t(opR2) arg2;                                            \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opR1)(env, s, modrm, &arg1)                  \
+            || insnop_init(opR2)(env, s, modrm, &arg2)) {               \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        insnop_prepare(opR1)(env, s, modrm, &arg1);                     \
+        insnop_prepare(opR2)(env, s, modrm, &arg2);                     \
+        (*gen_insn_fp)(env, s, arg1, arg2);                             \
+    }
+
+#define TRANSLATE_INSN_W(opW1)                                          \
+    static void translate_insn_w(opW1)(                                 \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opW1))) \
+    {                                                                   \
+        insnop_t(opW1) ret;                                             \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opW1)(env, s, modrm, &ret)) {                \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        (*gen_insn_fp)(env, s, ret);                                    \
+        insnop_finalize(opW1)(env, s, modrm, &ret);                     \
+    }
+
+#define TRANSLATE_INSN_WR(opW1, opR1)                                   \
+    static void translate_insn_wr(opW1, opR1)(                          \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opW1), \
+                            insnop_t(opR1)))                            \
+    {                                                                   \
+        insnop_t(opW1) ret;                                             \
+        insnop_t(opR1) arg1;                                            \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opW1)(env, s, modrm, &ret)                   \
+            || insnop_init(opR1)(env, s, modrm, &arg1)) {               \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        insnop_prepare(opR1)(env, s, modrm, &arg1);                     \
+        (*gen_insn_fp)(env, s, ret, arg1);                              \
+        insnop_finalize(opW1)(env, s, modrm, &ret);                     \
+    }
+
+#define TRANSLATE_INSN_WRR(opW1, opR1, opR2)                            \
+    static void translate_insn_wrr(opW1, opR1, opR2)(                   \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opW1), \
+                            insnop_t(opR1), insnop_t(opR2)))            \
+    {                                                                   \
+        insnop_t(opW1) ret;                                             \
+        insnop_t(opR1) arg1;                                            \
+        insnop_t(opR2) arg2;                                            \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opW1)(env, s, modrm, &ret)                   \
+            || insnop_init(opR1)(env, s, modrm, &arg1)                  \
+            || insnop_init(opR2)(env, s, modrm, &arg2)) {               \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        insnop_prepare(opR1)(env, s, modrm, &arg1);                     \
+        insnop_prepare(opR2)(env, s, modrm, &arg2);                     \
+        (*gen_insn_fp)(env, s, ret, arg1, arg2);                        \
+        insnop_finalize(opW1)(env, s, modrm, &ret);                     \
+    }
+
+#define TRANSLATE_INSN_WRRR(opW1, opR1, opR2, opR3)                     \
+    static void translate_insn_wrrr(opW1, opR1, opR2, opR3)(            \
+        CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
+        void (*gen_insn_fp)(CPUX86State *, DisasContext *, insnop_t(opW1), \
+                            insnop_t(opR1), insnop_t(opR2), insnop_t(opR3))) \
+    {                                                                   \
+        insnop_t(opW1) ret;                                             \
+        insnop_t(opR1) arg1;                                            \
+        insnop_t(opR2) arg2;                                            \
+        insnop_t(opR3) arg3;                                            \
+                                                                        \
+        if (ck_cpuid(env, s, ck_cpuid_feat)                             \
+            || insnop_init(opW1)(env, s, modrm, &ret)                   \
+            || insnop_init(opR1)(env, s, modrm, &arg1)                  \
+            || insnop_init(opR2)(env, s, modrm, &arg2)                  \
+            || insnop_init(opR3)(env, s, modrm, &arg3)) {               \
+            gen_illegal_opcode(s);                                      \
+            return;                                                     \
+        }                                                               \
+                                                                        \
+        insnop_prepare(opR1)(env, s, modrm, &arg1);                     \
+        insnop_prepare(opR2)(env, s, modrm, &arg2);                     \
+        insnop_prepare(opR3)(env, s, modrm, &arg3);                     \
+        (*gen_insn_fp)(env, s, ret, arg1, arg2, arg3);                  \
+        insnop_finalize(opW1)(env, s, modrm, &ret);                     \
+    }
+
+#define INSN_GRP_BEGIN(grpname)                                 \
+    static void translate_group(grpname)(                       \
+        CPUX86State *env, DisasContext *s, int modrm)           \
+    {                                                           \
+        const int reg = decode_modrm_reg_norexr(env, s, modrm); \
+                                                                \
+        switch (reg) {
+#define INSN_GRPMEMB(grpname, mnem, opcode, feat) \
+        case opcode:                              \
+            translate_insn(                       \
+                env, s, CK_CPUID_ ## feat,        \
+                gen_insn(mnem));                  \
+            return;
+#define INSN_GRPMEMB_R(grpname, mnem, opcode, feat, opR1) \
+        case opcode:                                      \
+            translate_insn_r(opR1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,         \
+                gen_insn_r(mnem, opR1));                  \
+            return;
+#define INSN_GRPMEMB_RR(grpname, mnem, opcode, feat, opR1, opR2) \
+        case opcode:                                             \
+            translate_insn_rr(opR1, opR2)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                \
+                gen_insn_rr(mnem, opR1, opR2));                  \
+            return;
+#define INSN_GRPMEMB_W(grpname, mnem, opcode, feat, opW1) \
+        case opcode:                                      \
+            translate_insn_w(opW1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,         \
+                gen_insn_w(mnem, opW1));                  \
+            return;
+#define INSN_GRPMEMB_WR(grpname, mnem, opcode, feat, opW1, opR1) \
+        case opcode:                                             \
+            translate_insn_wr(opW1, opR1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                \
+                gen_insn_wr(mnem, opW1, opR1));                  \
+            return;
+#define INSN_GRPMEMB_WRR(grpname, mnem, opcode, feat, opW1, opR1, opR2) \
+        case opcode:                                                    \
+            translate_insn_wrr(opW1, opR1, opR2)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                       \
+                gen_insn_wrr(mnem, opW1, opR1, opR2));                  \
+            return;
+#define INSN_GRPMEMB_WRRR(grpname, mnem, opcode, feat, opW1, opR1, opR2, opR3) \
+        case opcode:                                                    \
+            translate_insn_wrrr(opW1, opR1, opR2, opR3)(                \
+                env, s, modrm, CK_CPUID_ ## feat,                       \
+                gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3));           \
+            return;
+#define INSN_GRP_END(grpname)                   \
+        default:                                \
+            gen_illegal_opcode(s);              \
+            return;                             \
+        }                                       \
+                                                \
+        g_assert_not_reached();                 \
+    }
+#include "insn.h"
+
 static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
 {
     enum {
@@ -4726,15 +4942,87 @@ static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
         M_0F = 1 << (4 + 8),
     };
 
+    int modrm;
+
     switch (b | M_0F
             | (s->prefix & PREFIX_DATA ? P_66 : 0)
             | (s->prefix & PREFIX_REPZ ? P_F3 : 0)
             | (s->prefix & PREFIX_REPNZ ? P_F2 : 0)
             | (REX_W(s) > 0 ? W_1 : W_0)) {
 
+#define CASES_LEG_NP_0F_W0(opcode)              \
+    case opcode | M_0F | W_0:
+#define CASES_LEG_NP_0F_W1(opcode)              \
+    case opcode | M_0F | W_1:
+#define CASES_LEG_F3_0F_W0(opcode)              \
+    case opcode | M_0F | P_F3 | W_0:
+#define CASES_LEG_F3_0F_W1(opcode)              \
+    case opcode | M_0F | P_F3 | W_1:
+
+#define LEG(p, m, w)                            \
+    CASES_LEG_ ## p ## _ ## m ## _W ## w
+#define INSN(mnem, cases, opcode, feat)         \
+    cases(opcode)                               \
+        translate_insn(                         \
+            env, s, CK_CPUID_ ## feat,          \
+            gen_insn(mnem));                    \
+        return;
+#define INSN_R(mnem, cases, opcode, feat, opR1)      \
+    cases(opcode)                                    \
+        modrm = x86_ldub_code(env, s);               \
+        translate_insn_r(opR1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,        \
+            gen_insn_r(mnem, opR1));                 \
+        return;
+#define INSN_RR(mnem, cases, opcode, feat, opR1, opR2)       \
+    cases(opcode)                                            \
+        modrm = x86_ldub_code(env, s);                       \
+        translate_insn_rr(opR1, opR2)(                       \
+            env, s, modrm, CK_CPUID_ ## feat,                \
+            gen_insn_rr(mnem, opR1, opR2));                  \
+        return;
+#define INSN_W(mnem, cases, opcode, feat, opW1)       \
+    cases(opcode)                                     \
+        modrm = x86_ldub_code(env, s);                \
+        translate_insn_wr(opW1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,         \
+            gen_insn_wr(mnem, opW1));                 \
+        return;
+#define INSN_WR(mnem, cases, opcode, feat, opW1, opR1)      \
+    cases(opcode)                                           \
+        modrm = x86_ldub_code(env, s);                      \
+        translate_insn_wr(opW1, opR1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,               \
+            gen_insn_wr(mnem, opW1, opR1));                 \
+        return;
+#define INSN_WRR(mnem, cases, opcode, feat, opW1, opR1, opR2)       \
+    cases(opcode)                                                   \
+        modrm = x86_ldub_code(env, s);                              \
+        translate_insn_wrr(opW1, opR1, opR2)(                       \
+            env, s, modrm, CK_CPUID_ ## feat,                       \
+            gen_insn_wrr(mnem, opW1, opR1, opR2));                  \
+        return;
+#define INSN_WRRR(mnem, cases, opcode, feat, opW1, opR1, opR2, opR3)    \
+    cases(opcode)                                                   \
+        modrm = x86_ldub_code(env, s);                              \
+        translate_insn_wrrr(opW1, opR1, opR2, opR3)(                \
+            env, s, modrm, CK_CPUID_ ## feat,                       \
+            gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3));           \
+        return;
+#define INSN_GRP(grpname, cases, opcode)                \
+    cases(opcode)                                       \
+        modrm = x86_ldub_code(env, s);                  \
+        translate_group(grpname)(env, s, modrm);        \
+        return;
+#include "insn.h"
     default:
         gen_sse(env, s, b);
         return;
+
+#undef CASES_LEG_NP_0F_W0
+#undef CASES_LEG_NP_0F_W1
+#undef CASES_LEG_F3_0F_W0
+#undef CASES_LEG_F3_0F_W1
     }
 
     g_assert_not_reached();
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 24/39] target/i386: introduce Ib (immediate) operand
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (22 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 25/39] target/i386: introduce M* (memptr) operands Jan Bobek
                   ` (16 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Introduce the immediate-byte operand, which loads a byte from the
instruction stream and passes its value as the operand.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 0da064d5fd..b8e6eaebb4 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4697,6 +4697,14 @@ static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)
             insnop_finalize(opTrm)(env, s, modrm, &rm);                 \
         } while (0))
 
+/*
+ * Immediate operand
+ */
+INSNOP(Ib, int8_t,                              \
+       INSNOP_INIT_OK(*op),                     \
+       (*op = x86_ldub_code(env, s)),           \
+       INSNOP_FINALIZE_INVALID)
+
 /*
  * Code generators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 25/39] target/i386: introduce M* (memptr) operands
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (23 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 24/39] target/i386: introduce Ib (immediate) operand Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 26/39] target/i386: introduce G*, R*, E* (general register) operands Jan Bobek
                   ` (15 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The memory-pointer operand decodes the indirect form of ModR/M byte,
loads the effective address into a register and passes that register
as the operand.

Note: This operand has a known flaw: if an instruction is writing to
memory (rather than reading), this operand cannot and will not load
the effective address into the register (as it should). The current
workaround is to declare the memory operand as read (rather than
write); this flaw will be addressed in the next iteration.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index b8e6eaebb4..301dc4eddf 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4705,6 +4705,31 @@ INSNOP(Ib, int8_t,                              \
        (*op = x86_ldub_code(env, s)),           \
        INSNOP_FINALIZE_INVALID)
 
+/*
+ * Memory-pointer operand
+ */
+INSNOP(
+    M, TCGv,
+    do {
+        if (decode_modrm_mod(env, s, modrm) == 3) {
+            INSNOP_INIT_FAIL;
+        } else {
+            INSNOP_INIT_OK(s->A0);
+        }
+    } while (0),
+    do {
+        assert(*op == s->A0);
+        gen_lea_modrm(env, s, modrm);
+    } while (0),
+    INSNOP_FINALIZE_NOOP)
+
+INSNOP_ALIAS(Mb, M)
+INSNOP_ALIAS(Mw, M)
+INSNOP_ALIAS(Mq, M)
+INSNOP_ALIAS(Md, M)
+INSNOP_ALIAS(Mdq, M)
+INSNOP_ALIAS(Mqq, M)
+
 /*
  * Code generators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 26/39] target/i386: introduce G*, R*, E* (general register) operands
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (24 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 25/39] target/i386: introduce M* (memptr) operands Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 27/39] target/i386: introduce RdMw operand Jan Bobek
                   ` (14 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

These address the general-purpose register file. The corresponding
32-bit or 64-bit register is passed as the operand value.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 65 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 301dc4eddf..0e57d5f049 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4730,6 +4730,71 @@ INSNOP_ALIAS(Md, M)
 INSNOP_ALIAS(Mdq, M)
 INSNOP_ALIAS(Mqq, M)
 
+/*
+ * General registers
+ */
+#define INSNOP_R32(opT, regid_fp, init_stmt)                    \
+    INSNOP(                                                     \
+        opT, TCGv_i32, init_stmt,                               \
+        do {                                                    \
+            const int regid = regid_fp(env, s, modrm);          \
+            tcg_gen_trunc_tl_i32(*op, cpu_regs[regid]);         \
+        } while (0),                                            \
+        do {                                                    \
+            const int regid = regid_fp(env, s, modrm);          \
+            tcg_gen_extu_i32_tl(cpu_regs[regid], *op);          \
+        } while (0))
+
+#define INSNOP_R64(opT, regid_fp, init_stmt)                    \
+    INSNOP(                                                     \
+        opT, TCGv_i64, init_stmt,                               \
+        do {                                                    \
+            const int regid = regid_fp(env, s, modrm);          \
+            tcg_gen_mov_i64(*op, cpu_regs[regid]);              \
+        } while (0),                                            \
+        do {                                                    \
+            const int regid = regid_fp(env, s, modrm);          \
+            tcg_gen_mov_i64(cpu_regs[regid], *op);              \
+        } while (0))
+
+#ifdef TARGET_X86_64
+INSNOP_R32(Gd, decode_modrm_reg_rexr, INSNOP_INIT_OK(s->tmp2_i32))
+INSNOP_R64(Gq, decode_modrm_reg_rexr, INSNOP_INIT_OK(s->T1))
+
+INSNOP_R32(Rd, decode_modrm_rm_rexb,
+           INSNOP_INIT_DIRECT_ONLY(INSNOP_INIT_OK(s->tmp3_i32)))
+INSNOP_R64(Rq, decode_modrm_rm_rexb,
+           INSNOP_INIT_DIRECT_ONLY(INSNOP_INIT_OK(s->T0)))
+#else /* !TARGET_X86_64 */
+INSNOP_R32(Gd, decode_modrm_reg_rexr, INSNOP_INIT_OK(s->T1))
+INSNOP(Gq, TCGv_i64, INSNOP_INIT_FAIL,
+       INSNOP_PREPARE_INVALID, INSNOP_FINALIZE_INVALID)
+
+INSNOP_R32(Rd, decode_modrm_rm_rexb,
+           INSNOP_INIT_DIRECT_ONLY(INSNOP_INIT_OK(s->T0)))
+INSNOP(Rq, TCGv_i64, INSNOP_INIT_FAIL,
+       INSNOP_PREPARE_INVALID, INSNOP_FINALIZE_INVALID)
+#endif /* !TARGET_X86_64 */
+
+#ifdef TARGET_X86_64
+INSNOP_LDST(RdMd, Rd, Md, s->tmp3_i32,
+            tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUL),
+            tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUL))
+INSNOP_LDST(RqMq, Rq, Mq, s->T0,
+            tcg_gen_qemu_ld_i64(reg, ptr, s->mem_index, MO_LEQ),
+            tcg_gen_qemu_st_i64(reg, ptr, s->mem_index, MO_LEQ))
+#else /* !TARGET_X86_64 */
+INSNOP_LDST(RdMd, Rd, Md, s->T0,
+            tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUL),
+            tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUL))
+INSNOP_LDST(RqMq, Rq, Mq, NULL,
+            INSNOP_PREPARE_INVALID,
+            INSNOP_FINALIZE_INVALID)
+#endif /* !TARGET_X86_64 */
+
+INSNOP_LDST_UNIFY(Ed, Rd, RdMd)
+INSNOP_LDST_UNIFY(Eq, Rq, RqMq)
+
 /*
  * Code generators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 27/39] target/i386: introduce RdMw operand
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (25 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 26/39] target/i386: introduce G*, R*, E* (general register) operands Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 28/39] target/i386: introduce P*, N*, Q* (MMX) operands Jan Bobek
                   ` (13 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The PINSRW family of instructions have a peculiar second operand:
32-bit general-purpose register file is addressed, but if the operand
is indirect, only 16 bits are loaded from memory. Reflect this by the
RdMw operand.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 0e57d5f049..9896f1c99e 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4777,6 +4777,9 @@ INSNOP(Rq, TCGv_i64, INSNOP_INIT_FAIL,
 #endif /* !TARGET_X86_64 */
 
 #ifdef TARGET_X86_64
+INSNOP_LDST(RdMw, Rd, Mw, s->tmp3_i32,
+            tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUW),
+            tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUW))
 INSNOP_LDST(RdMd, Rd, Md, s->tmp3_i32,
             tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUL),
             tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUL))
@@ -4784,6 +4787,9 @@ INSNOP_LDST(RqMq, Rq, Mq, s->T0,
             tcg_gen_qemu_ld_i64(reg, ptr, s->mem_index, MO_LEQ),
             tcg_gen_qemu_st_i64(reg, ptr, s->mem_index, MO_LEQ))
 #else /* !TARGET_X86_64 */
+INSNOP_LDST(RdMw, Rd, Md, s->T0,
+            tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUW),
+            tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUW))
 INSNOP_LDST(RdMd, Rd, Md, s->T0,
             tcg_gen_qemu_ld_i32(reg, ptr, s->mem_index, MO_LEUL),
             tcg_gen_qemu_st_i32(reg, ptr, s->mem_index, MO_LEUL))
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 28/39] target/i386: introduce P*, N*, Q* (MMX) operands
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (26 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 27/39] target/i386: introduce RdMw operand Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 29/39] target/i386: introduce helper-based code generator macros Jan Bobek
                   ` (12 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

These address the MMX-technology register file; the corresponding
cpu_env offset is passed as the operand value. Notably, offset of the
entire register is pased at all times, regardless of the operand-size
suffix.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 9896f1c99e..19b92d61f6 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4801,6 +4801,43 @@ INSNOP_LDST(RqMq, Rq, Mq, NULL,
 INSNOP_LDST_UNIFY(Ed, Rd, RdMd)
 INSNOP_LDST_UNIFY(Eq, Rq, RqMq)
 
+/*
+ * MMX registers
+ */
+#define INSNOP_INIT_MM(mmid_fp)                                         \
+    do {                                                                \
+        const int mmid = mmid_fp(env, s, modrm);                        \
+        INSNOP_INIT_OK(offsetof(CPUX86State, fpregs[mmid].mmx));        \
+    } while (0)
+
+#define INSNOP_MM(opT, init_stmt)      \
+    INSNOP(opT, uint32_t,              \
+           init_stmt,                  \
+           INSNOP_PREPARE_NOOP,        \
+           INSNOP_FINALIZE_NOOP)
+
+INSNOP_MM(P, INSNOP_INIT_MM(decode_modrm_reg_norexr))
+INSNOP_ALIAS(Pd, P)
+INSNOP_ALIAS(Pq, P)
+
+INSNOP_MM(N, INSNOP_INIT_DIRECT_ONLY(INSNOP_INIT_MM(decode_modrm_rm_norexb)))
+INSNOP_ALIAS(Nd, N)
+INSNOP_ALIAS(Nq, N)
+
+INSNOP_LDST(NdMd, Nd, Md, offsetof(CPUX86State, mmx_t0),
+            (assert(ptr == s->A0),
+             gen_ldd_env_A0(s, reg + offsetof(MMXReg, MMX_L(0)))),
+            (assert(ptr == s->A0),
+             gen_std_env_A0(s, reg + offsetof(MMXReg, MMX_L(0)))))
+INSNOP_LDST(NqMq, Nq, Mq, offsetof(CPUX86State, mmx_t0),
+            (assert(ptr == s->A0),
+             gen_ldq_env_A0(s, reg + offsetof(MMXReg, MMX_Q(0)))),
+            (assert(ptr == s->A0),
+             gen_stq_env_A0(s, reg + offsetof(MMXReg, MMX_Q(0)))))
+
+INSNOP_LDST_UNIFY(Qd, Nd, NdMd)
+INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
+
 /*
  * Code generators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 29/39] target/i386: introduce helper-based code generator macros
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (27 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 28/39] target/i386: introduce P*, N*, Q* (MMX) operands Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 30/39] target/i386: introduce gvec-based " Jan Bobek
                   ` (11 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Code generators defined using these macros rely on a helper function
(as emitted by gen_helper_*).

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 19b92d61f6..d721bb5142 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4856,6 +4856,32 @@ INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
 #define gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3)     \
     gen_ ## mnem ## _ ## opW1 ## opR1 ## opR2 ## opR3
 
+#define GEN_INSN_HELPER(mnem, helper)           \
+    static void gen_insn(mnem)(                 \
+        CPUX86State *env, DisasContext *s)      \
+    {                                           \
+        gen_helper_ ## helper(cpu_env);         \
+    }
+#define GEN_INSN_WR_HELPER(mnem, helper, opW1, opR1)            \
+    static void gen_insn_wr(mnem, opW1, opR1)(                  \
+        CPUX86State *env, DisasContext *s, insnop_t(opW1) ret,  \
+        insnop_t(opR1) arg1)                                    \
+    {                                                           \
+        tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);                \
+        tcg_gen_addi_ptr(s->ptr1, cpu_env, arg1);               \
+        gen_helper_ ## helper(cpu_env, s->ptr0, s->ptr1);       \
+    }
+#define GEN_INSN_WRR_HELPER(mnem, helper, opW1, opR1, opR2)     \
+    static void gen_insn_wrr(mnem, opW1, opR1, opR2)(           \
+        CPUX86State *env, DisasContext *s, insnop_t(opW1) ret,  \
+        insnop_t(opR1) arg1, insnop_t(opR2) arg2)               \
+    {                                                           \
+        assert(ret == arg1);                                    \
+        tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);                \
+        tcg_gen_addi_ptr(s->ptr1, cpu_env, arg2);               \
+        gen_helper_ ## helper(cpu_env, s->ptr0, s->ptr1);       \
+    }
+
 /*
  * Instruction translators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 30/39] target/i386: introduce gvec-based code generator macros
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (28 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 29/39] target/i386: introduce helper-based code generator macros Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 31/39] target/i386: introduce MMX translators Jan Bobek
                   ` (10 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Code generators defined using these macros rely on a gvec operation
(i.e. tcg_gen_gvec_*).

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index d721bb5142..36f2579654 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -23,6 +23,7 @@
 #include "disas/disas.h"
 #include "exec/exec-all.h"
 #include "tcg-op.h"
+#include "tcg-op-gvec.h"
 #include "exec/cpu_ldst.h"
 #include "exec/translator.h"
 
@@ -4882,6 +4883,22 @@ INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
         gen_helper_ ## helper(cpu_env, s->ptr0, s->ptr1);       \
     }
 
+#define GEN_INSN_WR_GVEC(mnem, gvec, opW1, opR1, vece, oprsz, maxsz)    \
+    static void gen_insn_wr(mnem, opW1, opR1)(                          \
+        CPUX86State *env, DisasContext *s, insnop_t(opW1) ret,          \
+        insnop_t(opR1) arg1)                                            \
+    {                                                                   \
+        tcg_gen_gvec_ ## gvec(vece, ret, arg1, oprsz, maxsz);           \
+    }
+
+#define GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece, oprsz, maxsz) \
+    static void gen_insn_wrr(mnem, opW1, opR1, opR2)(                   \
+        CPUX86State *env, DisasContext *s, insnop_t(opW1) ret,          \
+        insnop_t(opR1) arg1, insnop_t(opR2) arg2)                       \
+    {                                                                   \
+        tcg_gen_gvec_ ## gvec(vece, ret, arg1, arg2, oprsz, maxsz);     \
+    }
+
 /*
  * Instruction translators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 31/39] target/i386: introduce MMX translators
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (29 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 30/39] target/i386: introduce gvec-based " Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 32/39] target/i386: introduce MMX code generators Jan Bobek
                   ` (9 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Use the translator macros to define instruction translators required
by MMX instructions.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 36f2579654..3475727380 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5005,6 +5005,15 @@ static void translate_insn(
         insnop_finalize(opW1)(env, s, modrm, &ret);                     \
     }
 
+TRANSLATE_INSN_WR(Pq, Ed)
+TRANSLATE_INSN_WR(Pq, Eq)
+TRANSLATE_INSN_WR(Ed, Pq)
+TRANSLATE_INSN_WR(Eq, Pq)
+TRANSLATE_INSN_WR(Pq, Qq)
+TRANSLATE_INSN_WR(Qq, Pq)
+TRANSLATE_INSN_WR(Gd, Nq)
+TRANSLATE_INSN_WR(Gq, Nq)
+
 #define TRANSLATE_INSN_WRR(opW1, opR1, opR2)                            \
     static void translate_insn_wrr(opW1, opR1, opR2)(                   \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
@@ -5029,6 +5038,13 @@ static void translate_insn(
         insnop_finalize(opW1)(env, s, modrm, &ret);                     \
     }
 
+TRANSLATE_INSN_WRR(Pq, Pq, Qd)
+TRANSLATE_INSN_WRR(Pq, Pq, Qq)
+TRANSLATE_INSN_WRR(Pq, Qq, Ib)
+TRANSLATE_INSN_WRR(Gd, Nq, Ib)
+TRANSLATE_INSN_WRR(Gq, Nq, Ib)
+TRANSLATE_INSN_WRR(Nq, Nq, Ib)
+
 #define TRANSLATE_INSN_WRRR(opW1, opR1, opR2, opR3)                     \
     static void translate_insn_wrrr(opW1, opR1, opR2, opR3)(            \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 32/39] target/i386: introduce MMX code generators
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (30 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 31/39] target/i386: introduce MMX translators Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 33/39] target/i386: introduce MMX instructions to insn.h Jan Bobek
                   ` (8 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Define code generators required for MMX instructions.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 114 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 3475727380..aa6fb8b013 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4890,6 +4890,9 @@ INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
     {                                                                   \
         tcg_gen_gvec_ ## gvec(vece, ret, arg1, oprsz, maxsz);           \
     }
+#define GEN_INSN_WR_GVEC_MM(mnem, gvec, opW1, opR1, vece)       \
+    GEN_INSN_WR_GVEC(mnem, gvec, opW1, opR1, vece,              \
+                     sizeof(MMXReg), sizeof(MMXReg))
 
 #define GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece, oprsz, maxsz) \
     static void gen_insn_wrr(mnem, opW1, opR1, opR2)(                   \
@@ -4898,6 +4901,117 @@ INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
     {                                                                   \
         tcg_gen_gvec_ ## gvec(vece, ret, arg1, arg2, oprsz, maxsz);     \
     }
+#define GEN_INSN_WRR_GVEC_MM(mnem, gvec, opW1, opR1, opR2, vece)    \
+    GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece,           \
+                      sizeof(MMXReg), sizeof(MMXReg))
+
+static void gen_insn_wr(movq, Eq, Pq)(CPUX86State *env, DisasContext *s,
+                                      insnop_t(Eq) ret, insnop_t(Pq) arg1)
+{
+    const size_t ofs = offsetof(MMXReg, MMX_Q(0));
+    tcg_gen_ld_i64(ret, cpu_env, arg1 + ofs);
+}
+
+static void gen_insn_wr(movd, Ed, Pq)(CPUX86State *env, DisasContext *s,
+                                      insnop_t(Ed) ret, insnop_t(Pq) arg1)
+{
+    const size_t ofs = offsetof(MMXReg, MMX_L(0));
+    tcg_gen_ld_i32(ret, cpu_env, arg1 + ofs);
+}
+
+static void gen_insn_wr(movq, Pq, Eq)(CPUX86State *env, DisasContext *s,
+                                      insnop_t(Pq) ret, insnop_t(Eq) arg1)
+{
+    const size_t ofs = offsetof(MMXReg, MMX_Q(0));
+    tcg_gen_st_i64(arg1, cpu_env, ret + ofs);
+}
+
+static void gen_insn_wr(movd, Pq, Ed)(CPUX86State *env, DisasContext *s,
+                                      insnop_t(Pq) ret, insnop_t(Ed) arg1)
+{
+    const insnop_t(Eq) r64 = s->tmp1_i64;
+    tcg_gen_extu_i32_i64(r64, arg1);
+    gen_insn_wr(movq, Pq, Eq)(env, s, ret, r64);
+}
+
+GEN_INSN_WR_GVEC_MM(movq, mov, Pq, Qq, MO_64)
+GEN_INSN_WR_GVEC_MM(movq, mov, Qq, Pq, MO_64)
+
+GEN_INSN_WRR_GVEC_MM(paddb, add, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(paddw, add, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(paddd, add, Pq, Pq, Qq, MO_32)
+GEN_INSN_WRR_GVEC_MM(paddsb, ssadd, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(paddsw, ssadd, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(paddusb, usadd, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(paddusw, usadd, Pq, Pq, Qq, MO_16)
+
+GEN_INSN_WRR_GVEC_MM(psubb, sub, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(psubw, sub, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(psubd, sub, Pq, Pq, Qq, MO_32)
+GEN_INSN_WRR_GVEC_MM(psubsb, sssub, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(psubsw, sssub, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(psubusb, ussub, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(psubusw, ussub, Pq, Pq, Qq, MO_16)
+
+GEN_INSN_WRR_HELPER(pmulhw, pmulhw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(pmullw, pmullw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(pmaddwd, pmaddwd_mmx, Pq, Pq, Qq)
+
+GEN_INSN_WRR_GVEC_MM(pcmpeqb, cmpeq, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(pcmpeqw, cmpeq, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(pcmpeqd, cmpeq, Pq, Pq, Qq, MO_32)
+GEN_INSN_WRR_GVEC_MM(pcmpgtb, cmpgt, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(pcmpgtw, cmpgt, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_GVEC_MM(pcmpgtd, cmpgt, Pq, Pq, Qq, MO_32)
+
+GEN_INSN_WRR_GVEC_MM(pand, and, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_MM(pandn, andn, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_MM(por, or, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_MM(pxor, xor, Pq, Pq, Qq, MO_64)
+
+GEN_INSN_WRR_HELPER(psllw, psllw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(pslld, pslld_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psllq, psllq_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psrlw, psrlw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psrld, psrld_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psrlq, psrlq_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psraw, psraw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psrad, psrad_mmx, Pq, Pq, Qq)
+
+#define GEN_PSHIFT_IMM_MM(mnem, opW1, opR1)                             \
+    static void gen_insn_wrr(mnem, opW1, opR1, Ib)(                     \
+        CPUX86State *env, DisasContext *s,                              \
+        insnop_t(opW1) ret, insnop_t(opR1) arg1, insnop_t(Ib) arg2)     \
+    {                                                                   \
+        const uint64_t arg2_ui64 = (uint8_t)arg2;                       \
+        const insnop_t(Eq) arg2_r64 = s->tmp1_i64;                      \
+        const insnop_t(Qq) arg2_mm = offsetof(CPUX86State, mmx_t0.MMX_Q(0)); \
+                                                                        \
+        tcg_gen_movi_i64(arg2_r64, arg2_ui64);                          \
+        gen_insn_wr(movq, Pq, Eq)(env, s, arg2_mm, arg2_r64);           \
+        gen_insn_wrr(mnem, Pq, Pq, Qq)(env, s, ret, arg1, arg2_mm);     \
+    }
+
+GEN_PSHIFT_IMM_MM(psllw, Nq, Nq)
+GEN_PSHIFT_IMM_MM(pslld, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psllq, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psrlw, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psrld, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psrlq, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psraw, Nq, Nq)
+GEN_PSHIFT_IMM_MM(psrad, Nq, Nq)
+
+GEN_INSN_WRR_HELPER(packsswb, packsswb_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(packssdw, packssdw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(packuswb, packuswb_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(punpcklbw, punpcklbw_mmx, Pq, Pq, Qd)
+GEN_INSN_WRR_HELPER(punpcklwd, punpcklwd_mmx, Pq, Pq, Qd)
+GEN_INSN_WRR_HELPER(punpckldq, punpckldq_mmx, Pq, Pq, Qd)
+GEN_INSN_WRR_HELPER(punpckhbw, punpckhbw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(punpckhwd, punpckhwd_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(punpckhdq, punpckhdq_mmx, Pq, Pq, Qq)
+
+GEN_INSN_HELPER(emms, emms)
 
 /*
  * Instruction translators
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 33/39] target/i386: introduce MMX instructions to insn.h
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (31 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 32/39] target/i386: introduce MMX code generators Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 34/39] target/i386: introduce V*, U*, W* (SSE/AVX) operands Jan Bobek
                   ` (7 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Add all MMX instruction entries to insn.h.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/insn.h | 131 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/target/i386/insn.h b/target/i386/insn.h
index 4b48c0c0e1..6506ff3137 100644
--- a/target/i386/insn.h
+++ b/target/i386/insn.h
@@ -66,6 +66,137 @@
 #   define INSN_GRP_END(grpname)
 #endif /* INSN_GRP_END */
 
+/* NP 0F 6E /r: MOVD mm,r/m32 */
+INSN_WR(movd, LEG(NP, 0F, 0), 0x6e, MMX, Pq, Ed)
+/* NP 0F 7E /r: MOVD r/m32,mm */
+INSN_WR(movd, LEG(NP, 0F, 0), 0x7e, MMX, Ed, Pq)
+/* NP REX.W + 0F 6E /r: MOVQ mm,r/m64 */
+INSN_WR(movq, LEG(NP, 0F, 1), 0x6e, MMX, Pq, Eq)
+/* NP REX.W + 0F 7E /r: MOVQ r/m64,mm */
+INSN_WR(movq, LEG(NP, 0F, 1), 0x7e, MMX, Eq, Pq)
+/* NP 0F 6F /r: MOVQ mm, mm/m64 */
+INSN_WR(movq, LEG(NP, 0F, 0), 0x6f, MMX, Pq, Qq)
+/* NP 0F 7F /r: MOVQ mm/m64, mm */
+INSN_WR(movq, LEG(NP, 0F, 0), 0x7f, MMX, Qq, Pq)
+/* NP 0F FC /r: PADDB mm, mm/m64 */
+INSN_WRR(paddb, LEG(NP, 0F, 0), 0xfc, MMX, Pq, Pq, Qq)
+/* NP 0F FD /r: PADDW mm, mm/m64 */
+INSN_WRR(paddw, LEG(NP, 0F, 0), 0xfd, MMX, Pq, Pq, Qq)
+/* NP 0F FE /r: PADDD mm, mm/m64 */
+INSN_WRR(paddd, LEG(NP, 0F, 0), 0xfe, MMX, Pq, Pq, Qq)
+/* NP 0F EC /r: PADDSB mm, mm/m64 */
+INSN_WRR(paddsb, LEG(NP, 0F, 0), 0xec, MMX, Pq, Pq, Qq)
+/* NP 0F ED /r: PADDSW mm, mm/m64 */
+INSN_WRR(paddsw, LEG(NP, 0F, 0), 0xed, MMX, Pq, Pq, Qq)
+/* NP 0F DC /r: PADDUSB mm,mm/m64 */
+INSN_WRR(paddusb, LEG(NP, 0F, 0), 0xdc, MMX, Pq, Pq, Qq)
+/* NP 0F DD /r: PADDUSW mm,mm/m64 */
+INSN_WRR(paddusw, LEG(NP, 0F, 0), 0xdd, MMX, Pq, Pq, Qq)
+/* NP 0F F8 /r: PSUBB mm, mm/m64 */
+INSN_WRR(psubb, LEG(NP, 0F, 0), 0xf8, MMX, Pq, Pq, Qq)
+/* NP 0F F9 /r: PSUBW mm, mm/m64 */
+INSN_WRR(psubw, LEG(NP, 0F, 0), 0xf9, MMX, Pq, Pq, Qq)
+/* NP 0F FA /r: PSUBD mm, mm/m64 */
+INSN_WRR(psubd, LEG(NP, 0F, 0), 0xfa, MMX, Pq, Pq, Qq)
+/* NP 0F E8 /r: PSUBSB mm, mm/m64 */
+INSN_WRR(psubsb, LEG(NP, 0F, 0), 0xe8, MMX, Pq, Pq, Qq)
+/* NP 0F E9 /r: PSUBSW mm, mm/m64 */
+INSN_WRR(psubsw, LEG(NP, 0F, 0), 0xe9, MMX, Pq, Pq, Qq)
+/* NP 0F D8 /r: PSUBUSB mm, mm/m64 */
+INSN_WRR(psubusb, LEG(NP, 0F, 0), 0xd8, MMX, Pq, Pq, Qq)
+/* NP 0F D9 /r: PSUBUSW mm, mm/m64 */
+INSN_WRR(psubusw, LEG(NP, 0F, 0), 0xd9, MMX, Pq, Pq, Qq)
+/* NP 0F D5 /r: PMULLW mm, mm/m64 */
+INSN_WRR(pmullw, LEG(NP, 0F, 0), 0xd5, MMX, Pq, Pq, Qq)
+/* NP 0F E5 /r: PMULHW mm, mm/m64 */
+INSN_WRR(pmulhw, LEG(NP, 0F, 0), 0xe5, MMX, Pq, Pq, Qq)
+/* NP 0F F5 /r: PMADDWD mm, mm/m64 */
+INSN_WRR(pmaddwd, LEG(NP, 0F, 0), 0xf5, MMX, Pq, Pq, Qq)
+/* NP 0F 74 /r: PCMPEQB mm,mm/m64 */
+INSN_WRR(pcmpeqb, LEG(NP, 0F, 0), 0x74, MMX, Pq, Pq, Qq)
+/* NP 0F 75 /r: PCMPEQW mm,mm/m64 */
+INSN_WRR(pcmpeqw, LEG(NP, 0F, 0), 0x75, MMX, Pq, Pq, Qq)
+/* NP 0F 76 /r: PCMPEQD mm,mm/m64 */
+INSN_WRR(pcmpeqd, LEG(NP, 0F, 0), 0x76, MMX, Pq, Pq, Qq)
+/* NP 0F 64 /r: PCMPGTB mm,mm/m64 */
+INSN_WRR(pcmpgtb, LEG(NP, 0F, 0), 0x64, MMX, Pq, Pq, Qq)
+/* NP 0F 65 /r: PCMPGTW mm,mm/m64 */
+INSN_WRR(pcmpgtw, LEG(NP, 0F, 0), 0x65, MMX, Pq, Pq, Qq)
+/* NP 0F 66 /r: PCMPGTD mm,mm/m64 */
+INSN_WRR(pcmpgtd, LEG(NP, 0F, 0), 0x66, MMX, Pq, Pq, Qq)
+/* NP 0F DB /r: PAND mm, mm/m64 */
+INSN_WRR(pand, LEG(NP, 0F, 0), 0xdb, MMX, Pq, Pq, Qq)
+/* NP 0F DF /r: PANDN mm, mm/m64 */
+INSN_WRR(pandn, LEG(NP, 0F, 0), 0xdf, MMX, Pq, Pq, Qq)
+/* NP 0F EB /r: POR mm, mm/m64 */
+INSN_WRR(por, LEG(NP, 0F, 0), 0xeb, MMX, Pq, Pq, Qq)
+/* NP 0F EF /r: PXOR mm, mm/m64 */
+INSN_WRR(pxor, LEG(NP, 0F, 0), 0xef, MMX, Pq, Pq, Qq)
+/* NP 0F F1 /r: PSLLW mm, mm/m64 */
+INSN_WRR(psllw, LEG(NP, 0F, 0), 0xf1, MMX, Pq, Pq, Qq)
+/* NP 0F F2 /r: PSLLD mm, mm/m64 */
+INSN_WRR(pslld, LEG(NP, 0F, 0), 0xf2, MMX, Pq, Pq, Qq)
+/* NP 0F F3 /r: PSLLQ mm, mm/m64 */
+INSN_WRR(psllq, LEG(NP, 0F, 0), 0xf3, MMX, Pq, Pq, Qq)
+/* NP 0F D1 /r: PSRLW mm, mm/m64 */
+INSN_WRR(psrlw, LEG(NP, 0F, 0), 0xd1, MMX, Pq, Pq, Qq)
+/* NP 0F D2 /r: PSRLD mm, mm/m64 */
+INSN_WRR(psrld, LEG(NP, 0F, 0), 0xd2, MMX, Pq, Pq, Qq)
+/* NP 0F D3 /r: PSRLQ mm, mm/m64 */
+INSN_WRR(psrlq, LEG(NP, 0F, 0), 0xd3, MMX, Pq, Pq, Qq)
+/* NP 0F E1 /r: PSRAW mm,mm/m64 */
+INSN_WRR(psraw, LEG(NP, 0F, 0), 0xe1, MMX, Pq, Pq, Qq)
+/* NP 0F E2 /r: PSRAD mm,mm/m64 */
+INSN_WRR(psrad, LEG(NP, 0F, 0), 0xe2, MMX, Pq, Pq, Qq)
+/* NP 0F 63 /r: PACKSSWB mm1, mm2/m64 */
+INSN_WRR(packsswb, LEG(NP, 0F, 0), 0x63, MMX, Pq, Pq, Qq)
+/* NP 0F 6B /r: PACKSSDW mm1, mm2/m64 */
+INSN_WRR(packssdw, LEG(NP, 0F, 0), 0x6b, MMX, Pq, Pq, Qq)
+/* NP 0F 67 /r: PACKUSWB mm, mm/m64 */
+INSN_WRR(packuswb, LEG(NP, 0F, 0), 0x67, MMX, Pq, Pq, Qq)
+/* NP 0F 68 /r: PUNPCKHBW mm, mm/m64 */
+INSN_WRR(punpckhbw, LEG(NP, 0F, 0), 0x68, MMX, Pq, Pq, Qq)
+/* NP 0F 69 /r: PUNPCKHWD mm, mm/m64 */
+INSN_WRR(punpckhwd, LEG(NP, 0F, 0), 0x69, MMX, Pq, Pq, Qq)
+/* NP 0F 6A /r: PUNPCKHDQ mm, mm/m64 */
+INSN_WRR(punpckhdq, LEG(NP, 0F, 0), 0x6a, MMX, Pq, Pq, Qq)
+/* NP 0F 60 /r: PUNPCKLBW mm, mm/m32 */
+INSN_WRR(punpcklbw, LEG(NP, 0F, 0), 0x60, MMX, Pq, Pq, Qd)
+/* NP 0F 61 /r: PUNPCKLWD mm, mm/m32 */
+INSN_WRR(punpcklwd, LEG(NP, 0F, 0), 0x61, MMX, Pq, Pq, Qd)
+/* NP 0F 62 /r: PUNPCKLDQ mm, mm/m32 */
+INSN_WRR(punpckldq, LEG(NP, 0F, 0), 0x62, MMX, Pq, Pq, Qd)
+/* NP 0F 77: EMMS */
+INSN(emms, LEG(NP, 0F, 0), 0x77, MMX)
+
+INSN_GRP(grp12_LEG_NP, LEG(NP, 0F, 0), 0x71)
+INSN_GRP_BEGIN(grp12_LEG_NP)
+    /* NP 0F 71 /6 ib: PSLLW mm1, imm8 */
+    INSN_GRPMEMB_WRR(grp12_LEG_NP, psllw, 6, MMX, Nq, Nq, Ib)
+    /* NP 0F 71 /2 ib: PSRLW mm, imm8 */
+    INSN_GRPMEMB_WRR(grp12_LEG_NP, psrlw, 2, MMX, Nq, Nq, Ib)
+    /* NP 0F 71 /4 ib: PSRAW mm,imm8 */
+    INSN_GRPMEMB_WRR(grp12_LEG_NP, psraw, 4, MMX, Nq, Nq, Ib)
+INSN_GRP_END(grp12_LEG_NP)
+
+INSN_GRP(grp13_LEG_NP, LEG(NP, 0F, 0), 0x72)
+INSN_GRP_BEGIN(grp13_LEG_NP)
+    /* NP 0F 72 /6 ib: PSLLD mm, imm8 */
+    INSN_GRPMEMB_WRR(grp13_LEG_NP, pslld, 6, MMX, Nq, Nq, Ib)
+    /* NP 0F 72 /2 ib: PSRLD mm, imm8 */
+    INSN_GRPMEMB_WRR(grp13_LEG_NP, psrld, 2, MMX, Nq, Nq, Ib)
+    /* NP 0F 72 /4 ib: PSRAD mm,imm8 */
+    INSN_GRPMEMB_WRR(grp13_LEG_NP, psrad, 4, MMX, Nq, Nq, Ib)
+INSN_GRP_END(grp13_LEG_NP)
+
+INSN_GRP(grp14_LEG_NP, LEG(NP, 0F, 0), 0x73)
+INSN_GRP_BEGIN(grp14_LEG_NP)
+    /* NP 0F 73 /6 ib: PSLLQ mm, imm8 */
+    INSN_GRPMEMB_WRR(grp14_LEG_NP, psllq, 6, MMX, Nq, Nq, Ib)
+    /* NP 0F 73 /2 ib: PSRLQ mm, imm8 */
+    INSN_GRPMEMB_WRR(grp14_LEG_NP, psrlq, 2, MMX, Nq, Nq, Ib)
+INSN_GRP_END(grp14_LEG_NP)
+
 #undef LEG
 #undef VEX
 #undef INSN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 34/39] target/i386: introduce V*, U*, W* (SSE/AVX) operands
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (32 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 33/39] target/i386: introduce MMX instructions to insn.h Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 35/39] target/i386: introduce UdqMq operand Jan Bobek
                   ` (6 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

These address the SSE/AVX-technology register file. Offset of the
entire corresponding register is passed as the operand value,
regardless of operand-size suffix.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 45 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index aa6fb8b013..97614e5941 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4839,6 +4839,51 @@ INSNOP_LDST(NqMq, Nq, Mq, offsetof(CPUX86State, mmx_t0),
 INSNOP_LDST_UNIFY(Qd, Nd, NdMd)
 INSNOP_LDST_UNIFY(Qq, Nq, NqMq)
 
+/*
+ * SSE/AVX registers
+ */
+#define INSNOP_INIT_XMM(xmmid_fp)                               \
+    do {                                                        \
+        const int xmmid = xmmid_fp(env, s, modrm);              \
+        INSNOP_INIT_OK(offsetof(CPUX86State, xmm_regs[xmmid])); \
+    } while (0)
+
+#define INSNOP_XMM(opT, init_stmt)     \
+    INSNOP(opT, uint32_t,              \
+           init_stmt,                  \
+           INSNOP_PREPARE_NOOP,        \
+           INSNOP_FINALIZE_NOOP)
+
+INSNOP_XMM(V, INSNOP_INIT_XMM(decode_modrm_reg_rexr))
+INSNOP_ALIAS(Vd, V)
+INSNOP_ALIAS(Vq, V)
+INSNOP_ALIAS(Vdq, V)
+INSNOP_ALIAS(Vqq, V)
+
+INSNOP_XMM(U, INSNOP_INIT_DIRECT_ONLY(INSNOP_INIT_XMM(decode_modrm_rm_rexb)))
+INSNOP_ALIAS(Ud, U)
+INSNOP_ALIAS(Uq, U)
+INSNOP_ALIAS(Udq, U)
+INSNOP_ALIAS(Uqq, U)
+
+INSNOP_LDST(UdMd, Ud, Md, offsetof(CPUX86State, xmm_t0),
+            (assert(ptr == s->A0),
+             gen_ldd_env_A0(s, reg + offsetof(ZMMReg, ZMM_L(0)))),
+            (assert(ptr == s->A0),
+             gen_std_env_A0(s, reg + offsetof(ZMMReg, ZMM_L(0)))))
+INSNOP_LDST(UqMq, Uq, Mq, offsetof(CPUX86State, xmm_t0),
+            (assert(ptr == s->A0),
+             gen_ldq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))),
+            (assert(ptr == s->A0),
+             gen_stq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))))
+INSNOP_LDST(UdqMdq, Udq, Mdq, offsetof(CPUX86State, xmm_t0),
+            (assert(ptr == s->A0), gen_ldo_env_A0(s, reg)),
+            (assert(ptr == s->A0), gen_sto_env_A0(s, reg)))
+
+INSNOP_LDST_UNIFY(Wd, Ud, UdMd)
+INSNOP_LDST_UNIFY(Wq, Uq, UqMq)
+INSNOP_LDST_UNIFY(Wdq, Udq, UdqMdq)
+
 /*
  * Code generators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 35/39] target/i386: introduce UdqMq operand
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (33 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 34/39] target/i386: introduce V*, U*, W* (SSE/AVX) operands Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 36/39] target/i386: introduce SSE translators Jan Bobek
                   ` (5 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The MOVHLPS instruction has a special operand: it reads the high
quadword of the source operand (hence it requires the full
double-quadword width), but if the operand is indirect, only 64-bits
are read from memory. Introduce UdqMq operand to address this case.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 97614e5941..5802b324f0 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4876,6 +4876,11 @@ INSNOP_LDST(UqMq, Uq, Mq, offsetof(CPUX86State, xmm_t0),
              gen_ldq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))),
             (assert(ptr == s->A0),
              gen_stq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))))
+INSNOP_LDST(UdqMq, Udq, Mq, offsetof(CPUX86State, xmm_t0),
+            (assert(ptr == s->A0),
+             gen_ldq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))),
+            (assert(ptr == s->A0),
+             gen_stq_env_A0(s, reg + offsetof(ZMMReg, ZMM_Q(0)))))
 INSNOP_LDST(UdqMdq, Udq, Mdq, offsetof(CPUX86State, xmm_t0),
             (assert(ptr == s->A0), gen_ldo_env_A0(s, reg)),
             (assert(ptr == s->A0), gen_sto_env_A0(s, reg)))
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 36/39] target/i386: introduce SSE translators
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (34 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 35/39] target/i386: introduce UdqMq operand Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 37/39] target/i386: introduce SSE code generators Jan Bobek
                   ` (4 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Use the translator macros to define translators required by SSE
instructions.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 5802b324f0..12d2ac2eb5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5110,6 +5110,9 @@ static void translate_insn(
         (*gen_insn_fp)(env, s, arg1);                                   \
     }
 
+TRANSLATE_INSN_R(Mb)
+TRANSLATE_INSN_R(Md)
+
 #define TRANSLATE_INSN_RR(opR1, opR2)                                   \
     static void translate_insn_rr(opR1, opR2)(                          \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
@@ -5131,6 +5134,13 @@ static void translate_insn(
         (*gen_insn_fp)(env, s, arg1, arg2);                             \
     }
 
+TRANSLATE_INSN_RR(Pq, Nq)
+TRANSLATE_INSN_RR(Mq, Pq)
+TRANSLATE_INSN_RR(Vd, Wd)
+TRANSLATE_INSN_RR(Mq, Vq)
+TRANSLATE_INSN_RR(Mq, Vdq)
+TRANSLATE_INSN_RR(Mdq, Vdq)
+
 #define TRANSLATE_INSN_W(opW1)                                          \
     static void translate_insn_w(opW1)(                                 \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
@@ -5178,6 +5188,20 @@ TRANSLATE_INSN_WR(Qq, Pq)
 TRANSLATE_INSN_WR(Gd, Nq)
 TRANSLATE_INSN_WR(Gq, Nq)
 
+TRANSLATE_INSN_WR(Vd, Wd)
+TRANSLATE_INSN_WR(Vdq, Wdq)
+TRANSLATE_INSN_WR(Vq, UdqMq)
+TRANSLATE_INSN_WR(Wd, Vd)
+TRANSLATE_INSN_WR(Wdq, Vdq)
+TRANSLATE_INSN_WR(Gd, Udq)
+TRANSLATE_INSN_WR(Gq, Udq)
+TRANSLATE_INSN_WR(Vdq, Qq)
+TRANSLATE_INSN_WR(Vd, Ed)
+TRANSLATE_INSN_WR(Vd, Eq)
+TRANSLATE_INSN_WR(Pq, Wq)
+TRANSLATE_INSN_WR(Gd, Wd)
+TRANSLATE_INSN_WR(Gq, Wd)
+
 #define TRANSLATE_INSN_WRR(opW1, opR1, opR2)                            \
     static void translate_insn_wrr(opW1, opR1, opR2)(                   \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
@@ -5209,6 +5233,11 @@ TRANSLATE_INSN_WRR(Gd, Nq, Ib)
 TRANSLATE_INSN_WRR(Gq, Nq, Ib)
 TRANSLATE_INSN_WRR(Nq, Nq, Ib)
 
+TRANSLATE_INSN_WRR(Vd, Vd, Wd)
+TRANSLATE_INSN_WRR(Vdq, Vdq, Wdq)
+TRANSLATE_INSN_WRR(Vdq, Vq, UqMq)
+TRANSLATE_INSN_WRR(Vdq, Vdq, UdMd)
+
 #define TRANSLATE_INSN_WRRR(opW1, opR1, opR2, opR3)                     \
     static void translate_insn_wrrr(opW1, opR1, opR2, opR3)(            \
         CPUX86State *env, DisasContext *s, int modrm, int ck_cpuid_feat, \
@@ -5236,6 +5265,10 @@ TRANSLATE_INSN_WRR(Nq, Nq, Ib)
         insnop_finalize(opW1)(env, s, modrm, &ret);                     \
     }
 
+TRANSLATE_INSN_WRRR(Vd, Vd, Wd, Ib)
+TRANSLATE_INSN_WRRR(Vdq, Vdq, Wdq, Ib)
+TRANSLATE_INSN_WRRR(Pq, Pq, RdMw, Ib)
+
 #define INSN_GRP_BEGIN(grpname)                                 \
     static void translate_group(grpname)(                       \
         CPUX86State *env, DisasContext *s, int modrm)           \
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 37/39] target/i386: introduce SSE code generators
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (35 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 36/39] target/i386: introduce SSE translators Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 38/39] target/i386: introduce SSE instructions to insn.h Jan Bobek
                   ` (3 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Introduce code generators required by SSE instructions.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/translate.c | 440 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 440 insertions(+)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 12d2ac2eb5..681fa1aee2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4943,6 +4943,9 @@ INSNOP_LDST_UNIFY(Wdq, Udq, UdqMdq)
 #define GEN_INSN_WR_GVEC_MM(mnem, gvec, opW1, opR1, vece)       \
     GEN_INSN_WR_GVEC(mnem, gvec, opW1, opR1, vece,              \
                      sizeof(MMXReg), sizeof(MMXReg))
+#define GEN_INSN_WR_GVEC_XMM(mnem, gvec, opW1, opR1, vece)      \
+    GEN_INSN_WR_GVEC(mnem, gvec, opW1, opR1, vece,              \
+                     sizeof(XMMReg), sizeof(XMMReg))
 
 #define GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece, oprsz, maxsz) \
     static void gen_insn_wrr(mnem, opW1, opR1, opR2)(                   \
@@ -4954,6 +4957,9 @@ INSNOP_LDST_UNIFY(Wdq, Udq, UdqMdq)
 #define GEN_INSN_WRR_GVEC_MM(mnem, gvec, opW1, opR1, opR2, vece)    \
     GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece,           \
                       sizeof(MMXReg), sizeof(MMXReg))
+#define GEN_INSN_WRR_GVEC_XMM(mnem, gvec, opW1, opR1, opR2, vece)   \
+    GEN_INSN_WRR_GVEC(mnem, gvec, opW1, opR1, opR2, vece,           \
+                      sizeof(XMMReg), sizeof(XMMReg))
 
 static void gen_insn_wr(movq, Eq, Pq)(CPUX86State *env, DisasContext *s,
                                       insnop_t(Eq) ret, insnop_t(Pq) arg1)
@@ -4986,6 +4992,101 @@ static void gen_insn_wr(movd, Pq, Ed)(CPUX86State *env, DisasContext *s,
 
 GEN_INSN_WR_GVEC_MM(movq, mov, Pq, Qq, MO_64)
 GEN_INSN_WR_GVEC_MM(movq, mov, Qq, Pq, MO_64)
+GEN_INSN_WR_GVEC_XMM(movaps, mov, Vdq, Wdq, MO_64)
+GEN_INSN_WR_GVEC_XMM(movaps, mov, Wdq, Vdq, MO_64)
+GEN_INSN_WR_GVEC_XMM(movups, mov, Vdq, Wdq, MO_64)
+GEN_INSN_WR_GVEC_XMM(movups, mov, Wdq, Vdq, MO_64)
+
+static void gen_insn_wr(movss, Wd, Vd)(CPUX86State *env, DisasContext *s,
+                                       insnop_t(Wd) ret, insnop_t(Vd) arg1)
+{
+    const size_t ofs = offsetof(ZMMReg, ZMM_L(0));
+    gen_op_movl(s, ret + ofs, arg1 + ofs);
+}
+
+static void gen_insn_wrr(movss, Vdq, Vdq, UdMd)(CPUX86State *env,
+                                                DisasContext *s,
+                                                insnop_t(Vdq) ret,
+                                                insnop_t(Vdq) arg1,
+                                                insnop_t(UdMd) arg2)
+{
+    assert(ret == arg1);
+
+    if (arg2.is_mem) {
+        const size_t ofs0 = offsetof(ZMMReg, ZMM_Q(0));
+        const size_t ofs1 = offsetof(ZMMReg, ZMM_Q(1));
+
+        tcg_gen_movi_i64(s->tmp1_i64, 0);
+        tcg_gen_st_i64(s->tmp1_i64, cpu_env, ret + ofs0);
+        tcg_gen_st_i64(s->tmp1_i64, cpu_env, ret + ofs1);
+    }
+    gen_insn_wr(movss, Wd, Vd)(env, s, ret, arg2.op_reg);
+}
+
+static void gen_insn_wr(movlps, Mq, Vq)(CPUX86State *env, DisasContext *s,
+                                        insnop_t(Mq) ret, insnop_t(Vq) arg1)
+{
+    assert(ret == s->A0);
+    gen_stq_env_A0(s, arg1 + offsetof(ZMMReg, ZMM_Q(0)));
+}
+
+static void gen_insn_wr(movhlps, Vq, UdqMq)(CPUX86State *env,
+                                            DisasContext *s,
+                                            insnop_t(Vq) ret,
+                                            insnop_t(UdqMq) arg1)
+{
+    const size_t dofs = offsetof(ZMMReg, ZMM_Q(0));
+    const size_t aofs = offsetof(ZMMReg, ZMM_Q(arg1.is_mem ? 0 : 1));
+    gen_op_movq(s, ret + dofs, arg1.op_reg + aofs);
+}
+
+static void gen_insn_wr(movhps, Mq, Vdq)(CPUX86State *env, DisasContext *s,
+                                         insnop_t(Mq) ret, insnop_t(Vdq) arg1)
+{
+    assert(ret == s->A0);
+    gen_stq_env_A0(s, arg1 + offsetof(ZMMReg, ZMM_Q(1)));
+}
+
+static void gen_insn_wrr(movlhps, Vdq, Vq, UqMq)(CPUX86State *env,
+                                                 DisasContext *s,
+                                                 insnop_t(Vdq) ret,
+                                                 insnop_t(Vq) arg1,
+                                                 insnop_t(UqMq) arg2)
+{
+    assert(ret == arg1);
+
+    const size_t dofs = offsetof(ZMMReg, ZMM_Q(1));
+    const size_t aofs = offsetof(ZMMReg, ZMM_Q(0));
+    gen_op_movq(s, ret + dofs, arg2.op_reg + aofs);
+}
+
+static void gen_insn_wr(pmovmskb, Gd, Nq)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Gd) ret, insnop_t(Nq) arg1)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_pmovmskb_mmx(ret, cpu_env, s->ptr0);
+}
+
+static void gen_insn_wr(pmovmskb, Gq, Nq)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Gq) ret, insnop_t(Nq) arg1)
+{
+    gen_insn_wr(pmovmskb, Gd, Nq)(env, s, s->tmp2_i32, arg1);
+    tcg_gen_extu_i32_i64(ret, s->tmp2_i32);
+}
+
+static void gen_insn_wr(movmskps, Gd, Udq)(CPUX86State *env, DisasContext *s,
+                                           insnop_t(Gd) ret, insnop_t(Udq) arg1)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_movmskps(ret, cpu_env, s->ptr0);
+}
+
+static void gen_insn_wr(movmskps, Gq, Udq)(CPUX86State *env, DisasContext *s,
+                                           insnop_t(Gq) ret, insnop_t(Udq) arg1)
+{
+    gen_insn_wr(movmskps, Gd, Udq)(env, s, s->tmp2_i32, arg1);
+    tcg_gen_extu_i32_i64(ret, s->tmp2_i32);
+}
 
 GEN_INSN_WRR_GVEC_MM(paddb, add, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(paddw, add, Pq, Pq, Qq, MO_16)
@@ -4994,6 +5095,8 @@ GEN_INSN_WRR_GVEC_MM(paddsb, ssadd, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(paddsw, ssadd, Pq, Pq, Qq, MO_16)
 GEN_INSN_WRR_GVEC_MM(paddusb, usadd, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(paddusw, usadd, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_HELPER(addps, addps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(addss, addss, Vd, Vd, Wd)
 
 GEN_INSN_WRR_GVEC_MM(psubb, sub, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(psubw, sub, Pq, Pq, Qq, MO_16)
@@ -5002,11 +5105,39 @@ GEN_INSN_WRR_GVEC_MM(psubsb, sssub, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(psubsw, sssub, Pq, Pq, Qq, MO_16)
 GEN_INSN_WRR_GVEC_MM(psubusb, ussub, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(psubusw, ussub, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_HELPER(subps, subps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(subss, subss, Vd, Vd, Wd)
 
 GEN_INSN_WRR_HELPER(pmulhw, pmulhw_mmx, Pq, Pq, Qq)
 GEN_INSN_WRR_HELPER(pmullw, pmullw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(pmulhuw, pmulhuw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(mulps, mulps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(mulss, mulss, Vd, Vd, Wd)
+
 GEN_INSN_WRR_HELPER(pmaddwd, pmaddwd_mmx, Pq, Pq, Qq)
 
+GEN_INSN_WRR_HELPER(divps, divps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(divss, divss, Vd, Vd, Wd)
+
+GEN_INSN_WR_HELPER(rcpps, rcpps, Vdq, Wdq)
+GEN_INSN_WR_HELPER(rcpss, rcpss, Vd, Wd)
+GEN_INSN_WR_HELPER(sqrtps, sqrtps, Vdq, Wdq)
+GEN_INSN_WR_HELPER(sqrtss, sqrtss, Vd, Wd)
+GEN_INSN_WR_HELPER(rsqrtps, rsqrtps, Vdq, Wdq)
+GEN_INSN_WR_HELPER(rsqrtss, rsqrtss, Vd, Wd)
+
+GEN_INSN_WRR_GVEC_MM(pminub, umin, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(pminsw, smin, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_HELPER(minps, minps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(minss, minss, Vd, Vd, Wd)
+GEN_INSN_WRR_GVEC_MM(pmaxub, umax, Pq, Pq, Qq, MO_8)
+GEN_INSN_WRR_GVEC_MM(pmaxsw, smax, Pq, Pq, Qq, MO_16)
+GEN_INSN_WRR_HELPER(maxps, maxps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(maxss, maxss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(pavgb, pavgb_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(pavgw, pavgw_mmx, Pq, Pq, Qq)
+GEN_INSN_WRR_HELPER(psadbw, psadbw_mmx, Pq, Pq, Qq)
+
 GEN_INSN_WRR_GVEC_MM(pcmpeqb, cmpeq, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(pcmpeqw, cmpeq, Pq, Pq, Qq, MO_16)
 GEN_INSN_WRR_GVEC_MM(pcmpeqd, cmpeq, Pq, Pq, Qq, MO_32)
@@ -5014,10 +5145,108 @@ GEN_INSN_WRR_GVEC_MM(pcmpgtb, cmpgt, Pq, Pq, Qq, MO_8)
 GEN_INSN_WRR_GVEC_MM(pcmpgtw, cmpgt, Pq, Pq, Qq, MO_16)
 GEN_INSN_WRR_GVEC_MM(pcmpgtd, cmpgt, Pq, Pq, Qq, MO_32)
 
+GEN_INSN_WRR_HELPER(cmpeqps, cmpeqps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpeqss, cmpeqss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpltps, cmpltps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpltss, cmpltss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpleps, cmpleps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpless, cmpless, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpunordps, cmpunordps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpunordss, cmpunordss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpneqps, cmpneqps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpneqss, cmpneqss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpnltps, cmpnltps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpnltss, cmpnltss, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpnleps, cmpnleps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpnless, cmpnless, Vd, Vd, Wd)
+GEN_INSN_WRR_HELPER(cmpordps, cmpordps, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(cmpordss, cmpordss, Vd, Vd, Wd)
+
+static void gen_insn_wrrr(cmpps, Vdq, Vdq, Wdq, Ib)(CPUX86State *env,
+                                                    DisasContext *s,
+                                                    insnop_t(Vdq) ret,
+                                                    insnop_t(Vdq) arg1,
+                                                    insnop_t(Wdq) arg2,
+                                                    insnop_t(Ib) arg3)
+{
+    switch (arg3 & 7) {
+    case 0:
+        gen_insn_wrr(cmpeqps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 1:
+        gen_insn_wrr(cmpltps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 2:
+        gen_insn_wrr(cmpleps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 3:
+        gen_insn_wrr(cmpunordps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 4:
+        gen_insn_wrr(cmpneqps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 5:
+        gen_insn_wrr(cmpnltps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 6:
+        gen_insn_wrr(cmpnleps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    case 7:
+        gen_insn_wrr(cmpordps, Vdq, Vdq, Wdq)(env, s, ret, arg1, arg2);
+        return;
+    }
+
+    g_assert_not_reached();
+}
+
+static void gen_insn_wrrr(cmpss, Vd, Vd, Wd, Ib)(CPUX86State *env,
+                                                 DisasContext *s,
+                                                 insnop_t(Vd) ret,
+                                                 insnop_t(Vd) arg1,
+                                                 insnop_t(Wd) arg2,
+                                                 insnop_t(Ib) arg3)
+{
+    switch (arg3 & 7) {
+    case 0:
+        gen_insn_wrr(cmpeqss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 1:
+        gen_insn_wrr(cmpltss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 2:
+        gen_insn_wrr(cmpless, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 3:
+        gen_insn_wrr(cmpunordss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 4:
+        gen_insn_wrr(cmpneqss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 5:
+        gen_insn_wrr(cmpnltss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 6:
+        gen_insn_wrr(cmpnless, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    case 7:
+        gen_insn_wrr(cmpordss, Vd, Vd, Wd)(env, s, ret, arg1, arg2);
+        return;
+    }
+
+    g_assert_not_reached();
+}
+
+GEN_INSN_WR_HELPER(comiss, comiss, Vd, Wd)
+GEN_INSN_WR_HELPER(ucomiss, ucomiss, Vd, Wd)
+
 GEN_INSN_WRR_GVEC_MM(pand, and, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_XMM(andps, and, Vdq, Vdq, Wdq, MO_64)
 GEN_INSN_WRR_GVEC_MM(pandn, andn, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_XMM(andnps, andn, Vdq, Vdq, Wdq, MO_64)
 GEN_INSN_WRR_GVEC_MM(por, or, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_XMM(orps, or, Vdq, Vdq, Wdq, MO_64)
 GEN_INSN_WRR_GVEC_MM(pxor, xor, Pq, Pq, Qq, MO_64)
+GEN_INSN_WRR_GVEC_XMM(xorps, xor, Vdq, Vdq, Wdq, MO_64)
 
 GEN_INSN_WRR_HELPER(psllw, psllw_mmx, Pq, Pq, Qq)
 GEN_INSN_WRR_HELPER(pslld, pslld_mmx, Pq, Pq, Qq)
@@ -5061,8 +5290,219 @@ GEN_INSN_WRR_HELPER(punpckhbw, punpckhbw_mmx, Pq, Pq, Qq)
 GEN_INSN_WRR_HELPER(punpckhwd, punpckhwd_mmx, Pq, Pq, Qq)
 GEN_INSN_WRR_HELPER(punpckhdq, punpckhdq_mmx, Pq, Pq, Qq)
 
+GEN_INSN_WRR_HELPER(unpcklps, punpckldq_xmm, Vdq, Vdq, Wdq)
+GEN_INSN_WRR_HELPER(unpckhps, punpckhdq_xmm, Vdq, Vdq, Wdq)
+
 GEN_INSN_HELPER(emms, emms)
 
+static void gen_insn_wrr(pshufw, Pq, Qq, Ib)(CPUX86State *env,
+                                             DisasContext *s,
+                                             insnop_t(Pq) ret,
+                                             insnop_t(Qq) arg1,
+                                             insnop_t(Ib) arg2)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);
+    tcg_gen_addi_ptr(s->ptr1, cpu_env, arg1);
+    tcg_gen_movi_i32(s->tmp2_i32, arg2);
+    gen_helper_pshufw_mmx(s->ptr0, s->ptr1, s->tmp2_i32);
+}
+
+static void gen_insn_wrrr(shufps, Vdq, Vdq, Wdq, Ib)(CPUX86State *env,
+                                                     DisasContext *s,
+                                                     insnop_t(Vdq) ret,
+                                                     insnop_t(Vdq) arg1,
+                                                     insnop_t(Wdq) arg2,
+                                                     insnop_t(Ib) arg3)
+{
+    assert(ret == arg1);
+
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);
+    tcg_gen_addi_ptr(s->ptr1, cpu_env, arg2);
+    tcg_gen_movi_i32(s->tmp2_i32, arg3);
+    gen_helper_shufps(s->ptr0, s->ptr1, s->tmp2_i32);
+}
+
+static void gen_insn_wrrr(pinsrw, Pq, Pq, RdMw, Ib)(CPUX86State *env,
+                                                    DisasContext *s,
+                                                    insnop_t(Pq) ret,
+                                                    insnop_t(Pq) arg1,
+                                                    insnop_t(RdMw) arg2,
+                                                    insnop_t(Ib) arg3)
+{
+    assert(ret == arg1);
+
+    const size_t ofs = offsetof(MMXReg, MMX_W(arg3 & 3));
+    tcg_gen_st16_i32(arg2.op_reg, cpu_env, ret + ofs);
+}
+
+static void gen_insn_wrr(pextrw, Gd, Nq, Ib)(CPUX86State *env,
+                                             DisasContext *s,
+                                             insnop_t(Gd) ret,
+                                             insnop_t(Nq) arg1,
+                                             insnop_t(Ib) arg2)
+{
+    const size_t ofs = offsetof(MMXReg, MMX_W(arg2 & 3));
+    tcg_gen_ld16u_i32(ret, cpu_env, arg1 + ofs);
+}
+
+static void gen_insn_wrr(pextrw, Gq, Nq, Ib)(CPUX86State *env,
+                                             DisasContext *s,
+                                             insnop_t(Gq) ret,
+                                             insnop_t(Nq) arg1,
+                                             insnop_t(Ib) arg2)
+{
+    const size_t ofs = offsetof(MMXReg, MMX_W(arg2 & 3));
+    tcg_gen_ld16u_i64(ret, cpu_env, arg1 + ofs);
+}
+
+GEN_INSN_WR_HELPER(cvtpi2ps, cvtpi2ps, Vdq, Qq)
+
+static void gen_insn_wr(cvtsi2ss, Vd, Ed)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Vd) ret, insnop_t(Ed) arg1)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);
+    gen_helper_cvtsi2ss(cpu_env, s->ptr0, arg1);
+}
+
+static void gen_insn_wr(cvtsi2ss, Vd, Eq)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Vd) ret, insnop_t(Eq) arg1)
+{
+#ifdef TARGET_X86_64
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);
+    gen_helper_cvtsq2ss(cpu_env, s->ptr0, arg1);
+#else /* TARGET_X86_64 */
+    g_assert_not_reached();
+#endif /* TARGET_X86_64 */
+}
+
+GEN_INSN_WR_HELPER(cvtps2pi, cvtps2pi, Pq, Wq)
+
+static void gen_insn_wr(cvtss2si, Gd, Wd)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Gd) ret, insnop_t(Wd) arg1)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_cvtss2si(ret, cpu_env, s->ptr0);
+}
+
+static void gen_insn_wr(cvtss2si, Gq, Wd)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Gq) ret, insnop_t(Wd) arg1)
+{
+#ifdef TARGET_X86_64
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_cvtss2sq(ret, cpu_env, s->ptr0);
+#else /* TARGET_X86_64 */
+    g_assert_not_reached();
+#endif /* TARGET_X86_64 */
+}
+
+GEN_INSN_WR_HELPER(cvttps2pi, cvttps2pi, Pq, Wq)
+
+static void gen_insn_wr(cvttss2si, Gd, Wd)(CPUX86State *env, DisasContext *s,
+                                           insnop_t(Gd) ret, insnop_t(Wd) arg1)
+{
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_cvttss2si(ret, cpu_env, s->ptr0);
+}
+
+static void gen_insn_wr(cvttss2si, Gq, Wd)(CPUX86State *env, DisasContext *s,
+                                           insnop_t(Gq) ret, insnop_t(Wd) arg1)
+{
+#ifdef TARGET_X86_64
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, arg1);
+    gen_helper_cvttss2sq(ret, cpu_env, s->ptr0);
+#else /* TARGET_X86_64 */
+    g_assert_not_reached();
+#endif /* TARGET_X86_64 */
+}
+
+static void gen_insn_wr(maskmovq, Pq, Nq)(CPUX86State *env, DisasContext *s,
+                                          insnop_t(Pq) ret, insnop_t(Nq) arg1)
+{
+    tcg_gen_mov_tl(s->A0, cpu_regs[R_EDI]);
+    gen_extu(s->aflag, s->A0);
+    gen_add_A0_ds_seg(s);
+
+    tcg_gen_addi_ptr(s->ptr0, cpu_env, ret);
+    tcg_gen_addi_ptr(s->ptr1, cpu_env, arg1);
+    gen_helper_maskmov_mmx(cpu_env, s->ptr0, s->ptr1, s->A0);
+}
+
+static void gen_insn_wr(movntq, Mq, Pq)(CPUX86State *env, DisasContext *s,
+                                        insnop_t(Mq) ret, insnop_t(Pq) arg1)
+{
+    assert(ret == s->A0);
+    gen_stq_env_A0(s, arg1);
+}
+
+static void gen_insn_wr(movntps, Mdq, Vdq)(CPUX86State *env,
+                                           DisasContext *s,
+                                           insnop_t(Mdq) ret,
+                                           insnop_t(Vdq) arg1)
+{
+    assert(ret == s->A0);
+    gen_sto_env_A0(s, arg1);
+}
+
+static void gen_insn(sfence)(CPUX86State *env, DisasContext *s)
+{
+    if (s->prefix & PREFIX_LOCK) {
+        gen_illegal_opcode(s);
+    } else {
+        tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
+    }
+}
+
+static void gen_insn_r(ldmxcsr, Md)(CPUX86State *env, DisasContext *s,
+                                    insnop_t(Md) arg1)
+{
+    if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
+        gen_illegal_opcode(s);
+    } else if (s->flags & HF_TS_MASK) {
+        gen_exception(s, EXCP07_PREX);
+    } else {
+        tcg_gen_qemu_ld_i32(s->tmp2_i32, arg1, s->mem_index, MO_LEUL);
+        gen_helper_ldmxcsr(cpu_env, s->tmp2_i32);
+    }
+}
+
+static void gen_insn_w(stmxcsr, Md)(CPUX86State *env, DisasContext *s,
+                                    insnop_t(Md) ret)
+{
+    if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
+        gen_illegal_opcode(s);
+    } else if (s->flags & HF_TS_MASK) {
+        gen_exception(s, EXCP07_PREX);
+    } else {
+        const size_t ofs = offsetof(CPUX86State, mxcsr);
+        tcg_gen_ld_i32(s->tmp2_i32, cpu_env, ofs);
+        tcg_gen_qemu_st_i32(s->tmp2_i32, ret, s->mem_index, MO_LEUL);
+    }
+}
+
+static void gen_insn_r(prefetcht0, Mb)(CPUX86State *env, DisasContext *s,
+                                       insnop_t(Mb) arg1)
+{
+    /* no-op */
+}
+
+static void gen_insn_r(prefetcht1, Mb)(CPUX86State *env, DisasContext *s,
+                                       insnop_t(Mb) arg1)
+{
+    /* no-op */
+}
+
+static void gen_insn_r(prefetcht2, Mb)(CPUX86State *env, DisasContext *s,
+                                       insnop_t(Mb) arg1)
+{
+    /* no-op */
+}
+
+static void gen_insn_r(prefetchnta, Mb)(CPUX86State *env, DisasContext *s,
+                                        insnop_t(Mb) arg1)
+{
+    /* no-op */
+}
+
 /*
  * Instruction translators
  */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 38/39] target/i386: introduce SSE instructions to insn.h
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (36 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 37/39] target/i386: introduce SSE code generators Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 39/39] target/i386: introduce memory-pointer operand read/write workarounds Jan Bobek
                   ` (2 subsequent siblings)
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

Add all the SSE instruction entries to insn.h.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/insn.h | 158 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)

diff --git a/target/i386/insn.h b/target/i386/insn.h
index 6506ff3137..6e0c75b9f7 100644
--- a/target/i386/insn.h
+++ b/target/i386/insn.h
@@ -78,6 +78,36 @@ INSN_WR(movq, LEG(NP, 0F, 1), 0x7e, MMX, Eq, Pq)
 INSN_WR(movq, LEG(NP, 0F, 0), 0x6f, MMX, Pq, Qq)
 /* NP 0F 7F /r: MOVQ mm/m64, mm */
 INSN_WR(movq, LEG(NP, 0F, 0), 0x7f, MMX, Qq, Pq)
+/* NP 0F 28 /r: MOVAPS xmm1, xmm2/m128 */
+INSN_WR(movaps, LEG(NP, 0F, 0), 0x28, SSE, Vdq, Wdq)
+/* NP 0F 29 /r: MOVAPS xmm2/m128, xmm1 */
+INSN_WR(movaps, LEG(NP, 0F, 0), 0x29, SSE, Wdq, Vdq)
+/* NP 0F 10 /r: MOVUPS xmm1, xmm2/m128 */
+INSN_WR(movups, LEG(NP, 0F, 0), 0x10, SSE, Vdq, Wdq)
+/* NP 0F 11 /r: MOVUPS xmm2/m128, xmm1 */
+INSN_WR(movups, LEG(NP, 0F, 0), 0x11, SSE, Wdq, Vdq)
+/* F3 0F 10 /r: MOVSS xmm1, xmm2/m32 */
+INSN_WRR(movss, LEG(F3, 0F, 0), 0x10, SSE, Vdq, Vdq, UdMd)
+/* F3 0F 11 /r: MOVSS xmm2/m32, xmm1 */
+INSN_WR(movss, LEG(F3, 0F, 0), 0x11, SSE, Wd, Vd)
+/* NP 0F 12 /r: MOVHLPS xmm1, xmm2 */
+/* NP 0F 12 /r: MOVLPS xmm1, m64 */
+INSN_WR(movhlps, LEG(NP, 0F, 0), 0x12, SSE, Vq, UdqMq)
+/* 0F 13 /r: MOVLPS m64, xmm1 */
+INSN_WR(movlps, LEG(NP, 0F, 0), 0x13, SSE, Mq, Vq)
+/* NP 0F 16 /r: MOVLHPS xmm1, xmm2 */
+/* NP 0F 16 /r: MOVHPS xmm1, m64 */
+INSN_WRR(movlhps, LEG(NP, 0F, 0), 0x16, SSE, Vdq, Vq, UqMq)
+/* NP 0F 17 /r: MOVHPS m64, xmm1 */
+INSN_WR(movhps, LEG(NP, 0F, 0), 0x17, SSE, Mq, Vdq)
+/* NP 0F D7 /r: PMOVMSKB r32, mm */
+INSN_WR(pmovmskb, LEG(NP, 0F, 0), 0xd7, SSE, Gd, Nq)
+/* NP REX.W 0F D7 /r: PMOVMSKB r64, mm */
+INSN_WR(pmovmskb, LEG(NP, 0F, 1), 0xd7, SSE, Gq, Nq)
+/* NP 0F 50 /r: MOVMSKPS r32, xmm */
+INSN_WR(movmskps, LEG(NP, 0F, 0), 0x50, SSE, Gd, Udq)
+/* NP REX.W 0F 50 /r: MOVMSKPS r64, xmm */
+INSN_WR(movmskps, LEG(NP, 0F, 1), 0x50, SSE, Gq, Udq)
 /* NP 0F FC /r: PADDB mm, mm/m64 */
 INSN_WRR(paddb, LEG(NP, 0F, 0), 0xfc, MMX, Pq, Pq, Qq)
 /* NP 0F FD /r: PADDW mm, mm/m64 */
@@ -92,6 +122,10 @@ INSN_WRR(paddsw, LEG(NP, 0F, 0), 0xed, MMX, Pq, Pq, Qq)
 INSN_WRR(paddusb, LEG(NP, 0F, 0), 0xdc, MMX, Pq, Pq, Qq)
 /* NP 0F DD /r: PADDUSW mm,mm/m64 */
 INSN_WRR(paddusw, LEG(NP, 0F, 0), 0xdd, MMX, Pq, Pq, Qq)
+/* NP 0F 58 /r: ADDPS xmm1, xmm2/m128 */
+INSN_WRR(addps, LEG(NP, 0F, 0), 0x58, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 58 /r: ADDSS xmm1, xmm2/m32 */
+INSN_WRR(addss, LEG(F3, 0F, 0), 0x58, SSE, Vd, Vd, Wd)
 /* NP 0F F8 /r: PSUBB mm, mm/m64 */
 INSN_WRR(psubb, LEG(NP, 0F, 0), 0xf8, MMX, Pq, Pq, Qq)
 /* NP 0F F9 /r: PSUBW mm, mm/m64 */
@@ -106,12 +140,60 @@ INSN_WRR(psubsw, LEG(NP, 0F, 0), 0xe9, MMX, Pq, Pq, Qq)
 INSN_WRR(psubusb, LEG(NP, 0F, 0), 0xd8, MMX, Pq, Pq, Qq)
 /* NP 0F D9 /r: PSUBUSW mm, mm/m64 */
 INSN_WRR(psubusw, LEG(NP, 0F, 0), 0xd9, MMX, Pq, Pq, Qq)
+/* NP 0F 5C /r: SUBPS xmm1, xmm2/m128 */
+INSN_WRR(subps, LEG(NP, 0F, 0), 0x5c, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 5C /r: SUBSS xmm1, xmm2/m32 */
+INSN_WRR(subss, LEG(F3, 0F, 0), 0x5c, SSE, Vd, Vd, Wd)
 /* NP 0F D5 /r: PMULLW mm, mm/m64 */
 INSN_WRR(pmullw, LEG(NP, 0F, 0), 0xd5, MMX, Pq, Pq, Qq)
 /* NP 0F E5 /r: PMULHW mm, mm/m64 */
 INSN_WRR(pmulhw, LEG(NP, 0F, 0), 0xe5, MMX, Pq, Pq, Qq)
+/* NP 0F E4 /r: PMULHUW mm1, mm2/m64 */
+INSN_WRR(pmulhuw, LEG(NP, 0F, 0), 0xe4, SSE, Pq, Pq, Qq)
+/* NP 0F 59 /r: MULPS xmm1, xmm2/m128 */
+INSN_WRR(mulps, LEG(NP, 0F, 0), 0x59, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 59 /r: MULSS xmm1,xmm2/m32 */
+INSN_WRR(mulss, LEG(F3, 0F, 0), 0x59, SSE, Vd, Vd, Wd)
 /* NP 0F F5 /r: PMADDWD mm, mm/m64 */
 INSN_WRR(pmaddwd, LEG(NP, 0F, 0), 0xf5, MMX, Pq, Pq, Qq)
+/* NP 0F 5E /r: DIVPS xmm1, xmm2/m128 */
+INSN_WRR(divps, LEG(NP, 0F, 0), 0x5e, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 5E /r: DIVSS xmm1, xmm2/m32 */
+INSN_WRR(divss, LEG(F3, 0F, 0), 0x5e, SSE, Vd, Vd, Wd)
+/* NP 0F 53 /r: RCPPS xmm1, xmm2/m128 */
+INSN_WR(rcpps, LEG(NP, 0F, 0), 0x53, SSE, Vdq, Wdq)
+/* F3 0F 53 /r: RCPSS xmm1, xmm2/m32 */
+INSN_WR(rcpss, LEG(F3, 0F, 0), 0x53, SSE, Vd, Wd)
+/* NP 0F 51 /r: SQRTPS xmm1, xmm2/m128 */
+INSN_WR(sqrtps, LEG(NP, 0F, 0), 0x51, SSE, Vdq, Wdq)
+/* F3 0F 51 /r: SQRTSS xmm1, xmm2/m32 */
+INSN_WR(sqrtss, LEG(F3, 0F, 0), 0x51, SSE, Vd, Wd)
+/* NP 0F 52 /r: RSQRTPS xmm1, xmm2/m128 */
+INSN_WR(rsqrtps, LEG(NP, 0F, 0), 0x52, SSE, Vdq, Wdq)
+/* F3 0F 52 /r: RSQRTSS xmm1, xmm2/m32 */
+INSN_WR(rsqrtss, LEG(F3, 0F, 0), 0x52, SSE, Vd, Wd)
+/* NP 0F DA /r: PMINUB mm1, mm2/m64 */
+INSN_WRR(pminub, LEG(NP, 0F, 0), 0xda, SSE, Pq, Pq, Qq)
+/* NP 0F EA /r: PMINSW mm1, mm2/m64 */
+INSN_WRR(pminsw, LEG(NP, 0F, 0), 0xea, SSE, Pq, Pq, Qq)
+/* NP 0F 5D /r: MINPS xmm1, xmm2/m128 */
+INSN_WRR(minps, LEG(NP, 0F, 0), 0x5d, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 5D /r: MINSS xmm1,xmm2/m32 */
+INSN_WRR(minss, LEG(F3, 0F, 0), 0x5d, SSE, Vd, Vd, Wd)
+/* NP 0F DE /r: PMAXUB mm1, mm2/m64 */
+INSN_WRR(pmaxub, LEG(NP, 0F, 0), 0xde, SSE, Pq, Pq, Qq)
+/* NP 0F EE /r: PMAXSW mm1, mm2/m64 */
+INSN_WRR(pmaxsw, LEG(NP, 0F, 0), 0xee, SSE, Pq, Pq, Qq)
+/* NP 0F 5F /r: MAXPS xmm1, xmm2/m128 */
+INSN_WRR(maxps, LEG(NP, 0F, 0), 0x5f, SSE, Vdq, Vdq, Wdq)
+/* F3 0F 5F /r: MAXSS xmm1, xmm2/m32 */
+INSN_WRR(maxss, LEG(F3, 0F, 0), 0x5f, SSE, Vd, Vd, Wd)
+/* NP 0F E0 /r: PAVGB mm1, mm2/m64 */
+INSN_WRR(pavgb, LEG(NP, 0F, 0), 0xe0, SSE, Pq, Pq, Qq)
+/* NP 0F E3 /r: PAVGW mm1, mm2/m64 */
+INSN_WRR(pavgw, LEG(NP, 0F, 0), 0xe3, SSE, Pq, Pq, Qq)
+/* NP 0F F6 /r: PSADBW mm1, mm2/m64 */
+INSN_WRR(psadbw, LEG(NP, 0F, 0), 0xf6, SSE, Pq, Pq, Qq)
 /* NP 0F 74 /r: PCMPEQB mm,mm/m64 */
 INSN_WRR(pcmpeqb, LEG(NP, 0F, 0), 0x74, MMX, Pq, Pq, Qq)
 /* NP 0F 75 /r: PCMPEQW mm,mm/m64 */
@@ -124,14 +206,30 @@ INSN_WRR(pcmpgtb, LEG(NP, 0F, 0), 0x64, MMX, Pq, Pq, Qq)
 INSN_WRR(pcmpgtw, LEG(NP, 0F, 0), 0x65, MMX, Pq, Pq, Qq)
 /* NP 0F 66 /r: PCMPGTD mm,mm/m64 */
 INSN_WRR(pcmpgtd, LEG(NP, 0F, 0), 0x66, MMX, Pq, Pq, Qq)
+/* NP 0F C2 /r ib: CMPPS xmm1, xmm2/m128, imm8 */
+INSN_WRRR(cmpps, LEG(NP, 0F, 0), 0xc2, SSE, Vdq, Vdq, Wdq, Ib)
+/* F3 0F C2 /r ib: CMPSS xmm1, xmm2/m32, imm8 */
+INSN_WRRR(cmpss, LEG(F3, 0F, 0), 0xc2, SSE, Vd, Vd, Wd, Ib)
+/* NP 0F 2E /r: UCOMISS xmm1, xmm2/m32 */
+INSN_RR(ucomiss, LEG(NP, 0F, 0), 0x2e, SSE, Vd, Wd)
+/* NP 0F 2F /r: COMISS xmm1, xmm2/m32 */
+INSN_RR(comiss, LEG(NP, 0F, 0), 0x2f, SSE, Vd, Wd)
 /* NP 0F DB /r: PAND mm, mm/m64 */
 INSN_WRR(pand, LEG(NP, 0F, 0), 0xdb, MMX, Pq, Pq, Qq)
+/* NP 0F 54 /r: ANDPS xmm1, xmm2/m128 */
+INSN_WRR(andps, LEG(NP, 0F, 0), 0x54, SSE, Vdq, Vdq, Wdq)
 /* NP 0F DF /r: PANDN mm, mm/m64 */
 INSN_WRR(pandn, LEG(NP, 0F, 0), 0xdf, MMX, Pq, Pq, Qq)
+/* NP 0F 55 /r: ANDNPS xmm1, xmm2/m128 */
+INSN_WRR(andnps, LEG(NP, 0F, 0), 0x55, SSE, Vdq, Vdq, Wdq)
 /* NP 0F EB /r: POR mm, mm/m64 */
 INSN_WRR(por, LEG(NP, 0F, 0), 0xeb, MMX, Pq, Pq, Qq)
+/* NP 0F 56 /r: ORPS xmm1, xmm2/m128 */
+INSN_WRR(orps, LEG(NP, 0F, 0), 0x56, SSE, Vdq, Vdq, Wdq)
 /* NP 0F EF /r: PXOR mm, mm/m64 */
 INSN_WRR(pxor, LEG(NP, 0F, 0), 0xef, MMX, Pq, Pq, Qq)
+/* NP 0F 57 /r: XORPS xmm1, xmm2/m128 */
+INSN_WRR(xorps, LEG(NP, 0F, 0), 0x57, SSE, Vdq, Vdq, Wdq)
 /* NP 0F F1 /r: PSLLW mm, mm/m64 */
 INSN_WRR(psllw, LEG(NP, 0F, 0), 0xf1, MMX, Pq, Pq, Qq)
 /* NP 0F F2 /r: PSLLD mm, mm/m64 */
@@ -166,6 +264,44 @@ INSN_WRR(punpcklbw, LEG(NP, 0F, 0), 0x60, MMX, Pq, Pq, Qd)
 INSN_WRR(punpcklwd, LEG(NP, 0F, 0), 0x61, MMX, Pq, Pq, Qd)
 /* NP 0F 62 /r: PUNPCKLDQ mm, mm/m32 */
 INSN_WRR(punpckldq, LEG(NP, 0F, 0), 0x62, MMX, Pq, Pq, Qd)
+/* NP 0F 14 /r: UNPCKLPS xmm1, xmm2/m128 */
+INSN_WRR(unpcklps, LEG(NP, 0F, 0), 0x14, SSE, Vdq, Vdq, Wdq)
+/* NP 0F 15 /r: UNPCKHPS xmm1, xmm2/m128 */
+INSN_WRR(unpckhps, LEG(NP, 0F, 0), 0x15, SSE, Vdq, Vdq, Wdq)
+/* NP 0F 70 /r ib: PSHUFW mm1, mm2/m64, imm8 */
+INSN_WRR(pshufw, LEG(NP, 0F, 0), 0x70, SSE, Pq, Qq, Ib)
+/* NP 0F C6 /r ib: SHUFPS xmm1, xmm3/m128, imm8 */
+INSN_WRRR(shufps, LEG(NP, 0F, 0), 0xc6, SSE, Vdq, Vdq, Wdq, Ib)
+/* NP 0F C4 /r ib: PINSRW mm, r32/m16, imm8 */
+INSN_WRRR(pinsrw, LEG(NP, 0F, 0), 0xc4, SSE, Pq, Pq, RdMw, Ib)
+/* NP 0F C5 /r ib: PEXTRW r32, mm, imm8 */
+INSN_WRR(pextrw, LEG(NP, 0F, 0), 0xc5, SSE, Gd, Nq, Ib)
+/* NP REX.W 0F C5 /r ib: PEXTRW r64, mm, imm8 */
+INSN_WRR(pextrw, LEG(NP, 0F, 1), 0xc5, SSE, Gq, Nq, Ib)
+/* NP 0F 2A /r: CVTPI2PS xmm, mm/m64 */
+INSN_WR(cvtpi2ps, LEG(NP, 0F, 0), 0x2a, SSE, Vdq, Qq)
+/* F3 0F 2A /r: CVTSI2SS xmm1,r/m32 */
+INSN_WR(cvtsi2ss, LEG(F3, 0F, 0), 0x2a, SSE, Vd, Ed)
+/* F3 REX.W 0F 2A /r: CVTSI2SS xmm1,r/m64 */
+INSN_WR(cvtsi2ss, LEG(F3, 0F, 1), 0x2a, SSE, Vd, Eq)
+/* NP 0F 2D /r: CVTPS2PI mm, xmm/m64 */
+INSN_WR(cvtps2pi, LEG(NP, 0F, 0), 0x2d, SSE, Pq, Wq)
+/* F3 0F 2D /r: CVTSS2SI r32,xmm1/m32 */
+INSN_WR(cvtss2si, LEG(F3, 0F, 0), 0x2d, SSE, Gd, Wd)
+/* F3 REX.W 0F 2D /r: CVTSS2SI r64,xmm1/m32 */
+INSN_WR(cvtss2si, LEG(F3, 0F, 1), 0x2d, SSE, Gq, Wd)
+/* NP 0F 2C /r: CVTTPS2PI mm, xmm/m64 */
+INSN_WR(cvttps2pi, LEG(NP, 0F, 0), 0x2c, SSE, Pq, Wq)
+/* F3 0F 2C /r: CVTTSS2SI r32,xmm1/m32 */
+INSN_WR(cvttss2si, LEG(F3, 0F, 0), 0x2c, SSE, Gd, Wd)
+/* F3 REX.W 0F 2C /r: CVTTSS2SI r64,xmm1/m32 */
+INSN_WR(cvttss2si, LEG(F3, 0F, 1), 0x2c, SSE, Gq, Wd)
+/* NP 0F F7 /r: MASKMOVQ mm1, mm2 */
+INSN_RR(maskmovq, LEG(NP, 0F, 0), 0xf7, SSE, Pq, Nq)
+/* NP 0F 2B /r: MOVNTPS m128, xmm1 */
+INSN_WR(movntps, LEG(NP, 0F, 0), 0x2b, SSE, Mdq, Vdq)
+/* NP 0F E7 /r: MOVNTQ m64, mm */
+INSN_WR(movntq, LEG(NP, 0F, 0), 0xe7, SSE, Mq, Pq)
 /* NP 0F 77: EMMS */
 INSN(emms, LEG(NP, 0F, 0), 0x77, MMX)
 
@@ -197,6 +333,28 @@ INSN_GRP_BEGIN(grp14_LEG_NP)
     INSN_GRPMEMB_WRR(grp14_LEG_NP, psrlq, 2, MMX, Nq, Nq, Ib)
 INSN_GRP_END(grp14_LEG_NP)
 
+INSN_GRP(grp15_LEG_NP, LEG(NP, 0F, 0), 0xae)
+INSN_GRP_BEGIN(grp15_LEG_NP)
+    /* NP 0F AE /7: SFENCE */
+    INSN_GRPMEMB(grp15_LEG_NP, sfence, 7, SSE)
+    /* NP 0F AE /2: LDMXCSR m32 */
+    INSN_GRPMEMB_R(grp15_LEG_NP, ldmxcsr, 2, SSE, Md)
+    /* NP 0F AE /3: STMXCSR m32 */
+    INSN_GRPMEMB_W(grp15_LEG_NP, stmxcsr, 3, SSE, Md)
+INSN_GRP_END(grp15_LEG_NP)
+
+INSN_GRP(grp16_LEG_NP, LEG(NP, 0F, 0), 0x18)
+INSN_GRP_BEGIN(grp16_LEG_NP)
+    /* 0F 18 /1: PREFETCHT0 m8 */
+    INSN_GRPMEMB_R(grp16_LEG_NP, prefetcht0, 1, SSE, Mb)
+    /* 0F 18 /2: PREFETCHT1 m8 */
+    INSN_GRPMEMB_R(grp16_LEG_NP, prefetcht1, 2, SSE, Mb)
+    /* 0F 18 /3: PREFETCHT2 m8 */
+    INSN_GRPMEMB_R(grp16_LEG_NP, prefetcht2, 3, SSE, Mb)
+    /* 0F 18 /0: PREFETCHNTA m8 */
+    INSN_GRPMEMB_R(grp16_LEG_NP, prefetchnta, 0, SSE, Mb)
+INSN_GRP_END(grp16_LEG_NP)
+
 #undef LEG
 #undef VEX
 #undef INSN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [Qemu-devel] [RFC PATCH v2 39/39] target/i386: introduce memory-pointer operand read/write workarounds
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (37 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 38/39] target/i386: introduce SSE instructions to insn.h Jan Bobek
@ 2019-08-10  4:12 ` Jan Bobek
  2019-08-10  4:44 ` [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation no-reply
  2019-08-10 23:35 ` Richard Henderson
  40 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-10  4:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Bobek, Alex Bennée, Richard Henderson

The memory-pointer operand has a known limitation (see the commit
introducing M* operands for details); the workaround involves
declaring write-memory operands as read-memory instead.

Note: This changeset is intended for development only and shall not be
included in the final patch series.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 target/i386/insn.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/i386/insn.h b/target/i386/insn.h
index 6e0c75b9f7..b61a4182f6 100644
--- a/target/i386/insn.h
+++ b/target/i386/insn.h
@@ -94,12 +94,14 @@ INSN_WR(movss, LEG(F3, 0F, 0), 0x11, SSE, Wd, Vd)
 /* NP 0F 12 /r: MOVLPS xmm1, m64 */
 INSN_WR(movhlps, LEG(NP, 0F, 0), 0x12, SSE, Vq, UdqMq)
 /* 0F 13 /r: MOVLPS m64, xmm1 */
-INSN_WR(movlps, LEG(NP, 0F, 0), 0x13, SSE, Mq, Vq)
+/* FIXME this is hacked, should be INSN_WR */
+INSN_RR(movlps, LEG(NP, 0F, 0), 0x13, SSE, Mq, Vq)
 /* NP 0F 16 /r: MOVLHPS xmm1, xmm2 */
 /* NP 0F 16 /r: MOVHPS xmm1, m64 */
 INSN_WRR(movlhps, LEG(NP, 0F, 0), 0x16, SSE, Vdq, Vq, UqMq)
 /* NP 0F 17 /r: MOVHPS m64, xmm1 */
-INSN_WR(movhps, LEG(NP, 0F, 0), 0x17, SSE, Mq, Vdq)
+/* FIXME this is hacked, should be INSN_WR */
+INSN_RR(movhps, LEG(NP, 0F, 0), 0x17, SSE, Mq, Vdq)
 /* NP 0F D7 /r: PMOVMSKB r32, mm */
 INSN_WR(pmovmskb, LEG(NP, 0F, 0), 0xd7, SSE, Gd, Nq)
 /* NP REX.W 0F D7 /r: PMOVMSKB r64, mm */
@@ -299,9 +301,11 @@ INSN_WR(cvttss2si, LEG(F3, 0F, 1), 0x2c, SSE, Gq, Wd)
 /* NP 0F F7 /r: MASKMOVQ mm1, mm2 */
 INSN_RR(maskmovq, LEG(NP, 0F, 0), 0xf7, SSE, Pq, Nq)
 /* NP 0F 2B /r: MOVNTPS m128, xmm1 */
-INSN_WR(movntps, LEG(NP, 0F, 0), 0x2b, SSE, Mdq, Vdq)
+/* FIXME this is hacked, should be INSN_WR */
+INSN_RR(movntps, LEG(NP, 0F, 0), 0x2b, SSE, Mdq, Vdq)
 /* NP 0F E7 /r: MOVNTQ m64, mm */
-INSN_WR(movntq, LEG(NP, 0F, 0), 0xe7, SSE, Mq, Pq)
+/* FIXME this is hacked, should be INSN_WR */
+INSN_RR(movntq, LEG(NP, 0F, 0), 0xe7, SSE, Mq, Pq)
 /* NP 0F 77: EMMS */
 INSN(emms, LEG(NP, 0F, 0), 0x77, MMX)
 
@@ -340,7 +344,8 @@ INSN_GRP_BEGIN(grp15_LEG_NP)
     /* NP 0F AE /2: LDMXCSR m32 */
     INSN_GRPMEMB_R(grp15_LEG_NP, ldmxcsr, 2, SSE, Md)
     /* NP 0F AE /3: STMXCSR m32 */
-    INSN_GRPMEMB_W(grp15_LEG_NP, stmxcsr, 3, SSE, Md)
+    /* FIXME this is hacked, should be INSN_GRPMEMB_W */
+    INSN_GRPMEMB_R(grp15_LEG_NP, stmxcsr, 3, SSE, Md)
 INSN_GRP_END(grp15_LEG_NP)
 
 INSN_GRP(grp16_LEG_NP, LEG(NP, 0F, 0), 0x18)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (38 preceding siblings ...)
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 39/39] target/i386: introduce memory-pointer operand read/write workarounds Jan Bobek
@ 2019-08-10  4:44 ` no-reply
  2019-08-10 23:35 ` Richard Henderson
  40 siblings, 0 replies; 60+ messages in thread
From: no-reply @ 2019-08-10  4:44 UTC (permalink / raw)
  To: jan.bobek; +Cc: alex.bennee, richard.henderson, jan.bobek, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190810041255.6820-1-jan.bobek@gmail.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation
Message-id: 20190810041255.6820-1-jan.bobek@gmail.com
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1565232570-29296-1-git-send-email-bmeng.cn@gmail.com -> patchew/1565232570-29296-1-git-send-email-bmeng.cn@gmail.com
 - [tag update]      patchew/1565335544-23584-1-git-send-email-bmeng.cn@gmail.com -> patchew/1565335544-23584-1-git-send-email-bmeng.cn@gmail.com
 - [tag update]      patchew/20190806165429.19327-1-brijesh.singh@amd.com -> patchew/20190806165429.19327-1-brijesh.singh@amd.com
 - [tag update]      patchew/20190808164117.23348-1-alex.bennee@linaro.org -> patchew/20190808164117.23348-1-alex.bennee@linaro.org
 - [tag update]      patchew/20190809091940.1223-1-alex.bennee@linaro.org -> patchew/20190809091940.1223-1-alex.bennee@linaro.org
 - [tag update]      patchew/20190809154153.31763-1-richard.henderson@linaro.org -> patchew/20190809154153.31763-1-richard.henderson@linaro.org
 * [new tag]         patchew/20190810041255.6820-1-jan.bobek@gmail.com -> patchew/20190810041255.6820-1-jan.bobek@gmail.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' (https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' (https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out '22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out '90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 'ba1ab360eebe6338bb8d7d83a9220ccf7e213af3'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out '20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' (https://github.com/openssl/openssl) registered for path 'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out '50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography': checked out '09403100de2f6f1cdd0d484dcb8e620f1c335c8f'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out 'de4565cbe76ea9f7913a01f331be3ee901bb6e17'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out 'c79e0ecb84f4f1ee3f73f521622e264edd1bf174'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/opensbi'...
Submodule path 'roms/opensbi': checked out 'ce228ee0919deb9957192d723eecc8aaae2697c6'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out 'bf0e13698872450164fa7040da36a95d2d4b326f'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out 'a5cab58e9a3fb6e168aba919c5669bea406573b4'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out '0f4fe84658165e96ce35870fd19fc634e182e77b'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out '261ca8e779e5138869a45f174caa49be6a274501'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 'd3689267f92c5956e09cc7d1baa4700141662bff'
Cloning into 'roms/u-boot-sam460ex'...
Submodule path 'roms/u-boot-sam460ex': checked out '60b3916f33e617a815973c5a6df77055b2e3a588'
Cloning into 'slirp'...
Submodule path 'slirp': checked out '126c04acbabd7ad32c2b018fe10dfac2a3bc1210'
Cloning into 'tests/fp/berkeley-softfloat-3'...
Submodule path 'tests/fp/berkeley-softfloat-3': checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'tests/fp/berkeley-testfloat-3'...
Submodule path 'tests/fp/berkeley-testfloat-3': checked out '5a59dcec19327396a011a17fd924aed4fec416b3'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
04e3211 target/i386: introduce memory-pointer operand read/write workarounds
887dd17 target/i386: introduce SSE instructions to insn.h
a0c5752 target/i386: introduce SSE code generators
858e3c5 target/i386: introduce SSE translators
5406d1f target/i386: introduce UdqMq operand
e4cdf59 target/i386: introduce V*, U*, W* (SSE/AVX) operands
7444e6d target/i386: introduce MMX instructions to insn.h
da28d62 target/i386: introduce MMX code generators
94dc39a target/i386: introduce MMX translators
ba278a5 target/i386: introduce gvec-based code generator macros
79af504 target/i386: introduce helper-based code generator macros
09fa8db target/i386: introduce P*, N*, Q* (MMX) operands
bb71c26 target/i386: introduce RdMw operand
118d273 target/i386: introduce G*, R*, E* (general register) operands
ba3f6d7 target/i386: introduce M* (memptr) operands
f3c2db4 target/i386: introduce Ib (immediate) operand
62f91f7 target/i386: introduce instruction translator macros
9b08111 target/i386: introduce code generators
1f3c49c target/i386: introduce insn.h
e585f94 target/i386: introduce generic load-store operand
5c2d1fe target/i386: introduce generic operand alias
d0acbb3 target/i386: introduce modifier for direct-only operand decoding
851452a target/i386: introduce helpers for decoding modrm fields
11aa099 target/i386: introduce instruction operand infrastructure
caf31ee target/i386: introduce function ck_cpuid
0eb2363 target/i386: introduce mnemonic aliases for several gvec operations
7b7f4a4 target/i386: disable unused function warning temporarily
065a819 target/i386: introduce gen_sse_ng
7388055 target/i386: introduce gen_(ld, st)d_env_A0
2b3eda7 target/i386: add vector register file alignment constraints
ad5da8c target/i386: make variable is_xmm const
76dbe83 target/i386: make variable b1 const
82b90e5 target/i386: use pc_start from DisasContext
b84b85a target/i386: Simplify gen_exception arguments
6957a05 target/i386: use prefix from DisasContext
65c1b82 target/i386: use dflag from DisasContext
e4bb0c7 target/i386: reduce scope of variable aflag
7f9aa75 target/i386: Push rex_w into DisasContext
9ffb757 target/i386: Push rex_r into DisasContext

=== OUTPUT BEGIN ===
1/39 Checking commit 9ffb757ff5c8 (target/i386: Push rex_r into DisasContext)
2/39 Checking commit 7f9aa75cf627 (target/i386: Push rex_w into DisasContext)
3/39 Checking commit e4bb0c7a0fc4 (target/i386: reduce scope of variable aflag)
4/39 Checking commit 65c1b822caba (target/i386: use dflag from DisasContext)
5/39 Checking commit 6957a05b4bca (target/i386: use prefix from DisasContext)
6/39 Checking commit b84b85a62db1 (target/i386: Simplify gen_exception arguments)
7/39 Checking commit 82b90e53d4a4 (target/i386: use pc_start from DisasContext)
WARNING: line over 80 characters
#64: FILE: target/i386/translate.c:6387:
+            gen_repz_scas(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 1);

WARNING: line over 80 characters
#67: FILE: target/i386/translate.c:6389:
+            gen_repz_scas(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 0);

WARNING: line over 80 characters
#76: FILE: target/i386/translate.c:6399:
+            gen_repz_cmps(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 1);

WARNING: line over 80 characters
#79: FILE: target/i386/translate.c:6401:
+            gen_repz_cmps(s, ot, s->pc_start - s->cs_base, s->pc - s->cs_base, 0);

WARNING: line over 80 characters
#197: FILE: target/i386/translate.c:7062:
+        gen_interrupt(s, EXCP03_INT3, s->pc_start - s->cs_base, s->pc - s->cs_base);

ERROR: line over 90 characters
#483: FILE: target/i386/translate.c:7693:
+            gen_svm_check_intercept(s, s->pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);

WARNING: line over 80 characters
#501: FILE: target/i386/translate.c:8090:
+                gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_WRITE_DR0 + reg);

WARNING: line over 80 characters
#509: FILE: target/i386/translate.c:8097:
+                gen_svm_check_intercept(s, s->pc_start, SVM_EXIT_READ_DR0 + reg);

total: 1 errors, 7 warnings, 464 lines checked

Patch 7/39 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

8/39 Checking commit 76dbe834b68d (target/i386: make variable b1 const)
9/39 Checking commit ad5da8ce24e9 (target/i386: make variable is_xmm const)
10/39 Checking commit 2b3eda73bd32 (target/i386: add vector register file alignment constraints)
11/39 Checking commit 7388055473c0 (target/i386: introduce gen_(ld, st)d_env_A0)
12/39 Checking commit 065a819bc768 (target/i386: introduce gen_sse_ng)
13/39 Checking commit 7b7f4a4bc38e (target/i386: disable unused function warning temporarily)
14/39 Checking commit 0eb2363cd44c (target/i386: introduce mnemonic aliases for several gvec operations)
15/39 Checking commit caf31eefbce8 (target/i386: introduce function ck_cpuid)
16/39 Checking commit 11aa0990bcc5 (target/i386: introduce instruction operand infrastructure)
ERROR: spaces required around that '*' (ctx:WxV)
#35: FILE: target/i386/translate.c:4560:
+                                int modrm, insnop_t(opT) *op)      \
                                                          ^

ERROR: spaces required around that '*' (ctx:WxV)
#41: FILE: target/i386/translate.c:4566:
+                                    int modrm, insnop_t(opT) *op)       \
                                                              ^

ERROR: spaces required around that '*' (ctx:WxV)
#47: FILE: target/i386/translate.c:4572:
+                                     int modrm, insnop_t(opT) *op)      \
                                                               ^

total: 3 errors, 0 warnings, 47 lines checked

Patch 16/39 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

17/39 Checking commit 851452a3a801 (target/i386: introduce helpers for decoding modrm fields)
18/39 Checking commit d0acbb315247 (target/i386: introduce modifier for direct-only operand decoding)
19/39 Checking commit 5c2d1fec9e5d (target/i386: introduce generic operand alias)
20/39 Checking commit e585f948be20 (target/i386: introduce generic load-store operand)
21/39 Checking commit 1f3c49c0e649 (target/i386: introduce insn.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

WARNING: line over 80 characters
#82: FILE: target/i386/insn.h:62:
+#   define INSN_GRPMEMB_WRRR(grpname, mnem, opcode, feat, opW1, opR1, opR2, opR3)

total: 0 errors, 2 warnings, 87 lines checked

Patch 21/39 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
22/39 Checking commit 9b081118d7bd (target/i386: introduce code generators)
23/39 Checking commit 62f91f70636c (target/i386: introduce instruction translator macros)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#187: FILE: target/i386/translate.c:4882:
+#define INSN_GRPMEMB(grpname, mnem, opcode, feat) \
+        case opcode:                              \
+            translate_insn(                       \
+                env, s, CK_CPUID_ ## feat,        \
+                gen_insn(mnem));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#193: FILE: target/i386/translate.c:4888:
+#define INSN_GRPMEMB_R(grpname, mnem, opcode, feat, opR1) \
+        case opcode:                                      \
+            translate_insn_r(opR1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,         \
+                gen_insn_r(mnem, opR1));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#199: FILE: target/i386/translate.c:4894:
+#define INSN_GRPMEMB_RR(grpname, mnem, opcode, feat, opR1, opR2) \
+        case opcode:                                             \
+            translate_insn_rr(opR1, opR2)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                \
+                gen_insn_rr(mnem, opR1, opR2));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#205: FILE: target/i386/translate.c:4900:
+#define INSN_GRPMEMB_W(grpname, mnem, opcode, feat, opW1) \
+        case opcode:                                      \
+            translate_insn_w(opW1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,         \
+                gen_insn_w(mnem, opW1));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#211: FILE: target/i386/translate.c:4906:
+#define INSN_GRPMEMB_WR(grpname, mnem, opcode, feat, opW1, opR1) \
+        case opcode:                                             \
+            translate_insn_wr(opW1, opR1)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                \
+                gen_insn_wr(mnem, opW1, opR1));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#217: FILE: target/i386/translate.c:4912:
+#define INSN_GRPMEMB_WRR(grpname, mnem, opcode, feat, opW1, opR1, opR2) \
+        case opcode:                                                    \
+            translate_insn_wrr(opW1, opR1, opR2)(                       \
+                env, s, modrm, CK_CPUID_ ## feat,                       \
+                gen_insn_wrr(mnem, opW1, opR1, opR2));                  \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#223: FILE: target/i386/translate.c:4918:
+#define INSN_GRPMEMB_WRRR(grpname, mnem, opcode, feat, opW1, opR1, opR2, opR3) \
+        case opcode:                                                    \
+            translate_insn_wrrr(opW1, opR1, opR2, opR3)(                \
+                env, s, modrm, CK_CPUID_ ## feat,                       \
+                gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3));           \
+            return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#229: FILE: target/i386/translate.c:4924:
+#define INSN_GRP_END(grpname)                   \
+        default:                                \
+            gen_illegal_opcode(s);              \
+            return;                             \
+        }                                       \
+                                                \
+        g_assert_not_reached();                 \
+    }

ERROR: spaces required around that ':' (ctx:VxE)
#230: FILE: target/i386/translate.c:4925:
+        default:                                \
                ^

ERROR: Macros with complex values should be enclosed in parenthesis
#254: FILE: target/i386/translate.c:4953:
+#define CASES_LEG_NP_0F_W0(opcode)              \
+    case opcode | M_0F | W_0:

ERROR: Macros with complex values should be enclosed in parenthesis
#256: FILE: target/i386/translate.c:4955:
+#define CASES_LEG_NP_0F_W1(opcode)              \
+    case opcode | M_0F | W_1:

ERROR: Macros with complex values should be enclosed in parenthesis
#258: FILE: target/i386/translate.c:4957:
+#define CASES_LEG_F3_0F_W0(opcode)              \
+    case opcode | M_0F | P_F3 | W_0:

ERROR: Macros with complex values should be enclosed in parenthesis
#260: FILE: target/i386/translate.c:4959:
+#define CASES_LEG_F3_0F_W1(opcode)              \
+    case opcode | M_0F | P_F3 | W_1:

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#265: FILE: target/i386/translate.c:4964:
+#define INSN(mnem, cases, opcode, feat)         \
+    cases(opcode)                               \
+        translate_insn(                         \
+            env, s, CK_CPUID_ ## feat,          \
+            gen_insn(mnem));                    \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#271: FILE: target/i386/translate.c:4970:
+#define INSN_R(mnem, cases, opcode, feat, opR1)      \
+    cases(opcode)                                    \
+        modrm = x86_ldub_code(env, s);               \
+        translate_insn_r(opR1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,        \
+            gen_insn_r(mnem, opR1));                 \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#278: FILE: target/i386/translate.c:4977:
+#define INSN_RR(mnem, cases, opcode, feat, opR1, opR2)       \
+    cases(opcode)                                            \
+        modrm = x86_ldub_code(env, s);                       \
+        translate_insn_rr(opR1, opR2)(                       \
+            env, s, modrm, CK_CPUID_ ## feat,                \
+            gen_insn_rr(mnem, opR1, opR2));                  \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#285: FILE: target/i386/translate.c:4984:
+#define INSN_W(mnem, cases, opcode, feat, opW1)       \
+    cases(opcode)                                     \
+        modrm = x86_ldub_code(env, s);                \
+        translate_insn_wr(opW1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,         \
+            gen_insn_wr(mnem, opW1));                 \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#292: FILE: target/i386/translate.c:4991:
+#define INSN_WR(mnem, cases, opcode, feat, opW1, opR1)      \
+    cases(opcode)                                           \
+        modrm = x86_ldub_code(env, s);                      \
+        translate_insn_wr(opW1, opR1)(                      \
+            env, s, modrm, CK_CPUID_ ## feat,               \
+            gen_insn_wr(mnem, opW1, opR1));                 \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#299: FILE: target/i386/translate.c:4998:
+#define INSN_WRR(mnem, cases, opcode, feat, opW1, opR1, opR2)       \
+    cases(opcode)                                                   \
+        modrm = x86_ldub_code(env, s);                              \
+        translate_insn_wrr(opW1, opR1, opR2)(                       \
+            env, s, modrm, CK_CPUID_ ## feat,                       \
+            gen_insn_wrr(mnem, opW1, opR1, opR2));                  \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#306: FILE: target/i386/translate.c:5005:
+#define INSN_WRRR(mnem, cases, opcode, feat, opW1, opR1, opR2, opR3)    \
+    cases(opcode)                                                   \
+        modrm = x86_ldub_code(env, s);                              \
+        translate_insn_wrrr(opW1, opR1, opR2, opR3)(                \
+            env, s, modrm, CK_CPUID_ ## feat,                       \
+            gen_insn_wrrr(mnem, opW1, opR1, opR2, opR3));           \
+        return;

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#313: FILE: target/i386/translate.c:5012:
+#define INSN_GRP(grpname, cases, opcode)                \
+    cases(opcode)                                       \
+        modrm = x86_ldub_code(env, s);                  \
+        translate_group(grpname)(env, s, modrm);        \
+        return;

total: 21 errors, 0 warnings, 309 lines checked

Patch 23/39 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

24/39 Checking commit f3c2db48a44b (target/i386: introduce Ib (immediate) operand)
25/39 Checking commit ba3f6d7b1968 (target/i386: introduce M* (memptr) operands)
26/39 Checking commit 118d273fcee6 (target/i386: introduce G*, R*, E* (general register) operands)
27/39 Checking commit bb71c265978f (target/i386: introduce RdMw operand)
28/39 Checking commit 09fa8dbff00a (target/i386: introduce P*, N*, Q* (MMX) operands)
29/39 Checking commit 79af504812e8 (target/i386: introduce helper-based code generator macros)
30/39 Checking commit ba278a5bc345 (target/i386: introduce gvec-based code generator macros)
31/39 Checking commit 94dc39a1e46f (target/i386: introduce MMX translators)
32/39 Checking commit da28d6295f87 (target/i386: introduce MMX code generators)
33/39 Checking commit 7444e6d9e560 (target/i386: introduce MMX instructions to insn.h)
34/39 Checking commit e4cdf59a44a5 (target/i386: introduce V*, U*, W* (SSE/AVX) operands)
35/39 Checking commit 5406d1ff66b3 (target/i386: introduce UdqMq operand)
36/39 Checking commit 858e3c56faa7 (target/i386: introduce SSE translators)
37/39 Checking commit a0c5752663d6 (target/i386: introduce SSE code generators)
38/39 Checking commit 887dd17910dc (target/i386: introduce SSE instructions to insn.h)
39/39 Checking commit 04e3211a003f (target/i386: introduce memory-pointer operand read/write workarounds)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190810041255.6820-1-jan.bobek@gmail.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation
  2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
                   ` (39 preceding siblings ...)
  2019-08-10  4:44 ` [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation no-reply
@ 2019-08-10 23:35 ` Richard Henderson
  2019-08-11 15:49   ` Jan Bobek
  40 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2019-08-10 23:35 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/9/19 9:12 PM, Jan Bobek wrote:
> This is a v2 of the patch series posted in [1]. Patches 1-9 are just
> cleanups; patches 10-39 are something actually interesting. Compared
> to v1, I started using preprocessor more extensively to generate
> repetitive boilerplate code; opinions/alternatives are welcome and
> appreciated.

This is tricky.  I'm not keen on code entirely expanded via macros because it
becomes extremely difficult to debug.  All statements get recorded at the same
line of the location of the expansion, which makes the gdb "step" command
finish the entire function because there is no next line.

Once upon a time I wrote some code that's extremely macro crazy:

https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=soft-fp/op-common.h;hb=HEAD

It has been extremely difficult to maintain over the years.

We have just recently gotten rid of some of the macros in the softmmu code

https://patchwork.ozlabs.org/project/qemu-devel/list/?series=105441

replacing most of them with inline functions.

A lot of what you have needs very little adjustment to address the debugging
problem.  E.g.

> +#define INSNOP_INIT(opT, init_stmt)                                \
> +    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
> +                                int modrm, insnop_t(opT) *op)      \
> +    {                                                              \
> +        init_stmt;                                                 \
> +    }
....
> +INSNOP(
> +    M, TCGv,
> +    do {
> +        if (decode_modrm_mod(env, s, modrm) == 3) {
> +            INSNOP_INIT_FAIL;
> +        } else {
> +            INSNOP_INIT_OK(s->A0);
> +        }
> +    } while (0),
> +    do {
> +        assert(*op == s->A0);
> +        gen_lea_modrm(env, s, modrm);
> +    } while (0),
> +    INSNOP_FINALIZE_NOOP)

Rearrange this as

#define INSNOP_INIT(OPT) \
    static bool insnop_##OPT##_init(CPUX86State *env, DisasContext *s, \
                                    int modrm, insnop_##OPT##_t *op)

#define INSNOP_PREPARE(OPT) \
    static void insnop_##OPT##_prepare(CPUX86State *env, DisasContext *s, \
                                       int modrm, insnop_##OPT##_t *op)

INSNOP_INIT(M)
{
    if (decode_modrm_mod(env, s, modrm) == 3) {
        INSNOP_INIT_FAIL;
    } else {
        INSNOP_INIT_OK(s->A0);
    }
}

INSNOP_PREPARE(M)
{
    assert(*op == s->A0);
    gen_lea_modrm(env, s, modrm);
}

etc and suddenly the entire expansion does not occur on a single line.

Further specific commentary to follow.


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation
  2019-08-10 23:35 ` Richard Henderson
@ 2019-08-11 15:49   ` Jan Bobek
  0 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-11 15:49 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Alex Bennée


[-- Attachment #1.1: Type: text/plain, Size: 3368 bytes --]

On 8/10/19 7:35 PM, Richard Henderson wrote:
> On 8/9/19 9:12 PM, Jan Bobek wrote:
>> This is a v2 of the patch series posted in [1]. Patches 1-9 are just
>> cleanups; patches 10-39 are something actually interesting. Compared
>> to v1, I started using preprocessor more extensively to generate
>> repetitive boilerplate code; opinions/alternatives are welcome and
>> appreciated.
> 
> This is tricky.  I'm not keen on code entirely expanded via macros because it
> becomes extremely difficult to debug.  All statements get recorded at the same
> line of the location of the expansion, which makes the gdb "step" command
> finish the entire function because there is no next line.
> 
> Once upon a time I wrote some code that's extremely macro crazy:
> 
> https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=soft-fp/op-common.h;hb=HEAD
> 
> It has been extremely difficult to maintain over the years.

Thank you, that's exactly the feedback I'm looking for! I've played
with the preprocessor in the past just to try out what's possible, but
I've never maintained code that uses it as extensively as this
series. It didn't occur to me that there would be a problem with
stepping it in gdb, for example, but now it seems obvious.

> We have just recently gotten rid of some of the macros in the softmmu code
> 
> https://patchwork.ozlabs.org/project/qemu-devel/list/?series=105441
> 
> replacing most of them with inline functions.

I'll have to look at it and see how exactly it's done; perhaps I'll
find something that's applicable to my case, too.

> A lot of what you have needs very little adjustment to address the debugging
> problem.  E.g.
> 
>> +#define INSNOP_INIT(opT, init_stmt)                                \
>> +    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
>> +                                int modrm, insnop_t(opT) *op)      \
>> +    {                                                              \
>> +        init_stmt;                                                 \
>> +    }
> ....
>> +INSNOP(
>> +    M, TCGv,
>> +    do {
>> +        if (decode_modrm_mod(env, s, modrm) == 3) {
>> +            INSNOP_INIT_FAIL;
>> +        } else {
>> +            INSNOP_INIT_OK(s->A0);
>> +        }
>> +    } while (0),
>> +    do {
>> +        assert(*op == s->A0);
>> +        gen_lea_modrm(env, s, modrm);
>> +    } while (0),
>> +    INSNOP_FINALIZE_NOOP)
> 
> Rearrange this as
> 
> #define INSNOP_INIT(OPT) \
>     static bool insnop_##OPT##_init(CPUX86State *env, DisasContext *s, \
>                                     int modrm, insnop_##OPT##_t *op)
> 
> #define INSNOP_PREPARE(OPT) \
>     static void insnop_##OPT##_prepare(CPUX86State *env, DisasContext *s, \
>                                        int modrm, insnop_##OPT##_t *op)
> 
> INSNOP_INIT(M)
> {
>     if (decode_modrm_mod(env, s, modrm) == 3) {
>         INSNOP_INIT_FAIL;
>     } else {
>         INSNOP_INIT_OK(s->A0);
>     }
> }
> 
> INSNOP_PREPARE(M)
> {
>     assert(*op == s->A0);
>     gen_lea_modrm(env, s, modrm);
> }
> 
> etc and suddenly the entire expansion does not occur on a single line.

That makes complete sense, thank you! I'll keep the debugging issue in
mind.

> Further specific commentary to follow.

Looking forward to it!

-Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext Jan Bobek
@ 2019-08-13  4:47   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:47 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> The variable pc_start is already a member of DisasContext. Remove the
> superfluous local variable.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 131 ++++++++++++++++++++--------------------
>  1 file changed, 65 insertions(+), 66 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag Jan Bobek
@ 2019-08-13  4:47   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:47 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée, Richard Henderson

On 8/10/19 5:12 AM, Jan Bobek wrote:
> The variable aflag is not used in most of disas_insn; make this clear
> by explicitly reducing its scope to the block where it is used.
> 
> Suggested-by: Richard Henderson <rth@twiddle.net>
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext Jan Bobek
@ 2019-08-13  4:48   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:48 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée, Richard Henderson

On 8/10/19 5:12 AM, Jan Bobek wrote:
> There already is a variable dflag in DisasContext, so reduce the scope
> of the local variable dflag to enforce use of the one in DisasContext.
> 
> Suggested-by: Richard Henderson <rth@twiddle.net>
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 184 ++++++++++++++++++++--------------------
>  1 file changed, 92 insertions(+), 92 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix from DisasContext
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix " Jan Bobek
@ 2019-08-13  4:48   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:48 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> Reduce scope of the local variable prefixes to enforce use of prefix
> from DisasContext instead.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 113 ++++++++++++++++++++--------------------
>  1 file changed, 57 insertions(+), 56 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const Jan Bobek
@ 2019-08-13  4:49   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:49 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> The variable b1 does not change value once assigned. Make this fact
> explicit by marking it const.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const Jan Bobek
@ 2019-08-13  4:52   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:52 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> The variable is_xmm does not change value after assignment, so make
> this fact explicit by marking it const.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0 Jan Bobek
@ 2019-08-13  4:56   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  4:56 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> Similar in spirit to the already present gen_(ld,st)(q,o)_env_A0, it
> will prove useful in later commits for smaller-sized vector loads.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng Jan Bobek
@ 2019-08-13  5:00   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  5:00 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> This function serves as the point-of-intercept for all newly
> implemented instructions. If no new implementation exists, fall back
> to gen_sse.
> 
> Note: This changeset is intended for development only and shall not be
> included in the final patch series.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)

Actually, I think this is a nice preparatory patch and should be included.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations Jan Bobek
@ 2019-08-13  5:01   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  5:01 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> It is helpful to introduce aliases for some general gvec operations as
> it makes a couple of instruction code generators simpler (added
> later).
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/translate.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/target/i386/translate.c b/target/i386/translate.c
> index 23550a21d3..03b49411e5 100644
> --- a/target/i386/translate.c
> +++ b/target/i386/translate.c
> @@ -4493,6 +4493,13 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
>  #pragma GCC diagnostic push
>  #pragma GCC diagnostic ignored "-Wunused-function"
>  
> +#define tcg_gen_gvec_andn(vece, dofs, aofs, bofs, oprsz, maxsz) \
> +    tcg_gen_gvec_andc(vece, dofs, bofs, aofs, oprsz, maxsz)
> +#define tcg_gen_gvec_cmpeq(vece, dofs, aofs, bofs, oprsz, maxsz)        \
> +    tcg_gen_gvec_cmp(TCG_COND_EQ, vece, dofs, aofs, bofs, oprsz, maxsz)
> +#define tcg_gen_gvec_cmpgt(vece, dofs, aofs, bofs, oprsz, maxsz)        \
> +    tcg_gen_gvec_cmp(TCG_COND_GT, vece, dofs, aofs, bofs, oprsz, maxsz)
> +
>  static void gen_sse_ng(CPUX86State *env, DisasContext *s, int b)
>  {
>      enum {
> 

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid Jan Bobek
@ 2019-08-13  5:07   ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  5:07 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> +enum {
> +    CK_CPUID_MMX = 1,
> +    CK_CPUID_3DNOW,
> +    CK_CPUID_SSE,
> +    CK_CPUID_SSE2,
> +    CK_CPUID_SSE3,
> +    CK_CPUID_SSSE3,
> +    CK_CPUID_SSE4_1,
> +    CK_CPUID_SSE4_2,
> +    CK_CPUID_SSE4A,
> +    CK_CPUID_AVX,
> +    CK_CPUID_AVX2,
> +};

Name the enumeration,

> +static int ck_cpuid(CPUX86State *env, DisasContext *s, int ck_cpuid_feat)

and use it in the parameter.  Return bool and true on success.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h Jan Bobek
@ 2019-08-13  6:00   ` Richard Henderson
  2019-08-15  0:55     ` Jan Bobek
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  6:00 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> This header is intended to eventually list all supported instructions
> along with some useful details (e.g. mnemonics, opcode, operands etc.)
> It shall be used (along with some preprocessor magic) anytime we need
> to automatically generate code for every instruction.
> 
> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
> ---
>  target/i386/insn.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
>  create mode 100644 target/i386/insn.h

Things that are included multiple times should be named *.inc.h.  There are
quite a few that don't follow this in the tree, but we are slowly fixing those.

Though even "insn.inc.h" isn't particularly descriptive, and definitely
overstates the case.  Maybe sse-opcode.inc.h?  While it's not only sse, it is
used by gen_sse_ng().


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure Jan Bobek
@ 2019-08-13  6:07   ` Richard Henderson
  2019-08-15  0:00     ` Jan Bobek
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  6:07 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> +#define INSNOP_INIT(opT, init_stmt)                                \
> +    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
> +                                int modrm, insnop_t(opT) *op)      \
> +    {                                                              \
> +        init_stmt;                                                 \
> +    }
...
> +#define INSNOP_INIT_FAIL        return 1
> +#define INSNOP_INIT_OK(x)       return ((*(op) = (x)), 0)

Return bool and true on success.


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros
  2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros Jan Bobek
@ 2019-08-13  6:30   ` Richard Henderson
  2019-08-15  0:51     ` Jan Bobek
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Henderson @ 2019-08-13  6:30 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/10/19 5:12 AM, Jan Bobek wrote:
> +#define CASES_LEG_NP_0F_W0(opcode)              \
> +    case opcode | M_0F | W_0:
> +#define CASES_LEG_NP_0F_W1(opcode)              \
> +    case opcode | M_0F | W_1:
> +#define CASES_LEG_F3_0F_W0(opcode)              \
> +    case opcode | M_0F | P_F3 | W_0:
> +#define CASES_LEG_F3_0F_W1(opcode)              \
> +    case opcode | M_0F | P_F3 | W_1:
> +
> +#define LEG(p, m, w)                            \
> +    CASES_LEG_ ## p ## _ ## m ## _W ## w
> +#define INSN(mnem, cases, opcode, feat)         \
> +    cases(opcode)                               \

It appears as if you don't need the CASES_* macros here.

#define LEG(p, m, w, op) \
   case P_##p | M_##m | W_##2 | op

#define INSN(mnem, leg, feat) \
   leg: translate_insn(env, s, CK_CPUID_##feat, gen_insn(mnem));

so long as P_NP is in the enumeration above with value 0.

Unless there's some other reason that opcode needs to stay separate?


r~


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure
  2019-08-13  6:07   ` Richard Henderson
@ 2019-08-15  0:00     ` Jan Bobek
  2019-08-15  9:09       ` Richard Henderson
  0 siblings, 1 reply; 60+ messages in thread
From: Jan Bobek @ 2019-08-15  0:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Alex Bennée


[-- Attachment #1.1: Type: text/plain, Size: 1047 bytes --]

On 8/13/19 2:07 AM, Richard Henderson wrote:
> On 8/10/19 5:12 AM, Jan Bobek wrote:
>> +#define INSNOP_INIT(opT, init_stmt)                                \
>> +    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
>> +                                int modrm, insnop_t(opT) *op)      \
>> +    {                                                              \
>> +        init_stmt;                                                 \
>> +    }
> ...
>> +#define INSNOP_INIT_FAIL        return 1
>> +#define INSNOP_INIT_OK(x)       return ((*(op) = (x)), 0)
> 
> Return bool and true on success.

So, the reason why I did this "inverted" logic (0 = success, 1 =
failure) is because I was anticipating I might need to differentiate
between two or more different failures, in which case returning
different non-zero values for different error cases makes perfect
sense. I have not made use of it yet, but I'd rather hold on to this
idiom at least for now, until I am 100 % sure it really is
unnecessary.

-Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros
  2019-08-13  6:30   ` Richard Henderson
@ 2019-08-15  0:51     ` Jan Bobek
  0 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-15  0:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Alex Bennée


[-- Attachment #1.1: Type: text/plain, Size: 1380 bytes --]

On 8/13/19 2:30 AM, Richard Henderson wrote:
> On 8/10/19 5:12 AM, Jan Bobek wrote:
>> +#define CASES_LEG_NP_0F_W0(opcode)              \
>> +    case opcode | M_0F | W_0:
>> +#define CASES_LEG_NP_0F_W1(opcode)              \
>> +    case opcode | M_0F | W_1:
>> +#define CASES_LEG_F3_0F_W0(opcode)              \
>> +    case opcode | M_0F | P_F3 | W_0:
>> +#define CASES_LEG_F3_0F_W1(opcode)              \
>> +    case opcode | M_0F | P_F3 | W_1:
>> +
>> +#define LEG(p, m, w)                            \
>> +    CASES_LEG_ ## p ## _ ## m ## _W ## w
>> +#define INSN(mnem, cases, opcode, feat)         \
>> +    cases(opcode)                               \
> 
> It appears as if you don't need the CASES_* macros here.
> 
> #define LEG(p, m, w, op) \
>    case P_##p | M_##m | W_##2 | op
> 
> #define INSN(mnem, leg, feat) \
>    leg: translate_insn(env, s, CK_CPUID_##feat, gen_insn(mnem));
> 
> so long as P_NP is in the enumeration above with value 0.
> 
> Unless there's some other reason that opcode needs to stay separate?

I was thinking ahead with the CASES_* macros here: if I have LIG
and/or WIG in the VEX prefix, I'll need more than one case label,
but only one label in other cases. However, that's not a reason
for the opcode to be separate, and I think I like it stashed with
the rest of the prefix fields better.

-Jan
 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h
  2019-08-13  6:00   ` Richard Henderson
@ 2019-08-15  0:55     ` Jan Bobek
  0 siblings, 0 replies; 60+ messages in thread
From: Jan Bobek @ 2019-08-15  0:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Alex Bennée


[-- Attachment #1.1: Type: text/plain, Size: 1031 bytes --]

On 8/13/19 2:00 AM, Richard Henderson wrote:
> On 8/10/19 5:12 AM, Jan Bobek wrote:
>> This header is intended to eventually list all supported instructions
>> along with some useful details (e.g. mnemonics, opcode, operands etc.)
>> It shall be used (along with some preprocessor magic) anytime we need
>> to automatically generate code for every instruction.
>>
>> Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
>> ---
>>  target/i386/insn.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 87 insertions(+)
>>  create mode 100644 target/i386/insn.h
> 
> Things that are included multiple times should be named *.inc.h.  There are
> quite a few that don't follow this in the tree, but we are slowly fixing those.
> 
> Though even "insn.inc.h" isn't particularly descriptive, and definitely
> overstates the case.  Maybe sse-opcode.inc.h?  While it's not only sse, it is
> used by gen_sse_ng().

"sse-opcode.inc.h" isn't 100 % as you point out, but looks good enough for now.

-Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure
  2019-08-15  0:00     ` Jan Bobek
@ 2019-08-15  9:09       ` Richard Henderson
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Henderson @ 2019-08-15  9:09 UTC (permalink / raw)
  To: Jan Bobek, qemu-devel; +Cc: Alex Bennée

On 8/15/19 1:00 AM, Jan Bobek wrote:
> On 8/13/19 2:07 AM, Richard Henderson wrote:
>> On 8/10/19 5:12 AM, Jan Bobek wrote:
>>> +#define INSNOP_INIT(opT, init_stmt)                                \
>>> +    static int insnop_init(opT)(CPUX86State *env, DisasContext *s, \
>>> +                                int modrm, insnop_t(opT) *op)      \
>>> +    {                                                              \
>>> +        init_stmt;                                                 \
>>> +    }
>> ...
>>> +#define INSNOP_INIT_FAIL        return 1
>>> +#define INSNOP_INIT_OK(x)       return ((*(op) = (x)), 0)
>>
>> Return bool and true on success.
> 
> So, the reason why I did this "inverted" logic (0 = success, 1 =
> failure) is because I was anticipating I might need to differentiate
> between two or more different failures, in which case returning
> different non-zero values for different error cases makes perfect
> sense. I have not made use of it yet, but I'd rather hold on to this
> idiom at least for now, until I am 100 % sure it really is
> unnecessary.

In that case "int" still isn't the best return type -- an enumeration would be.


r~



^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2019-08-15  9:10 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-10  4:12 [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 01/39] target/i386: Push rex_r into DisasContext Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 02/39] target/i386: Push rex_w " Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 03/39] target/i386: reduce scope of variable aflag Jan Bobek
2019-08-13  4:47   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 04/39] target/i386: use dflag from DisasContext Jan Bobek
2019-08-13  4:48   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 05/39] target/i386: use prefix " Jan Bobek
2019-08-13  4:48   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 06/39] target/i386: Simplify gen_exception arguments Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 07/39] target/i386: use pc_start from DisasContext Jan Bobek
2019-08-13  4:47   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 08/39] target/i386: make variable b1 const Jan Bobek
2019-08-13  4:49   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 09/39] target/i386: make variable is_xmm const Jan Bobek
2019-08-13  4:52   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 10/39] target/i386: add vector register file alignment constraints Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 11/39] target/i386: introduce gen_(ld, st)d_env_A0 Jan Bobek
2019-08-13  4:56   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 12/39] target/i386: introduce gen_sse_ng Jan Bobek
2019-08-13  5:00   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 13/39] target/i386: disable unused function warning temporarily Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 14/39] target/i386: introduce mnemonic aliases for several gvec operations Jan Bobek
2019-08-13  5:01   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 15/39] target/i386: introduce function ck_cpuid Jan Bobek
2019-08-13  5:07   ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 16/39] target/i386: introduce instruction operand infrastructure Jan Bobek
2019-08-13  6:07   ` Richard Henderson
2019-08-15  0:00     ` Jan Bobek
2019-08-15  9:09       ` Richard Henderson
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 17/39] target/i386: introduce helpers for decoding modrm fields Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 18/39] target/i386: introduce modifier for direct-only operand decoding Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 19/39] target/i386: introduce generic operand alias Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 20/39] target/i386: introduce generic load-store operand Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 21/39] target/i386: introduce insn.h Jan Bobek
2019-08-13  6:00   ` Richard Henderson
2019-08-15  0:55     ` Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 22/39] target/i386: introduce code generators Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 23/39] target/i386: introduce instruction translator macros Jan Bobek
2019-08-13  6:30   ` Richard Henderson
2019-08-15  0:51     ` Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 24/39] target/i386: introduce Ib (immediate) operand Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 25/39] target/i386: introduce M* (memptr) operands Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 26/39] target/i386: introduce G*, R*, E* (general register) operands Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 27/39] target/i386: introduce RdMw operand Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 28/39] target/i386: introduce P*, N*, Q* (MMX) operands Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 29/39] target/i386: introduce helper-based code generator macros Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 30/39] target/i386: introduce gvec-based " Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 31/39] target/i386: introduce MMX translators Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 32/39] target/i386: introduce MMX code generators Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 33/39] target/i386: introduce MMX instructions to insn.h Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 34/39] target/i386: introduce V*, U*, W* (SSE/AVX) operands Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 35/39] target/i386: introduce UdqMq operand Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 36/39] target/i386: introduce SSE translators Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 37/39] target/i386: introduce SSE code generators Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 38/39] target/i386: introduce SSE instructions to insn.h Jan Bobek
2019-08-10  4:12 ` [Qemu-devel] [RFC PATCH v2 39/39] target/i386: introduce memory-pointer operand read/write workarounds Jan Bobek
2019-08-10  4:44 ` [Qemu-devel] [RFC PATCH v2 00/39] rewrite MMX/SSE instruction translation no-reply
2019-08-10 23:35 ` Richard Henderson
2019-08-11 15:49   ` Jan Bobek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.