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