qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Hildenbrand <david@redhat.com>
To: qemu-devel@nongnu.org
Cc: qemu-s390x@nongnu.org, Thomas Huth <thuth@redhat.com>,
	Cornelia Huck <cohuck@redhat.com>,
	Richard Henderson <rth@twiddle.net>,
	David Hildenbrand <david@redhat.com>
Subject: [Qemu-devel] [PATCH v2 04/32] s390x/tcg: Implement VECTOR GATHER ELEMENT
Date: Fri,  1 Mar 2019 12:53:45 +0100	[thread overview]
Message-ID: <20190301115413.27153-5-david@redhat.com> (raw)
In-Reply-To: <20190301115413.27153-1-david@redhat.com>

Let's start with a more involved one, but it is the first in the list
of vector support instructions (introduced with the vector facility).

Good thing is, we need a lot of basic infrastructure for this. Reading
and writing vector elements as well as checking element validity.

All vector instruction related translation functions will reside in
translate_vx.inc.c, to be included in translate.c - similar to how
other architectures handle it.

While at it, directly add some documentation (which contains parts about
things added in follow-up patches, but splitting this up does not make
too much sense). Also add ES_* defines heavily used later.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/insn-data.def      |   6 ++
 target/s390x/translate.c        |   2 +
 target/s390x/translate_vx.inc.c | 135 ++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)
 create mode 100644 target/s390x/translate_vx.inc.c

diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 61b750a855..7d128ac9d6 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -972,6 +972,12 @@
     D(0xb93e, KIMD,    RRE,   MSA,  0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KIMD)
     D(0xb93f, KLMD,    RRE,   MSA,  0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KLMD)
 
+/* === Vector Support Instructions === */
+
+/* VECTOR GATHER ELEMENT */
+    E(0xe713, VGEF,    VRV,   V,   la2, 0, 0, 0, vge, 0, ES_32, IF_VEC)
+    E(0xe712, VGEG,    VRV,   V,   la2, 0, 0, 0, vge, 0, ES_64, IF_VEC)
+
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
     E(0xb250, CSP,     RRE,   Z,   r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL, IF_PRIV)
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index d52c02c572..a1c6698dea 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -5120,6 +5120,8 @@ static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
 }
 #endif
 
+#include "translate_vx.inc.c"
+
 /* ====================================================================== */
 /* The "Cc OUTput" generators.  Given the generated output (and in some cases
    the original inputs), update the various cc data structures in order to
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
new file mode 100644
index 0000000000..9864ec5134
--- /dev/null
+++ b/target/s390x/translate_vx.inc.c
@@ -0,0 +1,135 @@
+/*
+ * QEMU TCG support -- s390x vector instruction translation functions
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ *   David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * For most instructions that use the same element size for reads and
+ * writes, we can use real gvec vector expansion, which potantially uses
+ * real host vector instructions. As they only work up to 64 bit elements,
+ * 128 bit elements (vector is a single element) have to be handled
+ * differently. Operations that are too complicated to encode via TCG ops
+ * are handled via gvec ool (out-of-line) handlers.
+ *
+ * As soon as instructions use different element sizes for reads and writes
+ * or access elements "out of their element scope" we expand them manually
+ * in fancy loops, as gvec expansion does not deal with actual element
+ * numbers and does also not support access to other elements.
+ *
+ * 128 bit elements:
+ *  As we only have i32/i64, such elements have to be loaded into two
+ *  i64 values and can then be processed e.g. by tcg_gen_add2_i64.
+ *
+ * Sizes:
+ *  On s390x, the operand size (oprsz) and the maximum size (maxsz) are
+ *  always 16 (128 bit). What gvec code calls "vece", s390x calls "es",
+ *  a.k.a. "element size". These values nicely map to MO_8 ... MO_64. Only
+ *  128 bit element size has to be treated in a special way (MO_64 + 1).
+ *  We will use ES_* instead of MO_* for this reason in this file.
+ *
+ * CC handling:
+ *  As gvec ool-helpers can currently not return values (besides via
+ *  pointers like vectors or cpu_env), whenever we have to set the CC and
+ *  can't conclude the value from the result vector, we will directly
+ *  set it in "env->cc_op" and mark it as static via set_cc_static()".
+ *  Whenever this is done, the helper writes globals (cc_op).
+ */
+
+#define NUM_VEC_ELEMENT_BYTES(es) (1 << (es))
+#define NUM_VEC_ELEMENTS(es) (16 / NUM_VEC_ELEMENT_BYTES(es))
+
+#define ES_8    MO_8
+#define ES_16   MO_16
+#define ES_32   MO_32
+#define ES_64   MO_64
+#define ES_128  4
+
+static inline bool valid_vec_element(uint8_t enr, TCGMemOp es)
+{
+    return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
+}
+
+static void read_vec_element_i64(TCGv_i64 dst, uint8_t reg, uint8_t enr,
+                                 TCGMemOp memop)
+{
+    const int offs = vec_reg_offset(reg, enr, memop & MO_SIZE);
+
+    switch (memop) {
+    case ES_8:
+        tcg_gen_ld8u_i64(dst, cpu_env, offs);
+        break;
+    case ES_16:
+        tcg_gen_ld16u_i64(dst, cpu_env, offs);
+        break;
+    case ES_32:
+        tcg_gen_ld32u_i64(dst, cpu_env, offs);
+        break;
+    case ES_8 | MO_SIGN:
+        tcg_gen_ld8s_i64(dst, cpu_env, offs);
+        break;
+    case ES_16 | MO_SIGN:
+        tcg_gen_ld16s_i64(dst, cpu_env, offs);
+        break;
+    case ES_32 | MO_SIGN:
+        tcg_gen_ld32s_i64(dst, cpu_env, offs);
+        break;
+    case ES_64:
+    case ES_64 | MO_SIGN:
+        tcg_gen_ld_i64(dst, cpu_env, offs);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static void write_vec_element_i64(TCGv_i64 src, int reg, uint8_t enr,
+                                  TCGMemOp memop)
+{
+    const int offs = vec_reg_offset(reg, enr, memop & MO_SIZE);
+
+    switch (memop) {
+    case ES_8:
+        tcg_gen_st8_i64(src, cpu_env, offs);
+        break;
+    case ES_16:
+        tcg_gen_st16_i64(src, cpu_env, offs);
+        break;
+    case ES_32:
+        tcg_gen_st32_i64(src, cpu_env, offs);
+        break;
+    case ES_64:
+        tcg_gen_st_i64(src, cpu_env, offs);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static DisasJumpType op_vge(DisasContext *s, DisasOps *o)
+{
+    const uint8_t es = s->insn->data;
+    const uint8_t enr = get_field(s->fields, m3);
+    TCGv_i64 tmp;
+
+    if (!valid_vec_element(enr, es)) {
+        gen_program_exception(s, PGM_SPECIFICATION);
+        return DISAS_NORETURN;
+    }
+
+    tmp = tcg_temp_new_i64();
+    read_vec_element_i64(tmp, get_field(s->fields, v2), enr, es);
+    tcg_gen_add_i64(o->addr1, o->addr1, tmp);
+    gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 0);
+
+    tcg_gen_qemu_ld_i64(tmp, o->addr1, get_mem_index(s), MO_TE | es);
+    write_vec_element_i64(tmp, get_field(s->fields, v1), enr, es);
+    tcg_temp_free_i64(tmp);
+    return DISAS_NEXT;
+}
-- 
2.17.2

  parent reply	other threads:[~2019-03-01 11:54 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-01 11:53 [Qemu-devel] [PATCH v2 00/32] s390x/tcg: Vector Instruction Support Part 1 David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 01/32] s390x/tcg: Define vector instruction formats David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 02/32] s390x/tcg: Check vector register instructions at central point David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 03/32] s390x/tcg: Utilities for vector instruction helpers David Hildenbrand
2019-03-01 16:09   ` Richard Henderson
2019-03-01 16:13     ` David Hildenbrand
2019-03-01 16:16       ` Richard Henderson
2019-03-01 16:18         ` David Hildenbrand
2019-03-01 16:16       ` David Hildenbrand
2019-03-01 11:53 ` David Hildenbrand [this message]
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 05/32] s390x/tcg: Implement VECTOR GENERATE BYTE MASK David Hildenbrand
2019-03-01 16:11   ` Richard Henderson
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 06/32] s390x/tcg: Implement VECTOR GENERATE MASK David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 07/32] s390x/tcg: Implement VECTOR LOAD David Hildenbrand
2019-03-01 16:17   ` Richard Henderson
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 08/32] s390x/tcg: Implement VECTOR LOAD AND REPLICATE David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 09/32] s390x/tcg: Implement VECTOR LOAD ELEMENT David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 10/32] s390x/tcg: Implement VECTOR LOAD ELEMENT IMMEDIATE David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 11/32] s390x/tcg: Implement VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
2019-03-01 16:21   ` Richard Henderson
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 12/32] s390x/tcg: Implement VECTOR LOAD LOGICAL ELEMENT AND ZERO David Hildenbrand
2019-03-01 16:21   ` Richard Henderson
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 13/32] s390x/tcg: Implement VECTOR LOAD MULTIPLE David Hildenbrand
2019-03-01 16:26   ` Richard Henderson
2019-03-01 16:33     ` David Hildenbrand
2019-03-01 17:51   ` David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 14/32] s390x/tcg: Implement VECTOR LOAD TO BLOCK BOUNDARY David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 15/32] s390x/tcg: Implement VECTOR LOAD VR ELEMENT FROM GR David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 16/32] s390x/tcg: Implement VECTOR LOAD VR FROM GRS DISJOINT David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 17/32] s390x/tcg: Implement VECTOR LOAD WITH LENGTH David Hildenbrand
2019-03-01 11:53 ` [Qemu-devel] [PATCH v2 18/32] s390x/tcg: Implement VECTOR MERGE (HIGH|LOW) David Hildenbrand
2019-03-01 16:28   ` Richard Henderson
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 19/32] s390x/tcg: Implement VECTOR PACK * David Hildenbrand
2019-03-01 17:28   ` Richard Henderson
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 20/32] s390x/tcg: Implement VECTOR PERMUTE David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 21/32] s390x/tcg: Implement VECTOR PERMUTE DOUBLEWORD IMMEDIATE David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 22/32] s390x/tcg: Implement VECTOR REPLICATE David Hildenbrand
2019-03-01 17:35   ` Richard Henderson
2019-03-01 17:40     ` David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 23/32] s390x/tcg: Implement VECTOR REPLICATE IMMEDIATE David Hildenbrand
2019-03-01 17:35   ` Richard Henderson
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 24/32] s390x/tcg: Implement VECTOR SCATTER ELEMENT David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 25/32] s390x/tcg: Implement VECTOR SELECT David Hildenbrand
2019-03-01 17:37   ` Richard Henderson
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 26/32] s390x/tcg: Implement VECTOR SIGN EXTEND TO DOUBLEWORD David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 27/32] s390x/tcg: Provide probe_write helper David Hildenbrand
2019-03-01 17:54   ` Richard Henderson
2019-03-01 18:15     ` David Hildenbrand
2019-03-04  8:59     ` David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 28/32] s390x/tcg: Implement VECTOR STORE David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 29/32] s390x/tcg: Implement VECTOR STORE ELEMENT David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 30/32] s390x/tcg: Implement VECTOR STORE MULTIPLE David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 31/32] s390x/tcg: Implement VECTOR STORE WITH LENGTH David Hildenbrand
2019-03-01 11:54 ` [Qemu-devel] [PATCH v2 32/32] s390x/tcg: Implement VECTOR UNPACK * David Hildenbrand
2019-03-01 12:26 ` [Qemu-devel] [PATCH v2 00/32] s390x/tcg: Vector Instruction Support Part 1 no-reply
2019-03-01 16:17 ` no-reply
2019-03-01 16:26 ` no-reply
2019-03-01 16:31 ` no-reply
2019-03-01 16:38 ` no-reply
2019-03-01 16:40   ` David Hildenbrand
2019-03-01 21:24 ` no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190301115413.27153-5-david@redhat.com \
    --to=david@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).