13a0eae85SDavid Hildenbrand /* 23a0eae85SDavid Hildenbrand * QEMU TCG support -- s390x vector floating point instruction support 33a0eae85SDavid Hildenbrand * 43a0eae85SDavid Hildenbrand * Copyright (C) 2019 Red Hat Inc 53a0eae85SDavid Hildenbrand * 63a0eae85SDavid Hildenbrand * Authors: 73a0eae85SDavid Hildenbrand * David Hildenbrand <david@redhat.com> 83a0eae85SDavid Hildenbrand * 93a0eae85SDavid Hildenbrand * This work is licensed under the terms of the GNU GPL, version 2 or later. 103a0eae85SDavid Hildenbrand * See the COPYING file in the top-level directory. 113a0eae85SDavid Hildenbrand */ 123a0eae85SDavid Hildenbrand #include "qemu/osdep.h" 133a0eae85SDavid Hildenbrand #include "qemu-common.h" 143a0eae85SDavid Hildenbrand #include "cpu.h" 153a0eae85SDavid Hildenbrand #include "internal.h" 163a0eae85SDavid Hildenbrand #include "vec.h" 173a0eae85SDavid Hildenbrand #include "tcg_s390x.h" 183a0eae85SDavid Hildenbrand #include "tcg/tcg-gvec-desc.h" 193a0eae85SDavid Hildenbrand #include "exec/exec-all.h" 203a0eae85SDavid Hildenbrand #include "exec/helper-proto.h" 213a0eae85SDavid Hildenbrand #include "fpu/softfloat.h" 223a0eae85SDavid Hildenbrand 233a0eae85SDavid Hildenbrand #define VIC_INVALID 0x1 243a0eae85SDavid Hildenbrand #define VIC_DIVBYZERO 0x2 253a0eae85SDavid Hildenbrand #define VIC_OVERFLOW 0x3 263a0eae85SDavid Hildenbrand #define VIC_UNDERFLOW 0x4 273a0eae85SDavid Hildenbrand #define VIC_INEXACT 0x5 283a0eae85SDavid Hildenbrand 293a0eae85SDavid Hildenbrand /* returns the VEX. If the VEX is 0, there is no trap */ 303a0eae85SDavid Hildenbrand static uint8_t check_ieee_exc(CPUS390XState *env, uint8_t enr, bool XxC, 313a0eae85SDavid Hildenbrand uint8_t *vec_exc) 323a0eae85SDavid Hildenbrand { 333a0eae85SDavid Hildenbrand uint8_t vece_exc = 0, trap_exc; 343a0eae85SDavid Hildenbrand unsigned qemu_exc; 353a0eae85SDavid Hildenbrand 363a0eae85SDavid Hildenbrand /* Retrieve and clear the softfloat exceptions */ 373a0eae85SDavid Hildenbrand qemu_exc = env->fpu_status.float_exception_flags; 383a0eae85SDavid Hildenbrand if (qemu_exc == 0) { 393a0eae85SDavid Hildenbrand return 0; 403a0eae85SDavid Hildenbrand } 413a0eae85SDavid Hildenbrand env->fpu_status.float_exception_flags = 0; 423a0eae85SDavid Hildenbrand 433a0eae85SDavid Hildenbrand vece_exc = s390_softfloat_exc_to_ieee(qemu_exc); 443a0eae85SDavid Hildenbrand 453a0eae85SDavid Hildenbrand /* Add them to the vector-wide s390x exception bits */ 463a0eae85SDavid Hildenbrand *vec_exc |= vece_exc; 473a0eae85SDavid Hildenbrand 483a0eae85SDavid Hildenbrand /* Check for traps and construct the VXC */ 493a0eae85SDavid Hildenbrand trap_exc = vece_exc & env->fpc >> 24; 503a0eae85SDavid Hildenbrand if (trap_exc) { 513a0eae85SDavid Hildenbrand if (trap_exc & S390_IEEE_MASK_INVALID) { 523a0eae85SDavid Hildenbrand return enr << 4 | VIC_INVALID; 533a0eae85SDavid Hildenbrand } else if (trap_exc & S390_IEEE_MASK_DIVBYZERO) { 543a0eae85SDavid Hildenbrand return enr << 4 | VIC_DIVBYZERO; 553a0eae85SDavid Hildenbrand } else if (trap_exc & S390_IEEE_MASK_OVERFLOW) { 563a0eae85SDavid Hildenbrand return enr << 4 | VIC_OVERFLOW; 573a0eae85SDavid Hildenbrand } else if (trap_exc & S390_IEEE_MASK_UNDERFLOW) { 583a0eae85SDavid Hildenbrand return enr << 4 | VIC_UNDERFLOW; 593a0eae85SDavid Hildenbrand } else if (!XxC) { 603a0eae85SDavid Hildenbrand g_assert(trap_exc & S390_IEEE_MASK_INEXACT); 613a0eae85SDavid Hildenbrand /* inexact has lowest priority on traps */ 623a0eae85SDavid Hildenbrand return enr << 4 | VIC_INEXACT; 633a0eae85SDavid Hildenbrand } 643a0eae85SDavid Hildenbrand } 653a0eae85SDavid Hildenbrand return 0; 663a0eae85SDavid Hildenbrand } 673a0eae85SDavid Hildenbrand 683a0eae85SDavid Hildenbrand static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, uint8_t vec_exc, 693a0eae85SDavid Hildenbrand uintptr_t retaddr) 703a0eae85SDavid Hildenbrand { 713a0eae85SDavid Hildenbrand if (vxc) { 723a0eae85SDavid Hildenbrand /* on traps, the fpc flags are not updated, instruction is suppressed */ 733a0eae85SDavid Hildenbrand tcg_s390_vector_exception(env, vxc, retaddr); 743a0eae85SDavid Hildenbrand } 753a0eae85SDavid Hildenbrand if (vec_exc) { 763a0eae85SDavid Hildenbrand /* indicate exceptions for all elements combined */ 773a0eae85SDavid Hildenbrand env->fpc |= vec_exc << 16; 783a0eae85SDavid Hildenbrand } 793a0eae85SDavid Hildenbrand } 803a0eae85SDavid Hildenbrand 81bb03fd84SDavid Hildenbrand typedef uint64_t (*vop64_2_fn)(uint64_t a, float_status *s); 82bb03fd84SDavid Hildenbrand static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env, 83bb03fd84SDavid Hildenbrand bool s, bool XxC, uint8_t erm, vop64_2_fn fn, 84bb03fd84SDavid Hildenbrand uintptr_t retaddr) 85bb03fd84SDavid Hildenbrand { 86bb03fd84SDavid Hildenbrand uint8_t vxc, vec_exc = 0; 87bb03fd84SDavid Hildenbrand S390Vector tmp = {}; 88bb03fd84SDavid Hildenbrand int i, old_mode; 89bb03fd84SDavid Hildenbrand 90bb03fd84SDavid Hildenbrand old_mode = s390_swap_bfp_rounding_mode(env, erm); 91bb03fd84SDavid Hildenbrand for (i = 0; i < 2; i++) { 92bb03fd84SDavid Hildenbrand const uint64_t a = s390_vec_read_element64(v2, i); 93bb03fd84SDavid Hildenbrand 94bb03fd84SDavid Hildenbrand s390_vec_write_element64(&tmp, i, fn(a, &env->fpu_status)); 95bb03fd84SDavid Hildenbrand vxc = check_ieee_exc(env, i, XxC, &vec_exc); 96bb03fd84SDavid Hildenbrand if (s || vxc) { 97bb03fd84SDavid Hildenbrand break; 98bb03fd84SDavid Hildenbrand } 99bb03fd84SDavid Hildenbrand } 100bb03fd84SDavid Hildenbrand s390_restore_bfp_rounding_mode(env, old_mode); 101bb03fd84SDavid Hildenbrand handle_ieee_exc(env, vxc, vec_exc, retaddr); 102bb03fd84SDavid Hildenbrand *v1 = tmp; 103bb03fd84SDavid Hildenbrand } 104bb03fd84SDavid Hildenbrand 1053a0eae85SDavid Hildenbrand typedef uint64_t (*vop64_3_fn)(uint64_t a, uint64_t b, float_status *s); 1063a0eae85SDavid Hildenbrand static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3, 1073a0eae85SDavid Hildenbrand CPUS390XState *env, bool s, vop64_3_fn fn, 1083a0eae85SDavid Hildenbrand uintptr_t retaddr) 1093a0eae85SDavid Hildenbrand { 1103a0eae85SDavid Hildenbrand uint8_t vxc, vec_exc = 0; 1113a0eae85SDavid Hildenbrand S390Vector tmp = {}; 1123a0eae85SDavid Hildenbrand int i; 1133a0eae85SDavid Hildenbrand 1143a0eae85SDavid Hildenbrand for (i = 0; i < 2; i++) { 1153a0eae85SDavid Hildenbrand const uint64_t a = s390_vec_read_element64(v2, i); 1163a0eae85SDavid Hildenbrand const uint64_t b = s390_vec_read_element64(v3, i); 1173a0eae85SDavid Hildenbrand 1183a0eae85SDavid Hildenbrand s390_vec_write_element64(&tmp, i, fn(a, b, &env->fpu_status)); 1193a0eae85SDavid Hildenbrand vxc = check_ieee_exc(env, i, false, &vec_exc); 1203a0eae85SDavid Hildenbrand if (s || vxc) { 1213a0eae85SDavid Hildenbrand break; 1223a0eae85SDavid Hildenbrand } 1233a0eae85SDavid Hildenbrand } 1243a0eae85SDavid Hildenbrand handle_ieee_exc(env, vxc, vec_exc, retaddr); 1253a0eae85SDavid Hildenbrand *v1 = tmp; 1263a0eae85SDavid Hildenbrand } 1273a0eae85SDavid Hildenbrand 1283a0eae85SDavid Hildenbrand static uint64_t vfa64(uint64_t a, uint64_t b, float_status *s) 1293a0eae85SDavid Hildenbrand { 1303a0eae85SDavid Hildenbrand return float64_add(a, b, s); 1313a0eae85SDavid Hildenbrand } 1323a0eae85SDavid Hildenbrand 1333a0eae85SDavid Hildenbrand void HELPER(gvec_vfa64)(void *v1, const void *v2, const void *v3, 1343a0eae85SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 1353a0eae85SDavid Hildenbrand { 1363a0eae85SDavid Hildenbrand vop64_3(v1, v2, v3, env, false, vfa64, GETPC()); 1373a0eae85SDavid Hildenbrand } 1383a0eae85SDavid Hildenbrand 1393a0eae85SDavid Hildenbrand void HELPER(gvec_vfa64s)(void *v1, const void *v2, const void *v3, 1403a0eae85SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 1413a0eae85SDavid Hildenbrand { 1423a0eae85SDavid Hildenbrand vop64_3(v1, v2, v3, env, true, vfa64, GETPC()); 1433a0eae85SDavid Hildenbrand } 1445b89f0fbSDavid Hildenbrand 1455b89f0fbSDavid Hildenbrand static int wfc64(const S390Vector *v1, const S390Vector *v2, 1465b89f0fbSDavid Hildenbrand CPUS390XState *env, bool signal, uintptr_t retaddr) 1475b89f0fbSDavid Hildenbrand { 1485b89f0fbSDavid Hildenbrand /* only the zero-indexed elements are compared */ 1495b89f0fbSDavid Hildenbrand const float64 a = s390_vec_read_element64(v1, 0); 1505b89f0fbSDavid Hildenbrand const float64 b = s390_vec_read_element64(v2, 0); 1515b89f0fbSDavid Hildenbrand uint8_t vxc, vec_exc = 0; 1525b89f0fbSDavid Hildenbrand int cmp; 1535b89f0fbSDavid Hildenbrand 1545b89f0fbSDavid Hildenbrand if (signal) { 1555b89f0fbSDavid Hildenbrand cmp = float64_compare(a, b, &env->fpu_status); 1565b89f0fbSDavid Hildenbrand } else { 1575b89f0fbSDavid Hildenbrand cmp = float64_compare_quiet(a, b, &env->fpu_status); 1585b89f0fbSDavid Hildenbrand } 1595b89f0fbSDavid Hildenbrand vxc = check_ieee_exc(env, 0, false, &vec_exc); 1605b89f0fbSDavid Hildenbrand handle_ieee_exc(env, vxc, vec_exc, retaddr); 1615b89f0fbSDavid Hildenbrand 1625b89f0fbSDavid Hildenbrand return float_comp_to_cc(env, cmp); 1635b89f0fbSDavid Hildenbrand } 1645b89f0fbSDavid Hildenbrand 1655b89f0fbSDavid Hildenbrand void HELPER(gvec_wfc64)(const void *v1, const void *v2, CPUS390XState *env, 1665b89f0fbSDavid Hildenbrand uint32_t desc) 1675b89f0fbSDavid Hildenbrand { 1685b89f0fbSDavid Hildenbrand env->cc_op = wfc64(v1, v2, env, false, GETPC()); 1695b89f0fbSDavid Hildenbrand } 1705b89f0fbSDavid Hildenbrand 1715b89f0fbSDavid Hildenbrand void HELPER(gvec_wfk64)(const void *v1, const void *v2, CPUS390XState *env, 1725b89f0fbSDavid Hildenbrand uint32_t desc) 1735b89f0fbSDavid Hildenbrand { 1745b89f0fbSDavid Hildenbrand env->cc_op = wfc64(v1, v2, env, true, GETPC()); 1755b89f0fbSDavid Hildenbrand } 1762c806ab4SDavid Hildenbrand 1772c806ab4SDavid Hildenbrand typedef int (*vfc64_fn)(float64 a, float64 b, float_status *status); 1782c806ab4SDavid Hildenbrand static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3, 1792c806ab4SDavid Hildenbrand CPUS390XState *env, bool s, vfc64_fn fn, uintptr_t retaddr) 1802c806ab4SDavid Hildenbrand { 1812c806ab4SDavid Hildenbrand uint8_t vxc, vec_exc = 0; 1822c806ab4SDavid Hildenbrand S390Vector tmp = {}; 1832c806ab4SDavid Hildenbrand int match = 0; 1842c806ab4SDavid Hildenbrand int i; 1852c806ab4SDavid Hildenbrand 1862c806ab4SDavid Hildenbrand for (i = 0; i < 2; i++) { 1872c806ab4SDavid Hildenbrand const float64 a = s390_vec_read_element64(v2, i); 1882c806ab4SDavid Hildenbrand const float64 b = s390_vec_read_element64(v3, i); 1892c806ab4SDavid Hildenbrand 1902c806ab4SDavid Hildenbrand /* swap the order of the parameters, so we can use existing functions */ 1912c806ab4SDavid Hildenbrand if (fn(b, a, &env->fpu_status)) { 1922c806ab4SDavid Hildenbrand match++; 1932c806ab4SDavid Hildenbrand s390_vec_write_element64(&tmp, i, -1ull); 1942c806ab4SDavid Hildenbrand } 1952c806ab4SDavid Hildenbrand vxc = check_ieee_exc(env, i, false, &vec_exc); 1962c806ab4SDavid Hildenbrand if (s || vxc) { 1972c806ab4SDavid Hildenbrand break; 1982c806ab4SDavid Hildenbrand } 1992c806ab4SDavid Hildenbrand } 2002c806ab4SDavid Hildenbrand 2012c806ab4SDavid Hildenbrand handle_ieee_exc(env, vxc, vec_exc, retaddr); 2022c806ab4SDavid Hildenbrand *v1 = tmp; 2032c806ab4SDavid Hildenbrand if (match) { 2042c806ab4SDavid Hildenbrand return s || match == 2 ? 0 : 1; 2052c806ab4SDavid Hildenbrand } 2062c806ab4SDavid Hildenbrand return 3; 2072c806ab4SDavid Hildenbrand } 2082c806ab4SDavid Hildenbrand 2092c806ab4SDavid Hildenbrand void HELPER(gvec_vfce64)(void *v1, const void *v2, const void *v3, 2102c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2112c806ab4SDavid Hildenbrand { 2122c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, false, float64_eq_quiet, GETPC()); 2132c806ab4SDavid Hildenbrand } 2142c806ab4SDavid Hildenbrand 2152c806ab4SDavid Hildenbrand void HELPER(gvec_vfce64s)(void *v1, const void *v2, const void *v3, 2162c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2172c806ab4SDavid Hildenbrand { 2182c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, true, float64_eq_quiet, GETPC()); 2192c806ab4SDavid Hildenbrand } 2202c806ab4SDavid Hildenbrand 2212c806ab4SDavid Hildenbrand void HELPER(gvec_vfce64_cc)(void *v1, const void *v2, const void *v3, 2222c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2232c806ab4SDavid Hildenbrand { 2242c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, false, float64_eq_quiet, GETPC()); 2252c806ab4SDavid Hildenbrand } 2262c806ab4SDavid Hildenbrand 2272c806ab4SDavid Hildenbrand void HELPER(gvec_vfce64s_cc)(void *v1, const void *v2, const void *v3, 2282c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2292c806ab4SDavid Hildenbrand { 2302c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, true, float64_eq_quiet, GETPC()); 2312c806ab4SDavid Hildenbrand } 2322c806ab4SDavid Hildenbrand 2332c806ab4SDavid Hildenbrand void HELPER(gvec_vfch64)(void *v1, const void *v2, const void *v3, 2342c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2352c806ab4SDavid Hildenbrand { 2362c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, false, float64_lt_quiet, GETPC()); 2372c806ab4SDavid Hildenbrand } 2382c806ab4SDavid Hildenbrand 2392c806ab4SDavid Hildenbrand void HELPER(gvec_vfch64s)(void *v1, const void *v2, const void *v3, 2402c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2412c806ab4SDavid Hildenbrand { 2422c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, true, float64_lt_quiet, GETPC()); 2432c806ab4SDavid Hildenbrand } 2442c806ab4SDavid Hildenbrand 2452c806ab4SDavid Hildenbrand void HELPER(gvec_vfch64_cc)(void *v1, const void *v2, const void *v3, 2462c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2472c806ab4SDavid Hildenbrand { 2482c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, false, float64_lt_quiet, GETPC()); 2492c806ab4SDavid Hildenbrand } 2502c806ab4SDavid Hildenbrand 2512c806ab4SDavid Hildenbrand void HELPER(gvec_vfch64s_cc)(void *v1, const void *v2, const void *v3, 2522c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2532c806ab4SDavid Hildenbrand { 2542c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, true, float64_lt_quiet, GETPC()); 2552c806ab4SDavid Hildenbrand } 2562c806ab4SDavid Hildenbrand 2572c806ab4SDavid Hildenbrand void HELPER(gvec_vfche64)(void *v1, const void *v2, const void *v3, 2582c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2592c806ab4SDavid Hildenbrand { 2602c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, false, float64_le_quiet, GETPC()); 2612c806ab4SDavid Hildenbrand } 2622c806ab4SDavid Hildenbrand 2632c806ab4SDavid Hildenbrand void HELPER(gvec_vfche64s)(void *v1, const void *v2, const void *v3, 2642c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2652c806ab4SDavid Hildenbrand { 2662c806ab4SDavid Hildenbrand vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC()); 2672c806ab4SDavid Hildenbrand } 2682c806ab4SDavid Hildenbrand 2692c806ab4SDavid Hildenbrand void HELPER(gvec_vfche64_cc)(void *v1, const void *v2, const void *v3, 2702c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2712c806ab4SDavid Hildenbrand { 2722c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, false, float64_le_quiet, GETPC()); 2732c806ab4SDavid Hildenbrand } 2742c806ab4SDavid Hildenbrand 2752c806ab4SDavid Hildenbrand void HELPER(gvec_vfche64s_cc)(void *v1, const void *v2, const void *v3, 2762c806ab4SDavid Hildenbrand CPUS390XState *env, uint32_t desc) 2772c806ab4SDavid Hildenbrand { 2782c806ab4SDavid Hildenbrand env->cc_op = vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC()); 2792c806ab4SDavid Hildenbrand } 280bb03fd84SDavid Hildenbrand 281bb03fd84SDavid Hildenbrand static uint64_t vcdg64(uint64_t a, float_status *s) 282bb03fd84SDavid Hildenbrand { 283bb03fd84SDavid Hildenbrand return int64_to_float64(a, s); 284bb03fd84SDavid Hildenbrand } 285bb03fd84SDavid Hildenbrand 286bb03fd84SDavid Hildenbrand void HELPER(gvec_vcdg64)(void *v1, const void *v2, CPUS390XState *env, 287bb03fd84SDavid Hildenbrand uint32_t desc) 288bb03fd84SDavid Hildenbrand { 289bb03fd84SDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 290bb03fd84SDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 291bb03fd84SDavid Hildenbrand 292bb03fd84SDavid Hildenbrand vop64_2(v1, v2, env, false, XxC, erm, vcdg64, GETPC()); 293bb03fd84SDavid Hildenbrand } 294bb03fd84SDavid Hildenbrand 295bb03fd84SDavid Hildenbrand void HELPER(gvec_vcdg64s)(void *v1, const void *v2, CPUS390XState *env, 296bb03fd84SDavid Hildenbrand uint32_t desc) 297bb03fd84SDavid Hildenbrand { 298bb03fd84SDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 299bb03fd84SDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 300bb03fd84SDavid Hildenbrand 301bb03fd84SDavid Hildenbrand vop64_2(v1, v2, env, true, XxC, erm, vcdg64, GETPC()); 302bb03fd84SDavid Hildenbrand } 3039b8d1a38SDavid Hildenbrand 3049b8d1a38SDavid Hildenbrand static uint64_t vcdlg64(uint64_t a, float_status *s) 3059b8d1a38SDavid Hildenbrand { 3069b8d1a38SDavid Hildenbrand return uint64_to_float64(a, s); 3079b8d1a38SDavid Hildenbrand } 3089b8d1a38SDavid Hildenbrand 3099b8d1a38SDavid Hildenbrand void HELPER(gvec_vcdlg64)(void *v1, const void *v2, CPUS390XState *env, 3109b8d1a38SDavid Hildenbrand uint32_t desc) 3119b8d1a38SDavid Hildenbrand { 3129b8d1a38SDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 3139b8d1a38SDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 3149b8d1a38SDavid Hildenbrand 3159b8d1a38SDavid Hildenbrand vop64_2(v1, v2, env, false, XxC, erm, vcdlg64, GETPC()); 3169b8d1a38SDavid Hildenbrand } 3179b8d1a38SDavid Hildenbrand 3189b8d1a38SDavid Hildenbrand void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env, 3199b8d1a38SDavid Hildenbrand uint32_t desc) 3209b8d1a38SDavid Hildenbrand { 3219b8d1a38SDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 3229b8d1a38SDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 3239b8d1a38SDavid Hildenbrand 3249b8d1a38SDavid Hildenbrand vop64_2(v1, v2, env, true, XxC, erm, vcdlg64, GETPC()); 3259b8d1a38SDavid Hildenbrand } 32635b3bb1cSDavid Hildenbrand 32735b3bb1cSDavid Hildenbrand static uint64_t vcgd64(uint64_t a, float_status *s) 32835b3bb1cSDavid Hildenbrand { 32935b3bb1cSDavid Hildenbrand return float64_to_int64(a, s); 33035b3bb1cSDavid Hildenbrand } 33135b3bb1cSDavid Hildenbrand 33235b3bb1cSDavid Hildenbrand void HELPER(gvec_vcgd64)(void *v1, const void *v2, CPUS390XState *env, 33335b3bb1cSDavid Hildenbrand uint32_t desc) 33435b3bb1cSDavid Hildenbrand { 33535b3bb1cSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 33635b3bb1cSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 33735b3bb1cSDavid Hildenbrand 33835b3bb1cSDavid Hildenbrand vop64_2(v1, v2, env, false, XxC, erm, vcgd64, GETPC()); 33935b3bb1cSDavid Hildenbrand } 34035b3bb1cSDavid Hildenbrand 34135b3bb1cSDavid Hildenbrand void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env, 34235b3bb1cSDavid Hildenbrand uint32_t desc) 34335b3bb1cSDavid Hildenbrand { 34435b3bb1cSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 34535b3bb1cSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 34635b3bb1cSDavid Hildenbrand 34735b3bb1cSDavid Hildenbrand vop64_2(v1, v2, env, true, XxC, erm, vcgd64, GETPC()); 34835b3bb1cSDavid Hildenbrand } 34909c04e4bSDavid Hildenbrand 35009c04e4bSDavid Hildenbrand static uint64_t vclgd64(uint64_t a, float_status *s) 35109c04e4bSDavid Hildenbrand { 35209c04e4bSDavid Hildenbrand return float64_to_uint64(a, s); 35309c04e4bSDavid Hildenbrand } 35409c04e4bSDavid Hildenbrand 35509c04e4bSDavid Hildenbrand void HELPER(gvec_vclgd64)(void *v1, const void *v2, CPUS390XState *env, 35609c04e4bSDavid Hildenbrand uint32_t desc) 35709c04e4bSDavid Hildenbrand { 35809c04e4bSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 35909c04e4bSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 36009c04e4bSDavid Hildenbrand 36109c04e4bSDavid Hildenbrand vop64_2(v1, v2, env, false, XxC, erm, vclgd64, GETPC()); 36209c04e4bSDavid Hildenbrand } 36309c04e4bSDavid Hildenbrand 36409c04e4bSDavid Hildenbrand void HELPER(gvec_vclgd64s)(void *v1, const void *v2, CPUS390XState *env, 36509c04e4bSDavid Hildenbrand uint32_t desc) 36609c04e4bSDavid Hildenbrand { 36709c04e4bSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 36809c04e4bSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 36909c04e4bSDavid Hildenbrand 37009c04e4bSDavid Hildenbrand vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC()); 37109c04e4bSDavid Hildenbrand } 372*817a1cecSDavid Hildenbrand 373*817a1cecSDavid Hildenbrand static uint64_t vfd64(uint64_t a, uint64_t b, float_status *s) 374*817a1cecSDavid Hildenbrand { 375*817a1cecSDavid Hildenbrand return float64_div(a, b, s); 376*817a1cecSDavid Hildenbrand } 377*817a1cecSDavid Hildenbrand 378*817a1cecSDavid Hildenbrand void HELPER(gvec_vfd64)(void *v1, const void *v2, const void *v3, 379*817a1cecSDavid Hildenbrand CPUS390XState *env, uint32_t desc) 380*817a1cecSDavid Hildenbrand { 381*817a1cecSDavid Hildenbrand vop64_3(v1, v2, v3, env, false, vfd64, GETPC()); 382*817a1cecSDavid Hildenbrand } 383*817a1cecSDavid Hildenbrand 384*817a1cecSDavid Hildenbrand void HELPER(gvec_vfd64s)(void *v1, const void *v2, const void *v3, 385*817a1cecSDavid Hildenbrand CPUS390XState *env, uint32_t desc) 386*817a1cecSDavid Hildenbrand { 387*817a1cecSDavid Hildenbrand vop64_3(v1, v2, v3, env, true, vfd64, GETPC()); 388*817a1cecSDavid Hildenbrand } 389