aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/translate_vx.inc.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2019-05-29 21:21:21 +0200
committerDavid Hildenbrand <david@redhat.com>2019-06-07 14:53:25 +0200
commit3a0eae8546b4cda2526f1d913d50c4eb63f5c05e (patch)
tree6017d8b8f68942db8db7861753ee1e60493f384f /target/s390x/translate_vx.inc.c
parentaae65009726858390d8bfca73d795613698f317a (diff)
s390x/tcg: Implement VECTOR FP ADD
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>
Diffstat (limited to 'target/s390x/translate_vx.inc.c')
-rw-r--r--target/s390x/translate_vx.inc.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index f26ffa2895..44da9f2645 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;
+}