18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARM NEON vector operations.
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2007, 2008 CodeSourcery.
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Written by Paul Brook
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
79eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * This code is licensed under the GNU GPL v2.
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
133d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner#include "exec/exec-all.h"
145285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#include "helper.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SIGNBIT (uint32_t)0x80000000
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SIGNBIT64 ((uint64_t)1 << 63)
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
199eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_TYPE1(name, type) \
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct \
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v1; \
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} neon_##name;
2620894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#ifdef HOST_WORDS_BIGENDIAN
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_TYPE2(name, type) \
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct \
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v2; \
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v1; \
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} neon_##name;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_TYPE4(name, type) \
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct \
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v4; \
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v3; \
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v2; \
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v1; \
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} neon_##name;
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_TYPE2(name, type) \
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct \
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v1; \
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v2; \
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} neon_##name;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_TYPE4(name, type) \
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct \
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v1; \
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v2; \
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v3; \
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type v4; \
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} neon_##name;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE4(s8, int8_t)
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE4(u8, uint8_t)
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE2(s16, int16_t)
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE2(u16, uint16_t)
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE1(s32, int32_t)
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_TYPE1(u32, uint32_t)
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_TYPE4
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_TYPE2
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_TYPE1
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copy from a uint32_t to a vector structure type.  */
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_UNPACK(vtype, dest, val) do { \
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union { \
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vtype v; \
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t i; \
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } conv_u; \
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    conv_u.i = (val); \
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = conv_u.v; \
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copy from a vector structure type to a uint32_t.  */
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_PACK(vtype, dest, val) do { \
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union { \
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vtype v; \
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t i; \
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } conv_u; \
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    conv_u.v = (val); \
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = conv_u.i; \
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_DO1 \
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1);
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_DO2 \
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2);
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_DO4 \
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2); \
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v3, vsrc1.v3, vsrc2.v3); \
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v4, vsrc1.v4, vsrc2.v4);
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_VOP_BODY(vtype, n) \
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res; \
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vsrc1; \
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vsrc2; \
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vdest; \
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(vtype, vsrc1, arg1); \
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(vtype, vsrc2, arg2); \
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_DO##n; \
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(vtype, res, vdest); \
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res; \
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_VOP(name, vtype, n) \
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP_BODY(vtype, n)
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1163d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner#define NEON_VOP_ENV(name, vtype, n) \
1179eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turneruint32_t HELPER(glue(neon_,name))(CPUARMState *env, uint32_t arg1, uint32_t arg2) \
1183d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_BODY(vtype, n)
1193d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Pairwise operations.  */
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* For 32-bit elements each segment only contains a single element, so
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the elementwise and pairwise operations are the same.  */
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_PDO2 \
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v2, vsrc2.v1, vsrc2.v2);
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_PDO4 \
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v2, vsrc1.v3, vsrc1.v4); \
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v3, vsrc2.v1, vsrc2.v2); \
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_FN(vdest.v4, vsrc2.v3, vsrc2.v4); \
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_POP(name, vtype, n) \
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res; \
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vsrc1; \
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vsrc2; \
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vdest; \
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(vtype, vsrc1, arg1); \
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(vtype, vsrc2, arg2); \
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PDO##n; \
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(vtype, res, vdest); \
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res; \
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unary operators.  */
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_VOP1(name, vtype, n) \
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(glue(neon_,name))(uint32_t arg) \
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vsrc1; \
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vtype vdest; \
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(vtype, vsrc1, arg); \
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_DO##n; \
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(vtype, arg, vdest); \
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return arg; \
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_USAT(dest, src1, src2, type) do { \
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tmp != (type)tmp) { \
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = ~0; \
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = tmp; \
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while(0)
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
1683d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qadd_u8, neon_u8, 4)
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
1713d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qadd_u16, neon_u16, 2)
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_USAT
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1753d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qadd_u32)(CPUARMState *env, uint32_t a, uint32_t b)
1765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
1775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t res = a + b;
1785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (res < a) {
1795285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
1805285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ~0;
1815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
1825285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
1835285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
1845285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
1853d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qadd_u64)(CPUARMState *env, uint64_t src1, uint64_t src2)
1865285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
1875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t res;
1885285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
1895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    res = src1 + src2;
1905285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (res < src1) {
1915285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
1925285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ~(uint64_t)0;
1935285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
1945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
1955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
1965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_SSAT(dest, src1, src2, type) do { \
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tmp != (type)tmp) { \
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (src2 > 0) { \
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else { \
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = 1 << (sizeof(type) * 8 - 1); \
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = tmp; \
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
2103d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qadd_s8, neon_s8, 4)
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
2133d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qadd_s16, neon_s16, 2)
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_SSAT
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2173d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qadd_s32)(CPUARMState *env, uint32_t a, uint32_t b)
2185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
2195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t res = a + b;
2205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
2215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
2225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ~(((int32_t)a >> 31) ^ SIGNBIT);
2235285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
2245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
2255285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
2265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2273d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qadd_s64)(CPUARMState *env, uint64_t src1, uint64_t src2)
2285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
2295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t res;
2305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    res = src1 + src2;
2325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) {
2335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
2345285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
2355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
2365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
2375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
2385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_USAT(dest, src1, src2, type) do { \
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tmp != (type)tmp) { \
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = tmp; \
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while(0)
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
2483d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qsub_u8, neon_u8, 4)
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
2513d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qsub_u16, neon_u16, 2)
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_USAT
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2553d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qsub_u32)(CPUARMState *env, uint32_t a, uint32_t b)
2565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
2575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t res = a - b;
2585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (res > a) {
2595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
2605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = 0;
2615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
2625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
2635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
2645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2653d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qsub_u64)(CPUARMState *env, uint64_t src1, uint64_t src2)
2665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
2675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t res;
2685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2695285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (src1 < src2) {
2705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
2715285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = 0;
2725285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else {
2735285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = src1 - src2;
2745285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
2755285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
2765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
2775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_SSAT(dest, src1, src2, type) do { \
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tmp != (type)tmp) { \
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (src2 < 0) { \
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else { \
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = 1 << (sizeof(type) * 8 - 1); \
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = tmp; \
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
2913d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qsub_s8, neon_s8, 4)
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
2943d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qsub_s16, neon_s16, 2)
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_SSAT
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2983d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qsub_s32)(CPUARMState *env, uint32_t a, uint32_t b)
2995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
3005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t res = a - b;
3015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
3025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
3035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ~(((int32_t)a >> 31) ^ SIGNBIT);
3045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
3055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
3065285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
3075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
3083d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qsub_s64)(CPUARMState *env, uint64_t src1, uint64_t src2)
3095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
3105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t res;
3115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
3125285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    res = src1 - src2;
3135285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) {
3145285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
3155285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
3165285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
3175285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
3185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
3195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 + src2) >> 1
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hadd_s8, neon_s8, 4)
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hadd_u8, neon_u8, 4)
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hadd_s16, neon_s16, 2)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hadd_u16, neon_u16, 2)
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32_t HELPER(neon_hadd_s32)(int32_t src1, int32_t src2)
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t dest;
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) + (src2 >> 1);
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (src1 & src2 & 1)
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest++;
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_hadd_u32)(uint32_t src1, uint32_t src2)
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t dest;
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) + (src2 >> 1);
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (src1 & src2 & 1)
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest++;
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 + src2 + 1) >> 1
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rhadd_s8, neon_s8, 4)
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rhadd_u8, neon_u8, 4)
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rhadd_s16, neon_s16, 2)
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rhadd_u16, neon_u16, 2)
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32_t HELPER(neon_rhadd_s32)(int32_t src1, int32_t src2)
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t dest;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) + (src2 >> 1);
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((src1 | src2) & 1)
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest++;
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_rhadd_u32)(uint32_t src1, uint32_t src2)
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t dest;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) + (src2 >> 1);
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((src1 | src2) & 1)
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest++;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 - src2) >> 1
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hsub_s8, neon_s8, 4)
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hsub_u8, neon_u8, 4)
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hsub_s16, neon_s16, 2)
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(hsub_u16, neon_u16, 2)
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32_t HELPER(neon_hsub_s32)(int32_t src1, int32_t src2)
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t dest;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) - (src2 >> 1);
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((~src1) & src2 & 1)
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest--;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_hsub_u32)(uint32_t src1, uint32_t src2)
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t dest;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 >> 1) - (src2 >> 1);
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((~src1) & src2 & 1)
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest--;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dest;
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? ~0 : 0
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_s8, neon_s8, 4)
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_u8, neon_u8, 4)
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_s16, neon_s16, 2)
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_u16, neon_u16, 2)
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_s32, neon_s32, 1)
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cgt_u32, neon_u32, 1)
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 >= src2) ? ~0 : 0
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_s8, neon_s8, 4)
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_u8, neon_u8, 4)
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_s16, neon_s16, 2)
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_u16, neon_u16, 2)
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_s32, neon_s32, 1)
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(cge_u32, neon_u32, 1)
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_s8, neon_s8, 4)
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_u8, neon_u8, 4)
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_s16, neon_s16, 2)
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_u16, neon_u16, 2)
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_s32, neon_s32, 1)
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(min_u32, neon_u32, 1)
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmin_s8, neon_s8, 4)
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmin_u8, neon_u8, 4)
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmin_s16, neon_s16, 2)
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmin_u16, neon_u16, 2)
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_s8, neon_s8, 4)
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_u8, neon_u8, 4)
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_s16, neon_s16, 2)
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_u16, neon_u16, 2)
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_s32, neon_s32, 1)
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(max_u32, neon_u32, 1)
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmax_s8, neon_s8, 4)
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmax_u8, neon_u8, 4)
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmax_s16, neon_s16, 2)
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(pmax_u16, neon_u16, 2)
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) \
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_s8, neon_s8, 4)
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_u8, neon_u8, 4)
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_s16, neon_s16, 2)
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_u16, neon_u16, 2)
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_s32, neon_s32, 1)
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(abd_u32, neon_u32, 1)
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
4585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8 || \
4595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        tmp <= -(ssize_t)sizeof(src1) * 8) { \
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> -tmp; \
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_u8, neon_u8, 4)
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_u16, neon_u16, 2)
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_u32, neon_u32, 1)
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (int8_t)shiftop;
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (shift >= 64 || shift <= -64) {
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val = 0;
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift < 0) {
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= -shift;
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
4875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8) { \
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
4895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> (sizeof(src1) * 8 - 1); \
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> -tmp; \
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_s8, neon_s8, 4)
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_s16, neon_s16, 2)
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(shl_s32, neon_s32, 1)
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (int8_t)shiftop;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t val = valop;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (shift >= 64) {
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val = 0;
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift <= -64) {
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= 63;
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift < 0) {
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= -shift;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
5205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if ((tmp >= (ssize_t)sizeof(src1) * 8) \
5215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        || (tmp <= -(ssize_t)sizeof(src1) * 8)) { \
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rshl_s8, neon_s8, 4)
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rshl_s16, neon_s16, 2)
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* The addition of the rounding constant may overflow, so we use an
5339eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * intermediate 64 bit accumulator.  */
5345285864985be9077e58e42235af6582dee72e841David 'Digit' Turneruint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop)
5355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
5365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int32_t dest;
5375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int32_t val = (int32_t)valop;
5385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int8_t shift = (int8_t)shiftop;
5395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if ((shift >= 32) || (shift <= -32)) {
5405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0;
5415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
5425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
5435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = big_dest >> -shift;
5445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else {
5455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val << shift;
5465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
5475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return dest;
5485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
5495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
5509eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner/* Handling addition overflow with 64 bit input values is more
5519eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * tricky than with 32 bit values.  */
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (int8_t)shiftop;
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t val = valop;
5565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if ((shift >= 64) || (shift <= -64)) {
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val = 0;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift < 0) {
5595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val >>= (-shift - 1);
5605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val == INT64_MAX) {
5615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            /* In this case, it means that the rounding constant is 1,
5625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * and the addition would overflow. Return the actual
5635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * result directly.  */
5645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = 0x4000000000000000LL;
5655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
5665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val++;
5675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val >>= 1;
5685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
5785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8 || \
5795285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        tmp < -(ssize_t)sizeof(src1) * 8) { \
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
5815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
5825285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = src1 >> (-tmp - 1); \
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rshl_u8, neon_u8, 4)
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(rshl_u16, neon_u16, 2)
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5925285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* The addition of the rounding constant may overflow, so we use an
5939eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * intermediate 64 bit accumulator.  */
5945285864985be9077e58e42235af6582dee72e841David 'Digit' Turneruint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
5955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
5965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t dest;
5975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int8_t shift = (int8_t)shiftop;
5985285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 32 || shift < -32) {
5995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0;
6005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift == -32) {
6015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val >> 31;
6025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
6035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
6045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = big_dest >> -shift;
6055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else {
6065285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val << shift;
6075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
6085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return dest;
6095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
6105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
6119eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner/* Handling addition overflow with 64 bit input values is more
6129eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * tricky than with 32 bit values.  */
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (uint8_t)shiftop;
6165285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 64 || shift < -64) {
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val = 0;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift == -64) {
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Rounding a 1-bit result just preserves that bit.  */
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= 63;
6215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
6225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val >>= (-shift - 1);
6235285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val == UINT64_MAX) {
6245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            /* In this case, it means that the rounding constant is 1,
6255285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * and the addition would overflow. Return the actual
6265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * result directly.  */
6275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = 0x8000000000000000ULL;
6285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
6295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val++;
6305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val >>= 1;
6315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
6415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8) { \
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (src1) { \
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dest = ~0; \
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else { \
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dest = 0; \
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
6485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = 0; \
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> -tmp; \
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((dest >> tmp) != src1) { \
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dest = ~0; \
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
6593d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_u8, neon_u8, 4)
6603d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_u16, neon_u16, 2)
6613d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_u32, neon_u32, 1)
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6643d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qshl_u64)(CPUARMState *env, uint64_t val, uint64_t shiftop)
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (int8_t)shiftop;
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (shift >= 64) {
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val) {
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = ~(uint64_t)0;
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift <= -64) {
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val = 0;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift < 0) {
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= -shift;
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t tmp = val;
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((val >> shift) != tmp) {
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = ~(uint64_t)0;
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
6905285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8) { \
6915285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (src1) { \
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
6935285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
6945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (src1 > 0) { \
6955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest--; \
6965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
6975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else { \
6985285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = src1; \
6995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } \
7005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> 31; \
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (tmp < 0) { \
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 >> -tmp; \
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((dest >> tmp) != src1) { \
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
7085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
7095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (src1 > 0) { \
7105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest--; \
7115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
7143d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_s8, neon_s8, 4)
7153d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_s16, neon_s16, 2)
7163d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshl_s32, neon_s32, 1)
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7193d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qshl_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (uint8_t)shiftop;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t val = valop;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (shift >= 64) {
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val) {
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
7265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = (val >> 63) ^ ~SIGNBIT64;
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift <= -64) {
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= 63;
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (shift < 0) {
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val >>= -shift;
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int64_t tmp = val;
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((val >> shift) != tmp) {
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = (tmp >> 63) ^ ~SIGNBIT64;
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#define NEON_FN(dest, src1, src2) do { \
7445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (src1 & (1 << (sizeof(src1) * 8 - 1))) { \
7455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC(); \
7465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0; \
7475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else { \
7485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        int8_t tmp; \
7495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        tmp = (int8_t)src2; \
7505285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (tmp >= (ssize_t)sizeof(src1) * 8) { \
7515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (src1) { \
7525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                SET_QC(); \
7535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest = ~0; \
7545285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } else { \
7555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest = 0; \
7565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
7575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
7585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = 0; \
7595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else if (tmp < 0) { \
7605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = src1 >> -tmp; \
7615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else { \
7625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = src1 << tmp; \
7635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if ((dest >> tmp) != src1) { \
7645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                SET_QC(); \
7655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest = ~0; \
7665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
7675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } \
7685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }} while (0)
7693d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshlu_s8, neon_u8, 4)
7703d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qshlu_s16, neon_u16, 2)
7715285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#undef NEON_FN
7725285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
7733d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qshlu_s32)(CPUARMState *env, uint32_t valop, uint32_t shiftop)
7745285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
7755285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if ((int32_t)valop < 0) {
7765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
7775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        return 0;
7785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
7793d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner    return helper_neon_qshl_u32(env, valop, shiftop);
7805285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
7815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
7823d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qshlu_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
7835285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
7845285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if ((int64_t)valop < 0) {
7855285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
7865285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        return 0;
7875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
7883d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner    return helper_neon_qshl_u64(env, valop, shiftop);
7895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
7945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8) { \
7955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (src1) { \
7965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC(); \
7975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = ~0; \
7985285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else { \
7995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = 0; \
8005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } \
8015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp < -(ssize_t)sizeof(src1) * 8) { \
8025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0; \
8035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
8045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = src1 >> (sizeof(src1) * 8 - 1); \
8055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp < 0) { \
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((dest >> tmp) != src1) { \
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dest = ~0; \
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
8143d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrshl_u8, neon_u8, 4)
8153d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrshl_u16, neon_u16, 2)
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* The addition of the rounding constant may overflow, so we use an
8199eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * intermediate 64 bit accumulator.  */
8203d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qrshl_u32)(CPUARMState *env, uint32_t val, uint32_t shiftop)
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t dest;
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (int8_t)shiftop;
8245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 32) {
8255285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val) {
8265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
8275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = ~0;
8285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
8295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = 0;
8305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
8315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < -32) {
8325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0;
8335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift == -32) {
8345285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val >> 31;
8355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
8365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
8375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = big_dest >> -shift;
8385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else {
8395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val << shift;
8405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if ((dest >> shift) != val) {
8415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
8425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = ~0;
8435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
8445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
8455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return dest;
8465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
8475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
8489eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner/* Handling addition overflow with 64 bit input values is more
8499eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * tricky than with 32 bit values.  */
8503d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qrshl_u64)(CPUARMState *env, uint64_t val, uint64_t shiftop)
8515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
8525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int8_t shift = (int8_t)shiftop;
8535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 64) {
8545285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val) {
8555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
8565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = ~0;
8575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
8585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < -64) {
8595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val = 0;
8605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift == -64) {
8615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val >>= 63;
8625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
8635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val >>= (-shift - 1);
8645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val == UINT64_MAX) {
8655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            /* In this case, it means that the rounding constant is 1,
8665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * and the addition would overflow. Return the actual
8675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * result directly.  */
8685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = 0x8000000000000000ULL;
8695285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
8705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val++;
8715285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val >>= 1;
8725285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t tmp = val;
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((val >> shift) != tmp) {
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = ~0;
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) do { \
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t tmp; \
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (int8_t)src2; \
8875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (tmp >= (ssize_t)sizeof(src1) * 8) { \
8885285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (src1) { \
8895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC(); \
8905285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (1 << (sizeof(src1) * 8 - 1)); \
8915285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (src1 > 0) { \
8925285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest--; \
8935285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
8945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else { \
8955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = 0; \
8965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } \
8975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
8985285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0; \
8995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (tmp < 0) { \
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dest = src1 << tmp; \
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((dest >> tmp) != src1) { \
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
9055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
9065285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (src1 > 0) { \
9075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                dest--; \
9085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            } \
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
9113d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrshl_s8, neon_s8, 4)
9123d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrshl_s16, neon_s16, 2)
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9155285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* The addition of the rounding constant may overflow, so we use an
9169eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * intermediate 64 bit accumulator.  */
9173d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qrshl_s32)(CPUARMState *env, uint32_t valop, uint32_t shiftop)
9185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
9195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int32_t dest;
9205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int32_t val = (int32_t)valop;
9215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    int8_t shift = (int8_t)shiftop;
9225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 32) {
9235285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val) {
9245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
9255285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (val >> 31) ^ ~SIGNBIT;
9265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
9275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = 0;
9285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
9295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift <= -32) {
9305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = 0;
9315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
9325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
9335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = big_dest >> -shift;
9345285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else {
9355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        dest = val << shift;
9365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if ((dest >> shift) != val) {
9375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
9385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            dest = (val >> 31) ^ ~SIGNBIT;
9395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
9405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
9415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return dest;
9425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
9435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
9449eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner/* Handling addition overflow with 64 bit input values is more
9459eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner * tricky than with 32 bit values.  */
9463d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_qrshl_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8_t shift = (uint8_t)shiftop;
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t val = valop;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (shift >= 64) {
9525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val) {
9535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC();
9545285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = (val >> 63) ^ ~SIGNBIT64;
9555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
9565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift <= -64) {
9575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val = 0;
9585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (shift < 0) {
9595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        val >>= (-shift - 1);
9605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (val == INT64_MAX) {
9615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            /* In this case, it means that the rounding constant is 1,
9625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * and the addition would overflow. Return the actual
9635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner             * result directly.  */
9645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = 0x4000000000000000ULL;
9655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else {
9665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val++;
9675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val >>= 1;
9685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
9705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        int64_t tmp = val;
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val <<= shift;
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((val >> shift) != tmp) {
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC();
9745285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            val = (tmp >> 63) ^ ~SIGNBIT64;
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_add_u8)(uint32_t a, uint32_t b)
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ b) & 0x80808080u;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a &= ~0x80808080u;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x80808080u;
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a + b) ^ mask;
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_add_u16)(uint32_t a, uint32_t b)
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ b) & 0x80008000u;
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a &= ~0x80008000u;
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x80008000u;
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a + b) ^ mask;
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = src1 + src2
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(padd_u8, neon_u8, 4)
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_POP(padd_u16, neon_u16, 2)
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = src1 - src2
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(sub_u8, neon_u8, 4)
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(sub_u16, neon_u16, 2)
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = src1 * src2
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(mul_u8, neon_u8, 4)
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(mul_u16, neon_u16, 2)
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Polynomial multiplication is like integer multiplication except the
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   partial products are XORed, not added.  */
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t result;
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = 0;
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (op1) {
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = 0;
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (op1 & 1)
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            mask |= 0xff;
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (op1 & (1 << 8))
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            mask |= (0xff << 8);
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (op1 & (1 << 16))
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            mask |= (0xff << 16);
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (op1 & (1 << 24))
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            mask |= (0xff << 24);
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result ^= op2 & mask;
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op1 = (op1 >> 1) & 0x7f7f7f7f;
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op2 = (op2 << 1) & 0xfefefefe;
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10375285864985be9077e58e42235af6582dee72e841David 'Digit' Turneruint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
10385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
10395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t result = 0;
10405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t mask;
10415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t op2ex = op2;
10425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    op2ex = (op2ex & 0xff) |
10435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        ((op2ex & 0xff00) << 8) |
10445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        ((op2ex & 0xff0000) << 16) |
10455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        ((op2ex & 0xff000000) << 24);
10465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    while (op1) {
10475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        mask = 0;
10485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (op1 & 1) {
10495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            mask |= 0xffff;
10505285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
10515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (op1 & (1 << 8)) {
10525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            mask |= (0xffffU << 16);
10535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
10545285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (op1 & (1 << 16)) {
10555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            mask |= (0xffffULL << 32);
10565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
10575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (op1 & (1 << 24)) {
10585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            mask |= (0xffffULL << 48);
10595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        }
10605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        result ^= op2ex & mask;
10615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        op1 = (op1 >> 1) & 0x7f7f7f7f;
10625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        op2ex <<= 1;
10635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
10645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return result;
10655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
10665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(tst_u8, neon_u8, 4)
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(tst_u16, neon_u16, 2)
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(tst_u32, neon_u32, 1)
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) dest = (src1 == src2) ? -1 : 0
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(ceq_u8, neon_u8, 4)
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(ceq_u16, neon_u16, 2)
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP(ceq_u32, neon_u32, 1)
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(abs_s8, neon_s8, 4)
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(abs_s16, neon_s16, 2)
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Count Leading Sign/Zero Bits.  */
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int do_clz8(uint8_t x)
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 8; x; n--)
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x >>= 1;
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return n;
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int do_clz16(uint16_t x)
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 16; x; n--)
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x >>= 1;
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return n;
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src, dummy) dest = do_clz8(src)
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(clz_u8, neon_u8, 4)
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src, dummy) dest = do_clz16(src)
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(clz_u16, neon_u16, 2)
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src, dummy) dest = do_clz8((src < 0) ? ~src : src) - 1
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(cls_s8, neon_s8, 4)
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src, dummy) dest = do_clz16((src < 0) ? ~src : src) - 1
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNEON_VOP1(cls_s16, neon_s16, 2)
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_cls_s32)(uint32_t x)
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int count;
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((int32_t)x < 0)
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = ~x;
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (count = 32; x; count--)
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = x >> 1;
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return count - 1;
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Bit count.  */
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_cnt_u8)(uint32_t x)
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x = (x & 0x55555555) + ((x >>  1) & 0x55555555);
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x = (x & 0x33333333) + ((x >>  2) & 0x33333333);
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x = (x & 0x0f0f0f0f) + ((x >>  4) & 0x0f0f0f0f);
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_QDMULH16(dest, src1, src2, round) do { \
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((tmp ^ (tmp << 1)) & SIGNBIT) { \
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp = (tmp >> 31) ^ ~SIGNBIT; \
11415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else { \
11425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        tmp <<= 1; \
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (round) { \
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int32_t old = tmp; \
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp += 1 << 15; \
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((int32_t)tmp < old) { \
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = SIGNBIT - 1; \
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = tmp >> 16; \
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 0)
11553d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qdmulh_s16, neon_s16, 2)
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 1)
11583d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrdmulh_s16, neon_s16, 2)
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_QDMULH16
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_QDMULH32(dest, src1, src2, round) do { \
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp = (int64_t)(int32_t) src1 * (int32_t) src2; \
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((tmp ^ (tmp << 1)) & SIGNBIT64) { \
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp = (tmp >> 63) ^ ~SIGNBIT64; \
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp <<= 1; \
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (round) { \
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int64_t old = tmp; \
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp += (int64_t)1 << 31; \
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((int64_t)tmp < old) { \
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SET_QC(); \
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tmp = SIGNBIT64 - 1; \
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } \
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = tmp >> 32; \
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 0)
11813d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qdmulh_s32, neon_s32, 1)
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 1)
11843d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' TurnerNEON_VOP_ENV(qrdmulh_s32, neon_s32, 1)
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_FN
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NEON_QDMULH32
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_u8)(uint64_t x)
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (x & 0xffu) | ((x >> 8) & 0xff00u) | ((x >> 16) & 0xff0000u)
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           | ((x >> 24) & 0xff000000u);
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_u16)(uint64_t x)
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (x & 0xffffu) | ((x >> 16) & 0xffff0000u);
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_high_u8)(uint64_t x)
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_high_u16)(uint64_t x)
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_round_high_u8)(uint64_t x)
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x &= 0xff80ff80ff80ff80ull;
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x += 0x0080008000800080ull;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(neon_narrow_round_high_u16)(uint64_t x)
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x &= 0xffff8000ffff8000ull;
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x += 0x0000800000008000ull;
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12253d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_unarrow_sat8)(CPUARMState *env, uint64_t x)
12265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
12275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint16_t s;
12285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint8_t d;
12295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t res = 0;
12305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#define SAT8(n) \
12315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    s = x >> n; \
12325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (s & 0x8000) { \
12335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC(); \
12345285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else { \
12355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        if (s > 0xff) { \
12365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            d = 0xff; \
12375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            SET_QC(); \
12385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } else  { \
12395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            d = s; \
12405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        } \
12415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        res |= (uint32_t)d << (n / 2); \
12425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
12435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
12445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    SAT8(0);
12455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    SAT8(16);
12465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    SAT8(32);
12475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    SAT8(48);
12485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#undef SAT8
12495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return res;
12505285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
12515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
12523d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_u8)(CPUARMState *env, uint64_t x)
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t s;
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t d;
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res = 0;
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SAT8(n) \
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = x >> n; \
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s > 0xff) { \
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        d = 0xff; \
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else  { \
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        d = s; \
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res |= (uint32_t)d << (n / 2);
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(0);
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(16);
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(32);
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(48);
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef SAT8
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12753d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_s8)(CPUARMState *env, uint64_t x)
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16_t s;
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t d;
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res = 0;
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SAT8(n) \
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = x >> n; \
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s != (int8_t)s) { \
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        d = (s >> 15) ^ 0x7f; \
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else  { \
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        d = s; \
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res |= (uint32_t)d << (n / 2);
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(0);
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(16);
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(32);
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SAT8(48);
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef SAT8
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12983d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_unarrow_sat16)(CPUARMState *env, uint64_t x)
12995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
13005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t high;
13015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint32_t low;
13025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    low = x;
13035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (low & 0x80000000) {
13045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        low = 0;
13055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13065285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (low > 0xffff) {
13075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        low = 0xffff;
13085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
13105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    high = x >> 32;
13115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (high & 0x80000000) {
13125285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        high = 0;
13135285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13145285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    } else if (high > 0xffff) {
13155285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        high = 0xffff;
13165285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13175285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
13185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return low | (high << 16);
13195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
13205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
13213d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_u16)(CPUARMState *env, uint64_t x)
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t high;
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t low;
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = x;
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (low > 0xffff) {
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        low = 0xffff;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    high = x >> 32;
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (high > 0xffff) {
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        high = 0xffff;
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return low | (high << 16);
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13383d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_s16)(CPUARMState *env, uint64_t x)
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t low;
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t high;
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = x;
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (low != (int16_t)low) {
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        low = (low >> 31) ^ 0x7fff;
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    high = x >> 32;
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (high != (int16_t)high) {
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        high = (high >> 31) ^ 0x7fff;
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (uint16_t)low | (high << 16);
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13553d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_unarrow_sat32)(CPUARMState *env, uint64_t x)
13565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
13575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (x & 0x8000000000000000ull) {
13585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        return 0;
13605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
13615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    if (x > 0xffffffffu) {
13625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        SET_QC();
13635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        return 0xffffffffu;
13645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    }
13655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    return x;
13665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
13675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
13683d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_u32)(CPUARMState *env, uint64_t x)
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x > 0xffffffffu) {
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0xffffffffu;
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13773d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_narrow_sat_s32)(CPUARMState *env, uint64_t x)
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((int64_t)x != (int32_t)x) {
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
13815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        return ((int64_t)x >> 63) ^ 0x7fffffff;
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_widen_u8)(uint32_t x)
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t ret;
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = (uint8_t)x;
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint8_t)(x >> 8);
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 16;
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint8_t)(x >> 16);
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 32;
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint8_t)(x >> 24);
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 48;
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_widen_s8)(uint32_t x)
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t ret;
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = (uint16_t)(int8_t)x;
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint16_t)(int8_t)(x >> 8);
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 16;
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint16_t)(int8_t)(x >> 16);
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 32;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = (uint16_t)(int8_t)(x >> 24);
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret |= tmp << 48;
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_widen_u16)(uint32_t x)
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t high = (uint16_t)(x >> 16);
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((uint16_t)x) | (high << 32);
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_widen_s16)(uint32_t x)
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t high = (int16_t)(x >> 16);
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((uint32_t)(int16_t)x) | (high << 32);
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b)
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t mask;
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ b) & 0x8000800080008000ull;
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a &= ~0x8000800080008000ull;
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x8000800080008000ull;
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a + b) ^ mask;
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b)
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t mask;
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ b) & 0x8000000080000000ull;
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a &= ~0x8000000080000000ull;
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x8000000080000000ull;
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a + b) ^ mask;
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b)
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp2;
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = a & 0x0000ffff0000ffffull;
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp += (a >> 16) & 0x0000ffff0000ffffull;
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp2 = b & 0xffff0000ffff0000ull;
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp2 += (b << 16) & 0xffff0000ffff0000ull;
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return    ( tmp         & 0xffff)
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ((tmp  >> 16) & 0xffff0000ull)
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ((tmp2 << 16) & 0xffff00000000ull)
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ( tmp2        & 0xffff000000000000ull);
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b)
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t low = a + (a >> 32);
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t high = b + (b >> 32);
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return low + ((uint64_t)high << 32);
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b)
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t mask;
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ ~b) & 0x8000800080008000ull;
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a |= 0x8000800080008000ull;
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x8000800080008000ull;
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a - b) ^ mask;
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b)
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t mask;
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (a ^ ~b) & 0x8000000080000000ull;
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a |= 0x8000000080000000ull;
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b &= ~0x8000000080000000ull;
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a - b) ^ mask;
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14843d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_addl_saturate_s32)(CPUARMState *env, uint64_t a, uint64_t b)
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t x, y;
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t low, high;
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x = a;
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    y = b;
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = x + y;
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((low ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        low = ((int32_t)x >> 31) ^ ~SIGNBIT;
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x = a >> 32;
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    y = b >> 32;
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    high = x + y;
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((high ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        high = ((int32_t)x >> 31) ^ ~SIGNBIT;
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return low | ((uint64_t)high << 32);
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15063d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint64_t HELPER(neon_addl_saturate_s64)(CPUARMState *env, uint64_t a, uint64_t b)
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = a + b;
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((result ^ a) & SIGNBIT64) && !((a ^ b) & SIGNBIT64)) {
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = ((int64_t)a >> 63) ^ ~SIGNBIT64;
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* We have to do the arithmetic in a larger type than
15195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner * the input type, because for example with a signed 32 bit
15205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner * op the absolute difference can overflow a signed 32 bit value.
15215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner */
15225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#define DO_ABD(dest, x, y, intype, arithtype) do {            \
15235285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    arithtype tmp_x = (intype)(x);                            \
15245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    arithtype tmp_y = (intype)(y);                            \
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b)
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, uint8_t, uint32_t);
15335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 8, b >> 8, uint8_t, uint32_t);
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 16;
15355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 16, b >> 16, uint8_t, uint32_t);
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 32;
15375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 24, b >> 24, uint8_t, uint32_t);
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 48;
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b)
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, int8_t, int32_t);
15475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 8, b >> 8, int8_t, int32_t);
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 16;
15495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 16, b >> 16, int8_t, int32_t);
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 32;
15515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 24, b >> 24, int8_t, int32_t);
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 48;
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b)
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, uint16_t, uint32_t);
15615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 16, b >> 16, uint16_t, uint32_t);
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result | (tmp << 32);
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b)
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15695285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, int16_t, int32_t);
15705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(tmp, a >> 16, b >> 16, int16_t, int32_t);
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result | (tmp << 32);
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b)
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, uint32_t, uint64_t);
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b)
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
15845285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    DO_ABD(result, a, b, int32_t, int64_t);
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_ABD
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Widening multiply. Named type is the source type.  */
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_MULL(dest, x, y, type1, type2) do { \
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type1 tmp_x = x; \
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type1 tmp_y = y; \
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest = (type2)((type2)tmp_x * (type2)tmp_y); \
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_mull_u8)(uint32_t a, uint32_t b)
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(result, a, b, uint8_t, uint16_t);
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 8, b >> 8, uint8_t, uint16_t);
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 16;
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 16, b >> 16, uint8_t, uint16_t);
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 32;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 24, b >> 24, uint8_t, uint16_t);
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 48;
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_mull_s8)(uint32_t a, uint32_t b)
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(result, a, b, int8_t, uint16_t);
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 8, b >> 8, int8_t, uint16_t);
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 16;
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 16, b >> 16, int8_t, uint16_t);
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 32;
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 24, b >> 24, int8_t, uint16_t);
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= tmp << 48;
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_mull_u16)(uint32_t a, uint32_t b)
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(result, a, b, uint16_t, uint32_t);
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 16, b >> 16, uint16_t, uint32_t);
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result | (tmp << 32);
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_mull_s16)(uint32_t a, uint32_t b)
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t tmp;
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(result, a, b, int16_t, uint32_t);
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_MULL(tmp, a >> 16, b >> 16, int16_t, uint32_t);
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result | (tmp << 32);
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_negl_u16)(uint64_t x)
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t tmp;
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t result;
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = (uint16_t)-x;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = -(x >> 16);
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= (uint64_t)tmp << 16;
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = -(x >> 32);
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= (uint64_t)tmp << 32;
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = -(x >> 48);
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result |= (uint64_t)tmp << 48;
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_negl_u32)(uint64_t x)
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t low = -x;
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t high = -(x >> 32);
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return low | ((uint64_t)high << 32);
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* FIXME:  There should be a native op for this.  */
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t HELPER(neon_negl_u64)(uint64_t x)
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -x;
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16739eef50a878ea9af93eaf0e161a495704c468a2d4David 'Digit' Turner/* Saturating sign manipulation.  */
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ??? Make these use NEON_VOP1 */
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_QABS8(x) do { \
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == (int8_t)0x80) { \
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = 0x7f; \
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (x < 0) { \
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x; \
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
16823d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qabs_s8)(CPUARMState *env, uint32_t x)
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    neon_s8 vec;
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(neon_s8, vec, x);
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS8(vec.v1);
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS8(vec.v2);
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS8(vec.v3);
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS8(vec.v4);
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(neon_s8, x, vec);
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_QABS8
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_QNEG8(x) do { \
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == (int8_t)0x80) { \
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = 0x7f; \
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x; \
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
17023d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qneg_s8)(CPUARMState *env, uint32_t x)
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    neon_s8 vec;
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(neon_s8, vec, x);
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG8(vec.v1);
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG8(vec.v2);
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG8(vec.v3);
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG8(vec.v4);
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(neon_s8, x, vec);
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_QNEG8
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_QABS16(x) do { \
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == (int16_t)0x8000) { \
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = 0x7fff; \
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (x < 0) { \
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x; \
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
17223d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qabs_s16)(CPUARMState *env, uint32_t x)
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    neon_s16 vec;
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(neon_s16, vec, x);
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS16(vec.v1);
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QABS16(vec.v2);
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(neon_s16, x, vec);
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_QABS16
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_QNEG16(x) do { \
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == (int16_t)0x8000) { \
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = 0x7fff; \
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC(); \
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else { \
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x; \
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }} while (0)
17403d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qneg_s16)(CPUARMState *env, uint32_t x)
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    neon_s16 vec;
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_UNPACK(neon_s16, vec, x);
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG16(vec.v1);
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DO_QNEG16(vec.v2);
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NEON_PACK(neon_s16, x, vec);
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_QNEG16
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17513d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qabs_s32)(CPUARMState *env, uint32_t x)
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == SIGNBIT) {
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = ~SIGNBIT;
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if ((int32_t)x < 0) {
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x;
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17623d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turneruint32_t HELPER(neon_qneg_s32)(CPUARMState *env, uint32_t x)
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x == SIGNBIT) {
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SET_QC();
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = ~SIGNBIT;
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x = -x;
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* NEON Float helpers.  */
177416998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b, void *fpstp)
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
177616998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
17773d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner    return float32_val(float32_min(make_float32(a), make_float32(b), fpst));
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178016998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b, void *fpstp)
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
178216998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
17833d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turner    return float32_val(float32_max(make_float32(a), make_float32(b), fpst));
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178616998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp)
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
178816998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
17895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f0 = make_float32(a);
17905285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f1 = make_float32(b);
179116998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return float32_val(float32_abs(float32_sub(f0, f1, fpst)));
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner/* Floating point comparisons produce an integer result.
17955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner * Note that EQ doesn't signal InvalidOp for QNaNs but GE and GT do.
17965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner * Softfloat routines return 0/1, which we convert to the 0/-1 Neon requires.
17975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner */
179816998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_ceq_f32)(uint32_t a, uint32_t b, void *fpstp)
17995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
180016998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
180116998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return -float32_eq_quiet(make_float32(a), make_float32(b), fpst);
18025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
180416998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_cge_f32)(uint32_t a, uint32_t b, void *fpstp)
18055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
180616998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
180716998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return -float32_le(make_float32(b), make_float32(a), fpst);
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
181016998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_cgt_f32)(uint32_t a, uint32_t b, void *fpstp)
18115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
181216998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
181316998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return -float32_lt(make_float32(b), make_float32(a), fpst);
18145285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
181616998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b, void *fpstp)
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
181816998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
18195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f0 = float32_abs(make_float32(a));
18205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f1 = float32_abs(make_float32(b));
182116998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return -float32_le(f1, f0, fpst);
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
182416998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turneruint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b, void *fpstp)
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
182616998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    float_status *fpst = fpstp;
18275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f0 = float32_abs(make_float32(a));
18285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    float32 f1 = float32_abs(make_float32(b));
182916998987568fa923e463d41735dcf5c1b28220b9David 'Digit' Turner    return -float32_lt(f1, f0, fpst);
18305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
18325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
18335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
18343d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
18355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
18365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
18375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
18385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
18395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
18405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
18415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
18425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
18435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 4, 8) << 48) | (ELEM(zd1, 6, 8) << 56);
18445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zm0, 0, 8) | (ELEM(zm0, 2, 8) << 8)
18455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm0, 4, 8) << 16) | (ELEM(zm0, 6, 8) << 24)
18465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 0, 8) << 32) | (ELEM(zm1, 2, 8) << 40)
18475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 4, 8) << 48) | (ELEM(zm1, 6, 8) << 56);
18485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd0, 1, 8) | (ELEM(zd0, 3, 8) << 8)
18495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 5, 8) << 16) | (ELEM(zd0, 7, 8) << 24)
18505285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 1, 8) << 32) | (ELEM(zd1, 3, 8) << 40)
18515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 5, 8) << 48) | (ELEM(zd1, 7, 8) << 56);
18525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zm0, 1, 8) | (ELEM(zm0, 3, 8) << 8)
18535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
18545285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
18555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
18565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
18575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
18585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
18595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
18605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
18623d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
18635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
18645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
18655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
18665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
18675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
18685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16)
18695285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48);
18705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16)
18715285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 0, 16) << 32) | (ELEM(zm1, 2, 16) << 48);
18725285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd0, 1, 16) | (ELEM(zd0, 3, 16) << 16)
18735285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 1, 16) << 32) | (ELEM(zd1, 3, 16) << 48);
18745285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zm0, 1, 16) | (ELEM(zm0, 3, 16) << 16)
18755285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm1, 1, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
18765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
18775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
18785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
18795285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
18805285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
18823d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qunzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
18835285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
18845285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
18855285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
18865285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
18875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
18885285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zd1, 0, 32) << 32);
18895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zm0, 0, 32) | (ELEM(zm1, 0, 32) << 32);
18905285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd0, 1, 32) | (ELEM(zd1, 1, 32) << 32);
18915285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zm0, 1, 32) | (ELEM(zm1, 1, 32) << 32);
18925285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
18935285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
18945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
18955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
18965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
18975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
18983d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_unzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
18995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm = float64_val(env->vfp.regs[rm]);
19015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd = float64_val(env->vfp.regs[rd]);
19025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zd, 2, 8) << 8)
19035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 4, 8) << 16) | (ELEM(zd, 6, 8) << 24)
19045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 0, 8) << 32) | (ELEM(zm, 2, 8) << 40)
19055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 4, 8) << 48) | (ELEM(zm, 6, 8) << 56);
19065285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd, 1, 8) | (ELEM(zd, 3, 8) << 8)
19075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 5, 8) << 16) | (ELEM(zd, 7, 8) << 24)
19085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 1, 8) << 32) | (ELEM(zm, 3, 8) << 40)
19095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 5, 8) << 48) | (ELEM(zm, 7, 8) << 56);
19105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
19115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
19125285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
19135285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
19143d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_unzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
19155285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19165285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm = float64_val(env->vfp.regs[rm]);
19175285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd = float64_val(env->vfp.regs[rd]);
19185285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zd, 2, 16) << 16)
19195285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 0, 16) << 32) | (ELEM(zm, 2, 16) << 48);
19205285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd, 1, 16) | (ELEM(zd, 3, 16) << 16)
19215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zm, 1, 16) << 32) | (ELEM(zm, 3, 16) << 48);
19225285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
19235285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
19245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
19255285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
19263d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
19275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
19295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
19305285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
19315285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
19325285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zm0, 0, 8) << 8)
19335285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 1, 8) << 16) | (ELEM(zm0, 1, 8) << 24)
19345285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 2, 8) << 32) | (ELEM(zm0, 2, 8) << 40)
19355285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 3, 8) << 48) | (ELEM(zm0, 3, 8) << 56);
19365285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zd0, 4, 8) | (ELEM(zm0, 4, 8) << 8)
19375285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 5, 8) << 16) | (ELEM(zm0, 5, 8) << 24)
19385285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 6, 8) << 32) | (ELEM(zm0, 6, 8) << 40)
19395285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 7, 8) << 48) | (ELEM(zm0, 7, 8) << 56);
19405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd1, 0, 8) | (ELEM(zm1, 0, 8) << 8)
19415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 1, 8) << 16) | (ELEM(zm1, 1, 8) << 24)
19425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 2, 8) << 32) | (ELEM(zm1, 2, 8) << 40)
19435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 3, 8) << 48) | (ELEM(zm1, 3, 8) << 56);
19445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zd1, 4, 8) | (ELEM(zm1, 4, 8) << 8)
19455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 5, 8) << 16) | (ELEM(zm1, 5, 8) << 24)
19465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 6, 8) << 32) | (ELEM(zm1, 6, 8) << 40)
19475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 7, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
19485285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
19495285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
19505285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
19515285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
19525285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
19535285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
19543d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
19555285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19565285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
19575285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
19585285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
19595285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
19605285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zm0, 0, 16) << 16)
19615285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 1, 16) << 32) | (ELEM(zm0, 1, 16) << 48);
19625285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zd0, 2, 16) | (ELEM(zm0, 2, 16) << 16)
19635285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd0, 3, 16) << 32) | (ELEM(zm0, 3, 16) << 48);
19645285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd1, 0, 16) | (ELEM(zm1, 0, 16) << 16)
19655285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 1, 16) << 32) | (ELEM(zm1, 1, 16) << 48);
19665285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zd1, 2, 16) | (ELEM(zm1, 2, 16) << 16)
19675285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd1, 3, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
19685285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
19695285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
19705285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
19715285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
19725285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
19735285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
19743d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_qzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
19755285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm0 = float64_val(env->vfp.regs[rm]);
19775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
19785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd0 = float64_val(env->vfp.regs[rd]);
19795285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
19805285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zm0, 0, 32) << 32);
19815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d1 = ELEM(zd0, 1, 32) | (ELEM(zm0, 1, 32) << 32);
19825285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd1, 0, 32) | (ELEM(zm1, 0, 32) << 32);
19835285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m1 = ELEM(zd1, 1, 32) | (ELEM(zm1, 1, 32) << 32);
19845285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
19855285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm + 1] = make_float64(m1);
19865285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
19875285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd + 1] = make_float64(d1);
19885285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
19895285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
19903d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_zip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
19915285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
19925285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm = float64_val(env->vfp.regs[rm]);
19935285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd = float64_val(env->vfp.regs[rd]);
19945285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zm, 0, 8) << 8)
19955285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 1, 8) << 16) | (ELEM(zm, 1, 8) << 24)
19965285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 2, 8) << 32) | (ELEM(zm, 2, 8) << 40)
19975285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 3, 8) << 48) | (ELEM(zm, 3, 8) << 56);
19985285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd, 4, 8) | (ELEM(zm, 4, 8) << 8)
19995285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 5, 8) << 16) | (ELEM(zm, 5, 8) << 24)
20005285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 6, 8) << 32) | (ELEM(zm, 6, 8) << 40)
20015285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 7, 8) << 48) | (ELEM(zm, 7, 8) << 56);
20025285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
20035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
20045285864985be9077e58e42235af6582dee72e841David 'Digit' Turner}
20055285864985be9077e58e42235af6582dee72e841David 'Digit' Turner
20063d323dda130b16c690a78f08b7f766becb84914fDavid 'Digit' Turnervoid HELPER(neon_zip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
20075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner{
20085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zm = float64_val(env->vfp.regs[rm]);
20095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t zd = float64_val(env->vfp.regs[rd]);
20105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zm, 0, 16) << 16)
20115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 1, 16) << 32) | (ELEM(zm, 1, 16) << 48);
20125285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    uint64_t m0 = ELEM(zd, 2, 16) | (ELEM(zm, 2, 16) << 16)
20135285864985be9077e58e42235af6582dee72e841David 'Digit' Turner        | (ELEM(zd, 3, 16) << 32) | (ELEM(zm, 3, 16) << 48);
20145285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rm] = make_float64(m0);
20155285864985be9077e58e42235af6582dee72e841David 'Digit' Turner    env->vfp.regs[rd] = make_float64(d0);
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2017