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 } 326*35b3bb1cSDavid Hildenbrand 327*35b3bb1cSDavid Hildenbrand static uint64_t vcgd64(uint64_t a, float_status *s) 328*35b3bb1cSDavid Hildenbrand { 329*35b3bb1cSDavid Hildenbrand return float64_to_int64(a, s); 330*35b3bb1cSDavid Hildenbrand } 331*35b3bb1cSDavid Hildenbrand 332*35b3bb1cSDavid Hildenbrand void HELPER(gvec_vcgd64)(void *v1, const void *v2, CPUS390XState *env, 333*35b3bb1cSDavid Hildenbrand uint32_t desc) 334*35b3bb1cSDavid Hildenbrand { 335*35b3bb1cSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 336*35b3bb1cSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 337*35b3bb1cSDavid Hildenbrand 338*35b3bb1cSDavid Hildenbrand vop64_2(v1, v2, env, false, XxC, erm, vcgd64, GETPC()); 339*35b3bb1cSDavid Hildenbrand } 340*35b3bb1cSDavid Hildenbrand 341*35b3bb1cSDavid Hildenbrand void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env, 342*35b3bb1cSDavid Hildenbrand uint32_t desc) 343*35b3bb1cSDavid Hildenbrand { 344*35b3bb1cSDavid Hildenbrand const uint8_t erm = extract32(simd_data(desc), 4, 4); 345*35b3bb1cSDavid Hildenbrand const bool XxC = extract32(simd_data(desc), 2, 1); 346*35b3bb1cSDavid Hildenbrand 347*35b3bb1cSDavid Hildenbrand vop64_2(v1, v2, env, true, XxC, erm, vcgd64, GETPC()); 348*35b3bb1cSDavid Hildenbrand } 349