All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cornelia Huck <cohuck@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-s390x@nongnu.org,
	Richard Henderson <richard.henderson@linaro.org>,
	qemu-devel@nongnu.org, David Hildenbrand <david@redhat.com>
Subject: [Qemu-devel] [PULL 14/35] s390x/tcg: Implement VECTOR FP ADD
Date: Fri,  7 Jun 2019 11:52:16 +0200	[thread overview]
Message-ID: <20190607095237.11364-15-cohuck@redhat.com> (raw)
In-Reply-To: <20190607095237.11364-1-cohuck@redhat.com>

From: David Hildenbrand <david@redhat.com>

1. We'll reuse op_vfa() for similar instructions later, prepare for
   that.
2. We'll reuse vop64_3() for other instructions later.
3. Take care of modifying the vector register only if no trap happened.
 - on traps, flags are not updated and no elements are modified
 - traps don't modify the fpc flags
 - without traps, all exceptions of all elements are merged
4. We'll reuse check_ieee_exc() later when we need the XxC flag.

We have to check for exceptions after processing each element.
Provide separate handlers for single/all element processing. We'll do
the same for all applicable FP instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/Makefile.objs      |   1 +
 target/s390x/helper.h           |   4 ++
 target/s390x/insn-data.def      |   5 ++
 target/s390x/translate_vx.inc.c |  29 ++++++++
 target/s390x/vec_fpu_helper.c   | 119 ++++++++++++++++++++++++++++++++
 5 files changed, 158 insertions(+)
 create mode 100644 target/s390x/vec_fpu_helper.c

diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
index ffdd484ef05e..3e2745594a29 100644
--- a/target/s390x/Makefile.objs
+++ b/target/s390x/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += cpu.o cpu_models.o cpu_features.o gdbstub.o interrupt.o helper.o
 obj-$(CONFIG_TCG) += translate.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o crypto_helper.o
 obj-$(CONFIG_TCG) += vec_helper.o vec_int_helper.o vec_string_helper.o
+obj-$(CONFIG_TCG) += vec_fpu_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o
 obj-$(CONFIG_SOFTMMU) += sigp.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 5db67779d3c6..21658a277190 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -249,6 +249,10 @@ DEF_HELPER_6(gvec_vstrc_cc_rt8, void, ptr, cptr, cptr, cptr, env, i32)
 DEF_HELPER_6(gvec_vstrc_cc_rt16, void, ptr, cptr, cptr, cptr, env, i32)
 DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
 
+/* === Vector Floating-Point Instructions */
+DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
 DEF_HELPER_4(diag, void, env, i32, i32, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index a2969fab5884..79892f6042f0 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1204,6 +1204,11 @@
 /* VECTOR STRING RANGE COMPARE */
     F(0xe78a, VSTRC,   VRR_d, V,   0, 0, 0, 0, vstrc, 0, IF_VEC)
 
+/* === Vector Floating-Point Instructions */
+
+/* VECTOR FP ADD */
+    F(0xe7e3, VFA,     VRR_c, V,   0, 0, 0, 0, vfa, 0, 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_vx.inc.c b/target/s390x/translate_vx.inc.c
index f26ffa28957a..44da9f26457b 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -52,6 +52,11 @@
 #define ES_64   MO_64
 #define ES_128  4
 
+/* Floating-Point Format */
+#define FPF_SHORT       2
+#define FPF_LONG        3
+#define FPF_EXT         4
+
 static inline bool valid_vec_element(uint8_t enr, TCGMemOp es)
 {
     return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
@@ -2538,3 +2543,27 @@ static DisasJumpType op_vstrc(DisasContext *s, DisasOps *o)
     }
     return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
+{
+    const uint8_t fpf = get_field(s->fields, m4);
+    const uint8_t m5 = get_field(s->fields, m5);
+    const bool se = extract32(m5, 3, 1);
+    gen_helper_gvec_3_ptr *fn;
+
+    if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+        gen_program_exception(s, PGM_SPECIFICATION);
+        return DISAS_NORETURN;
+    }
+
+    switch (s->fields->op2) {
+    case 0xe3:
+        fn = se ? gen_helper_gvec_vfa64s : gen_helper_gvec_vfa64;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+                   get_field(s->fields, v3), cpu_env, 0, fn);
+    return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
new file mode 100644
index 000000000000..c7db0791d7ca
--- /dev/null
+++ b/target/s390x/vec_fpu_helper.c
@@ -0,0 +1,119 @@
+/*
+ * QEMU TCG support -- s390x vector floating point instruction support
+ *
+ * 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.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internal.h"
+#include "vec.h"
+#include "tcg_s390x.h"
+#include "tcg/tcg-gvec-desc.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "fpu/softfloat.h"
+
+#define VIC_INVALID         0x1
+#define VIC_DIVBYZERO       0x2
+#define VIC_OVERFLOW        0x3
+#define VIC_UNDERFLOW       0x4
+#define VIC_INEXACT         0x5
+
+/* returns the VEX. If the VEX is 0, there is no trap */
+static uint8_t check_ieee_exc(CPUS390XState *env, uint8_t enr, bool XxC,
+                              uint8_t *vec_exc)
+{
+    uint8_t vece_exc = 0, trap_exc;
+    unsigned qemu_exc;
+
+    /* Retrieve and clear the softfloat exceptions */
+    qemu_exc = env->fpu_status.float_exception_flags;
+    if (qemu_exc == 0) {
+        return 0;
+    }
+    env->fpu_status.float_exception_flags = 0;
+
+    vece_exc = s390_softfloat_exc_to_ieee(qemu_exc);
+
+    /* Add them to the vector-wide s390x exception bits */
+    *vec_exc |= vece_exc;
+
+    /* Check for traps and construct the VXC */
+    trap_exc = vece_exc & env->fpc >> 24;
+    if (trap_exc) {
+        if (trap_exc & S390_IEEE_MASK_INVALID) {
+            return enr << 4 | VIC_INVALID;
+        } else if (trap_exc & S390_IEEE_MASK_DIVBYZERO) {
+            return enr << 4 | VIC_DIVBYZERO;
+        } else if (trap_exc & S390_IEEE_MASK_OVERFLOW) {
+            return enr << 4 | VIC_OVERFLOW;
+        } else if (trap_exc & S390_IEEE_MASK_UNDERFLOW) {
+            return enr << 4 | VIC_UNDERFLOW;
+        } else if (!XxC) {
+            g_assert(trap_exc & S390_IEEE_MASK_INEXACT);
+            /* inexact has lowest priority on traps */
+            return enr << 4 | VIC_INEXACT;
+        }
+    }
+    return 0;
+}
+
+static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, uint8_t vec_exc,
+                            uintptr_t retaddr)
+{
+    if (vxc) {
+        /* on traps, the fpc flags are not updated, instruction is suppressed */
+        tcg_s390_vector_exception(env, vxc, retaddr);
+    }
+    if (vec_exc) {
+        /* indicate exceptions for all elements combined */
+        env->fpc |= vec_exc << 16;
+    }
+}
+
+typedef uint64_t (*vop64_3_fn)(uint64_t a, uint64_t b, float_status *s);
+static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+                    CPUS390XState *env, bool s, vop64_3_fn fn,
+                    uintptr_t retaddr)
+{
+    uint8_t vxc, vec_exc = 0;
+    S390Vector tmp = {};
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        const uint64_t a = s390_vec_read_element64(v2, i);
+        const uint64_t b = s390_vec_read_element64(v3, i);
+
+        s390_vec_write_element64(&tmp, i, fn(a, b, &env->fpu_status));
+        vxc = check_ieee_exc(env, i, false, &vec_exc);
+        if (s || vxc) {
+            break;
+        }
+    }
+    handle_ieee_exc(env, vxc, vec_exc, retaddr);
+    *v1 = tmp;
+}
+
+static uint64_t vfa64(uint64_t a, uint64_t b, float_status *s)
+{
+    return float64_add(a, b, s);
+}
+
+void HELPER(gvec_vfa64)(void *v1, const void *v2, const void *v3,
+                        CPUS390XState *env, uint32_t desc)
+{
+    vop64_3(v1, v2, v3, env, false, vfa64, GETPC());
+}
+
+void HELPER(gvec_vfa64s)(void *v1, const void *v2, const void *v3,
+                         CPUS390XState *env, uint32_t desc)
+{
+    vop64_3(v1, v2, v3, env, true, vfa64, GETPC());
+}
-- 
2.20.1



  parent reply	other threads:[~2019-06-07 10:57 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-07  9:52 [Qemu-devel] [PULL 00/35] s390x updates Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 01/35] MAINTAINERS: cover tests/migration/s390x/ Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 02/35] vfio-ccw: support async command subregion Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 03/35] s390x/tcg: Implement VECTOR FIND ANY ELEMENT EQUAL Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 04/35] s390x/tcg: Implement VECTOR FIND " Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 05/35] s390x/tcg: Implement VECTOR FIND ELEMENT NOT EQUAL Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 06/35] s390x/tcg: Implement VECTOR ISOLATE STRING Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 07/35] s390x/tcg: Implement VECTOR STRING RANGE COMPARE Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 08/35] s390x: Align vector registers to 16 bytes Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 09/35] s390x: Use uint64_t for vector registers Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 10/35] s390x/tcg: Fix max_byte detection for stfle Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 11/35] s390x/tcg: Store only the necessary amount of doublewords for STFLE Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 12/35] s390x/tcg: Introduce tcg_s390_vector_exception() Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 13/35] s390x/tcg: Export float_comp_to_cc() and float(32|64|128)_dcmask() Cornelia Huck
2019-06-07  9:52 ` Cornelia Huck [this message]
2019-06-07  9:52 ` [Qemu-devel] [PULL 15/35] s390x/tcg: Implement VECTOR FP COMPARE (AND SIGNAL) SCALAR Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 16/35] s390x/tcg: Implement VECTOR FP COMPARE (EQUAL|HIGH|HIGH OR EQUAL) Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 17/35] s390x/tcg: Implement VECTOR FP CONVERT FROM FIXED 64-BIT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 18/35] s390x/tcg: Implement VECTOR FP CONVERT FROM LOGICAL 64-BIT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 19/35] s390x/tcg: Implement VECTOR FP CONVERT TO FIXED 64-BIT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 20/35] s390x/tcg: Implement VECTOR FP CONVERT TO LOGICAL 64-BIT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 21/35] s390x/tcg: Implement VECTOR FP DIVIDE Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 22/35] s390x/tcg: Implement VECTOR LOAD FP INTEGER Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 23/35] s390x/tcg: Implement VECTOR LOAD LENGTHENED Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 24/35] s390x/tcg: Implement VECTOR LOAD ROUNDED Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 25/35] s390x/tcg: Implement VECTOR FP MULTIPLY Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 26/35] s390x/tcg: Implement VECTOR FP MULTIPLY AND (ADD|SUBTRACT) Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 27/35] s390x/tcg: Implement VECTOR FP PERFORM SIGN OPERATION Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 28/35] s390x/tcg: Implement VECTOR FP SQUARE ROOT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 29/35] s390x/tcg: Implement VECTOR FP SUBTRACT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 30/35] s390x/tcg: Implement VECTOR FP TEST DATA CLASS IMMEDIATE Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 31/35] s390x/tcg: Allow linux-user to use vector instructions Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 32/35] s390x/tcg: We support the Vector Facility Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 33/35] s390x: Bump the "qemu" CPU model up to a stripped-down z13 Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 34/35] s390x/tcg: Use tcg_gen_gvec_bitsel for VECTOR SELECT Cornelia Huck
2019-06-07  9:52 ` [Qemu-devel] [PULL 35/35] linux-user: elf: ELF_HWCAP for s390x Cornelia Huck
2019-06-07  9:57 ` [Qemu-devel] [PULL 00/35] s390x updates Peter Maydell
2019-06-07  9:58   ` Peter Maydell
2019-06-07 10:02     ` Cornelia Huck
2019-06-07 10:06     ` Cornelia Huck
2019-06-07 13:00     ` Cornelia Huck

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=20190607095237.11364-15-cohuck@redhat.com \
    --to=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /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 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.