1*5f39d1b3SJooyung Han // Copyright 2015 The Gemmlowp Authors. All Rights Reserved. 2*5f39d1b3SJooyung Han // 3*5f39d1b3SJooyung Han // Licensed under the Apache License, Version 2.0 (the "License"); 4*5f39d1b3SJooyung Han // you may not use this file except in compliance with the License. 5*5f39d1b3SJooyung Han // You may obtain a copy of the License at 6*5f39d1b3SJooyung Han // 7*5f39d1b3SJooyung Han // http://www.apache.org/licenses/LICENSE-2.0 8*5f39d1b3SJooyung Han // 9*5f39d1b3SJooyung Han // Unless required by applicable law or agreed to in writing, software 10*5f39d1b3SJooyung Han // distributed under the License is distributed on an "AS IS" BASIS, 11*5f39d1b3SJooyung Han // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*5f39d1b3SJooyung Han // See the License for the specific language governing permissions and 13*5f39d1b3SJooyung Han // limitations under the License. 14*5f39d1b3SJooyung Han 15*5f39d1b3SJooyung Han // fixedpoint_neon.h: optimized NEON specializations of the templates 16*5f39d1b3SJooyung Han // in fixedpoint.h. 17*5f39d1b3SJooyung Han 18*5f39d1b3SJooyung Han #ifndef GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ 19*5f39d1b3SJooyung Han #define GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ 20*5f39d1b3SJooyung Han 21*5f39d1b3SJooyung Han #include <arm_neon.h> 22*5f39d1b3SJooyung Han 23*5f39d1b3SJooyung Han namespace gemmlowp { 24*5f39d1b3SJooyung Han 25*5f39d1b3SJooyung Han template <> 26*5f39d1b3SJooyung Han struct FixedPointRawTypeTraits<int32x4_t> { 27*5f39d1b3SJooyung Han typedef std::int32_t ScalarRawType; 28*5f39d1b3SJooyung Han static constexpr int kLanes = 4; 29*5f39d1b3SJooyung Han }; 30*5f39d1b3SJooyung Han 31*5f39d1b3SJooyung Han template <> 32*5f39d1b3SJooyung Han struct FixedPointRawTypeTraits<int16x8_t> { 33*5f39d1b3SJooyung Han typedef std::int16_t ScalarRawType; 34*5f39d1b3SJooyung Han static constexpr int kLanes = 8; 35*5f39d1b3SJooyung Han }; 36*5f39d1b3SJooyung Han 37*5f39d1b3SJooyung Han template <> 38*5f39d1b3SJooyung Han inline int32x4_t BitAnd(int32x4_t a, int32x4_t b) { 39*5f39d1b3SJooyung Han return vandq_s32(a, b); 40*5f39d1b3SJooyung Han } 41*5f39d1b3SJooyung Han 42*5f39d1b3SJooyung Han template <> 43*5f39d1b3SJooyung Han inline int16x8_t BitAnd(int16x8_t a, int16x8_t b) { 44*5f39d1b3SJooyung Han return vandq_s16(a, b); 45*5f39d1b3SJooyung Han } 46*5f39d1b3SJooyung Han 47*5f39d1b3SJooyung Han template <> 48*5f39d1b3SJooyung Han inline int32x4_t BitOr(int32x4_t a, int32x4_t b) { 49*5f39d1b3SJooyung Han return vorrq_s32(a, b); 50*5f39d1b3SJooyung Han } 51*5f39d1b3SJooyung Han 52*5f39d1b3SJooyung Han template <> 53*5f39d1b3SJooyung Han inline int16x8_t BitOr(int16x8_t a, int16x8_t b) { 54*5f39d1b3SJooyung Han return vorrq_s16(a, b); 55*5f39d1b3SJooyung Han } 56*5f39d1b3SJooyung Han 57*5f39d1b3SJooyung Han template <> 58*5f39d1b3SJooyung Han inline int32x4_t BitXor(int32x4_t a, int32x4_t b) { 59*5f39d1b3SJooyung Han return veorq_s32(a, b); 60*5f39d1b3SJooyung Han } 61*5f39d1b3SJooyung Han 62*5f39d1b3SJooyung Han template <> 63*5f39d1b3SJooyung Han inline int16x8_t BitXor(int16x8_t a, int16x8_t b) { 64*5f39d1b3SJooyung Han return veorq_s16(a, b); 65*5f39d1b3SJooyung Han } 66*5f39d1b3SJooyung Han 67*5f39d1b3SJooyung Han template <> 68*5f39d1b3SJooyung Han inline int32x4_t BitNot(int32x4_t a) { 69*5f39d1b3SJooyung Han return veorq_s32(a, vdupq_n_s32(-1)); 70*5f39d1b3SJooyung Han } 71*5f39d1b3SJooyung Han 72*5f39d1b3SJooyung Han template <> 73*5f39d1b3SJooyung Han inline int16x8_t BitNot(int16x8_t a) { 74*5f39d1b3SJooyung Han return veorq_s16(a, vdupq_n_s16(-1)); 75*5f39d1b3SJooyung Han } 76*5f39d1b3SJooyung Han 77*5f39d1b3SJooyung Han template <> 78*5f39d1b3SJooyung Han inline int32x4_t Add(int32x4_t a, int32x4_t b) { 79*5f39d1b3SJooyung Han return vaddq_s32(a, b); 80*5f39d1b3SJooyung Han } 81*5f39d1b3SJooyung Han 82*5f39d1b3SJooyung Han template <> 83*5f39d1b3SJooyung Han inline int16x8_t Add(int16x8_t a, int16x8_t b) { 84*5f39d1b3SJooyung Han return vaddq_s16(a, b); 85*5f39d1b3SJooyung Han } 86*5f39d1b3SJooyung Han 87*5f39d1b3SJooyung Han template <> 88*5f39d1b3SJooyung Han inline int32x4_t Sub(int32x4_t a, int32x4_t b) { 89*5f39d1b3SJooyung Han return vsubq_s32(a, b); 90*5f39d1b3SJooyung Han } 91*5f39d1b3SJooyung Han 92*5f39d1b3SJooyung Han template <> 93*5f39d1b3SJooyung Han inline int16x8_t Sub(int16x8_t a, int16x8_t b) { 94*5f39d1b3SJooyung Han return vsubq_s16(a, b); 95*5f39d1b3SJooyung Han } 96*5f39d1b3SJooyung Han 97*5f39d1b3SJooyung Han template <> 98*5f39d1b3SJooyung Han inline int32x4_t Neg(int32x4_t a) { 99*5f39d1b3SJooyung Han return vnegq_s32(a); 100*5f39d1b3SJooyung Han } 101*5f39d1b3SJooyung Han 102*5f39d1b3SJooyung Han template <> 103*5f39d1b3SJooyung Han inline int16x8_t Neg(int16x8_t a) { 104*5f39d1b3SJooyung Han return vnegq_s16(a); 105*5f39d1b3SJooyung Han } 106*5f39d1b3SJooyung Han 107*5f39d1b3SJooyung Han template <> 108*5f39d1b3SJooyung Han inline int32x4_t ShiftLeft(int32x4_t a, int offset) { 109*5f39d1b3SJooyung Han return vshlq_s32(a, vdupq_n_s32(offset)); 110*5f39d1b3SJooyung Han } 111*5f39d1b3SJooyung Han 112*5f39d1b3SJooyung Han template <> 113*5f39d1b3SJooyung Han inline int16x8_t ShiftLeft(int16x8_t a, int offset) { 114*5f39d1b3SJooyung Han return vshlq_s16(a, vdupq_n_s16(offset)); 115*5f39d1b3SJooyung Han } 116*5f39d1b3SJooyung Han 117*5f39d1b3SJooyung Han template <> 118*5f39d1b3SJooyung Han inline int32x4_t ShiftLeft(int32x4_t a, int32x4_t offset) { 119*5f39d1b3SJooyung Han return vshlq_s32(a, offset); 120*5f39d1b3SJooyung Han } 121*5f39d1b3SJooyung Han 122*5f39d1b3SJooyung Han template <> 123*5f39d1b3SJooyung Han inline int16x8_t ShiftLeft(int16x8_t a, int16x8_t offset) { 124*5f39d1b3SJooyung Han return vshlq_s16(a, offset); 125*5f39d1b3SJooyung Han } 126*5f39d1b3SJooyung Han 127*5f39d1b3SJooyung Han template <> 128*5f39d1b3SJooyung Han inline int32x4_t ShiftRight(int32x4_t a, int offset) { 129*5f39d1b3SJooyung Han return vshlq_s32(a, vdupq_n_s32(-offset)); 130*5f39d1b3SJooyung Han } 131*5f39d1b3SJooyung Han 132*5f39d1b3SJooyung Han template <> 133*5f39d1b3SJooyung Han inline int16x8_t ShiftRight(int16x8_t a, int offset) { 134*5f39d1b3SJooyung Han return vshlq_s16(a, vdupq_n_s16(-offset)); 135*5f39d1b3SJooyung Han } 136*5f39d1b3SJooyung Han 137*5f39d1b3SJooyung Han template <> 138*5f39d1b3SJooyung Han inline int32x4_t SelectUsingMask(int32x4_t if_mask, int32x4_t then_val, 139*5f39d1b3SJooyung Han int32x4_t else_val) { 140*5f39d1b3SJooyung Han return vbslq_s32(vreinterpretq_u32_s32(if_mask), then_val, else_val); 141*5f39d1b3SJooyung Han } 142*5f39d1b3SJooyung Han 143*5f39d1b3SJooyung Han template <> 144*5f39d1b3SJooyung Han inline int16x8_t SelectUsingMask(int16x8_t if_mask, int16x8_t then_val, 145*5f39d1b3SJooyung Han int16x8_t else_val) { 146*5f39d1b3SJooyung Han return vbslq_s16(vreinterpretq_u16_s16(if_mask), then_val, else_val); 147*5f39d1b3SJooyung Han } 148*5f39d1b3SJooyung Han 149*5f39d1b3SJooyung Han template <> 150*5f39d1b3SJooyung Han inline int32x4_t MaskIfEqual(int32x4_t a, int32x4_t b) { 151*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vceqq_s32(a, b)); 152*5f39d1b3SJooyung Han } 153*5f39d1b3SJooyung Han 154*5f39d1b3SJooyung Han template <> 155*5f39d1b3SJooyung Han inline int16x8_t MaskIfEqual(int16x8_t a, int16x8_t b) { 156*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vceqq_s16(a, b)); 157*5f39d1b3SJooyung Han } 158*5f39d1b3SJooyung Han 159*5f39d1b3SJooyung Han template <> 160*5f39d1b3SJooyung Han inline int32x4_t MaskIfNotEqual(int32x4_t a, int32x4_t b) { 161*5f39d1b3SJooyung Han return BitNot(MaskIfEqual(a, b)); 162*5f39d1b3SJooyung Han } 163*5f39d1b3SJooyung Han 164*5f39d1b3SJooyung Han template <> 165*5f39d1b3SJooyung Han inline int16x8_t MaskIfNotEqual(int16x8_t a, int16x8_t b) { 166*5f39d1b3SJooyung Han return BitNot(MaskIfEqual(a, b)); 167*5f39d1b3SJooyung Han } 168*5f39d1b3SJooyung Han 169*5f39d1b3SJooyung Han template <> 170*5f39d1b3SJooyung Han inline int32x4_t MaskIfZero(int32x4_t a) { 171*5f39d1b3SJooyung Han return MaskIfEqual(a, vdupq_n_s32(0)); 172*5f39d1b3SJooyung Han } 173*5f39d1b3SJooyung Han 174*5f39d1b3SJooyung Han template <> 175*5f39d1b3SJooyung Han inline int16x8_t MaskIfZero(int16x8_t a) { 176*5f39d1b3SJooyung Han return MaskIfEqual(a, vdupq_n_s16(0)); 177*5f39d1b3SJooyung Han } 178*5f39d1b3SJooyung Han 179*5f39d1b3SJooyung Han template <> 180*5f39d1b3SJooyung Han inline int32x4_t MaskIfNonZero(int32x4_t a) { 181*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vtstq_s32(a, a)); 182*5f39d1b3SJooyung Han } 183*5f39d1b3SJooyung Han 184*5f39d1b3SJooyung Han template <> 185*5f39d1b3SJooyung Han inline int16x8_t MaskIfNonZero(int16x8_t a) { 186*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vtstq_s16(a, a)); 187*5f39d1b3SJooyung Han } 188*5f39d1b3SJooyung Han 189*5f39d1b3SJooyung Han template <> 190*5f39d1b3SJooyung Han inline int32x4_t MaskIfGreaterThan(int32x4_t a, int32x4_t b) { 191*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vcgtq_s32(a, b)); 192*5f39d1b3SJooyung Han } 193*5f39d1b3SJooyung Han 194*5f39d1b3SJooyung Han template <> 195*5f39d1b3SJooyung Han inline int16x8_t MaskIfGreaterThan(int16x8_t a, int16x8_t b) { 196*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vcgtq_s16(a, b)); 197*5f39d1b3SJooyung Han } 198*5f39d1b3SJooyung Han 199*5f39d1b3SJooyung Han template <> 200*5f39d1b3SJooyung Han inline int32x4_t MaskIfGreaterThanOrEqual(int32x4_t a, int32x4_t b) { 201*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vcgeq_s32(a, b)); 202*5f39d1b3SJooyung Han } 203*5f39d1b3SJooyung Han 204*5f39d1b3SJooyung Han template <> 205*5f39d1b3SJooyung Han inline int16x8_t MaskIfGreaterThanOrEqual(int16x8_t a, int16x8_t b) { 206*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vcgeq_s16(a, b)); 207*5f39d1b3SJooyung Han } 208*5f39d1b3SJooyung Han 209*5f39d1b3SJooyung Han template <> 210*5f39d1b3SJooyung Han inline int32x4_t MaskIfLessThan(int32x4_t a, int32x4_t b) { 211*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vcltq_s32(a, b)); 212*5f39d1b3SJooyung Han } 213*5f39d1b3SJooyung Han 214*5f39d1b3SJooyung Han template <> 215*5f39d1b3SJooyung Han inline int16x8_t MaskIfLessThan(int16x8_t a, int16x8_t b) { 216*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vcltq_s16(a, b)); 217*5f39d1b3SJooyung Han } 218*5f39d1b3SJooyung Han 219*5f39d1b3SJooyung Han template <> 220*5f39d1b3SJooyung Han inline int32x4_t MaskIfLessThanOrEqual(int32x4_t a, int32x4_t b) { 221*5f39d1b3SJooyung Han return vreinterpretq_s32_u32(vcleq_s32(a, b)); 222*5f39d1b3SJooyung Han } 223*5f39d1b3SJooyung Han 224*5f39d1b3SJooyung Han template <> 225*5f39d1b3SJooyung Han inline int16x8_t MaskIfLessThanOrEqual(int16x8_t a, int16x8_t b) { 226*5f39d1b3SJooyung Han return vreinterpretq_s16_u16(vcleq_s16(a, b)); 227*5f39d1b3SJooyung Han } 228*5f39d1b3SJooyung Han 229*5f39d1b3SJooyung Han template <> 230*5f39d1b3SJooyung Han inline bool All(int32x4_t a) { 231*5f39d1b3SJooyung Han a = vandq_s32(a, vextq_s32(a, a, 1)); 232*5f39d1b3SJooyung Han a = vandq_s32(a, vextq_s32(a, a, 2)); 233*5f39d1b3SJooyung Han return vgetq_lane_s32(a, 0); 234*5f39d1b3SJooyung Han } 235*5f39d1b3SJooyung Han 236*5f39d1b3SJooyung Han template <> 237*5f39d1b3SJooyung Han inline bool All(int16x8_t a) { 238*5f39d1b3SJooyung Han a = vandq_s16(a, vextq_s16(a, a, 1)); 239*5f39d1b3SJooyung Han a = vandq_s16(a, vextq_s16(a, a, 2)); 240*5f39d1b3SJooyung Han a = vandq_s16(a, vextq_s16(a, a, 4)); 241*5f39d1b3SJooyung Han return vgetq_lane_s16(a, 0); 242*5f39d1b3SJooyung Han } 243*5f39d1b3SJooyung Han 244*5f39d1b3SJooyung Han template <> 245*5f39d1b3SJooyung Han inline bool Any(int32x4_t a) { 246*5f39d1b3SJooyung Han a = vorrq_s32(a, vextq_s32(a, a, 1)); 247*5f39d1b3SJooyung Han a = vorrq_s32(a, vextq_s32(a, a, 2)); 248*5f39d1b3SJooyung Han return vgetq_lane_s32(a, 0); 249*5f39d1b3SJooyung Han } 250*5f39d1b3SJooyung Han 251*5f39d1b3SJooyung Han template <> 252*5f39d1b3SJooyung Han inline bool Any(int16x8_t a) { 253*5f39d1b3SJooyung Han a = vorrq_s16(a, vextq_s16(a, a, 1)); 254*5f39d1b3SJooyung Han a = vorrq_s16(a, vextq_s16(a, a, 2)); 255*5f39d1b3SJooyung Han a = vorrq_s16(a, vextq_s16(a, a, 4)); 256*5f39d1b3SJooyung Han return vgetq_lane_s16(a, 0); 257*5f39d1b3SJooyung Han } 258*5f39d1b3SJooyung Han 259*5f39d1b3SJooyung Han template <> 260*5f39d1b3SJooyung Han inline int32x4_t RoundingHalfSum(int32x4_t a, int32x4_t b) { 261*5f39d1b3SJooyung Han return vrhaddq_s32(a, b); 262*5f39d1b3SJooyung Han } 263*5f39d1b3SJooyung Han 264*5f39d1b3SJooyung Han template <> 265*5f39d1b3SJooyung Han inline int16x8_t RoundingHalfSum(int16x8_t a, int16x8_t b) { 266*5f39d1b3SJooyung Han return vrhaddq_s16(a, b); 267*5f39d1b3SJooyung Han } 268*5f39d1b3SJooyung Han 269*5f39d1b3SJooyung Han template <> 270*5f39d1b3SJooyung Han inline int32x4_t SaturatingRoundingDoublingHighMul(int32x4_t a, int32x4_t b) { 271*5f39d1b3SJooyung Han return vqrdmulhq_s32(a, b); 272*5f39d1b3SJooyung Han } 273*5f39d1b3SJooyung Han 274*5f39d1b3SJooyung Han template <> 275*5f39d1b3SJooyung Han inline int16x8_t SaturatingRoundingDoublingHighMul(int16x8_t a, int16x8_t b) { 276*5f39d1b3SJooyung Han return vqrdmulhq_s16(a, b); 277*5f39d1b3SJooyung Han } 278*5f39d1b3SJooyung Han 279*5f39d1b3SJooyung Han template <> 280*5f39d1b3SJooyung Han inline int32x4_t RoundingDivideByPOT(int32x4_t x, int exponent) { 281*5f39d1b3SJooyung Han const int32x4_t shift_vec = vdupq_n_s32(-exponent); 282*5f39d1b3SJooyung Han const int32x4_t fixup = vshrq_n_s32(vandq_s32(x, shift_vec), 31); 283*5f39d1b3SJooyung Han const int32x4_t fixed_up_x = vqaddq_s32(x, fixup); 284*5f39d1b3SJooyung Han return vrshlq_s32(fixed_up_x, shift_vec); 285*5f39d1b3SJooyung Han } 286*5f39d1b3SJooyung Han 287*5f39d1b3SJooyung Han template <> 288*5f39d1b3SJooyung Han inline int16x8_t RoundingDivideByPOT(int16x8_t x, int exponent) { 289*5f39d1b3SJooyung Han const int16x8_t shift_vec = vdupq_n_s16(-exponent); 290*5f39d1b3SJooyung Han const int16x8_t fixup = vshrq_n_s16(vandq_s16(x, shift_vec), 15); 291*5f39d1b3SJooyung Han const int16x8_t fixed_up_x = vqaddq_s16(x, fixup); 292*5f39d1b3SJooyung Han return vrshlq_s16(fixed_up_x, shift_vec); 293*5f39d1b3SJooyung Han } 294*5f39d1b3SJooyung Han 295*5f39d1b3SJooyung Han template <> 296*5f39d1b3SJooyung Han inline int32x4_t RoundingDivideByPOT(int32x4_t x, int32x4_t exponent) { 297*5f39d1b3SJooyung Han const int32x4_t shift_vec = vnegq_s32(exponent); 298*5f39d1b3SJooyung Han const int32x4_t fixup = vshrq_n_s32(vandq_s32(x, shift_vec), 31); 299*5f39d1b3SJooyung Han const int32x4_t fixed_up_x = vqaddq_s32(x, fixup); 300*5f39d1b3SJooyung Han return vrshlq_s32(fixed_up_x, shift_vec); 301*5f39d1b3SJooyung Han } 302*5f39d1b3SJooyung Han 303*5f39d1b3SJooyung Han template <> 304*5f39d1b3SJooyung Han inline int16x8_t RoundingDivideByPOT(int16x8_t x, int16x8_t exponent) { 305*5f39d1b3SJooyung Han const int16x8_t shift_vec = vnegq_s16(exponent); 306*5f39d1b3SJooyung Han const int16x8_t fixup = vshrq_n_s16(vandq_s16(x, shift_vec), 15); 307*5f39d1b3SJooyung Han const int16x8_t fixed_up_x = vqaddq_s16(x, fixup); 308*5f39d1b3SJooyung Han return vrshlq_s16(fixed_up_x, shift_vec); 309*5f39d1b3SJooyung Han } 310*5f39d1b3SJooyung Han 311*5f39d1b3SJooyung Han template <int Exponent> 312*5f39d1b3SJooyung Han struct ImplSaturatingRoundingMultiplyByPOT<Exponent, int32x4_t, 1> { 313*5f39d1b3SJooyung Han static int32x4_t eval(int32x4_t x) { return vqshlq_n_s32(x, Exponent); } 314*5f39d1b3SJooyung Han }; 315*5f39d1b3SJooyung Han 316*5f39d1b3SJooyung Han template <int Exponent> 317*5f39d1b3SJooyung Han struct ImplSaturatingRoundingMultiplyByPOT<Exponent, int32x4_t, -1> { 318*5f39d1b3SJooyung Han static int32x4_t eval(int32x4_t x) { 319*5f39d1b3SJooyung Han const int32x4_t fixup = vshrq_n_s32(x, 31); 320*5f39d1b3SJooyung Han const int32x4_t fixed_up_x = vqaddq_s32(x, fixup); 321*5f39d1b3SJooyung Han return vrshrq_n_s32(fixed_up_x, -Exponent); 322*5f39d1b3SJooyung Han } 323*5f39d1b3SJooyung Han }; 324*5f39d1b3SJooyung Han 325*5f39d1b3SJooyung Han template <int Exponent> 326*5f39d1b3SJooyung Han struct ImplSaturatingRoundingMultiplyByPOT<Exponent, int16x8_t, 1> { 327*5f39d1b3SJooyung Han static int16x8_t eval(int16x8_t x) { return vqshlq_n_s16(x, Exponent); } 328*5f39d1b3SJooyung Han }; 329*5f39d1b3SJooyung Han 330*5f39d1b3SJooyung Han template <int Exponent> 331*5f39d1b3SJooyung Han struct ImplSaturatingRoundingMultiplyByPOT<Exponent, int16x8_t, -1> { 332*5f39d1b3SJooyung Han static int16x8_t eval(int16x8_t x) { 333*5f39d1b3SJooyung Han const int16x8_t fixup = vshrq_n_s16(x, 15); 334*5f39d1b3SJooyung Han const int16x8_t fixed_up_x = vqaddq_s16(x, fixup); 335*5f39d1b3SJooyung Han return vrshrq_n_s16(fixed_up_x, -Exponent); 336*5f39d1b3SJooyung Han } 337*5f39d1b3SJooyung Han }; 338*5f39d1b3SJooyung Han 339*5f39d1b3SJooyung Han template <> 340*5f39d1b3SJooyung Han inline int32x4_t Dup<int32x4_t>(std::int32_t x) { 341*5f39d1b3SJooyung Han return vdupq_n_s32(x); 342*5f39d1b3SJooyung Han } 343*5f39d1b3SJooyung Han 344*5f39d1b3SJooyung Han template <> 345*5f39d1b3SJooyung Han inline int16x8_t Dup<int16x8_t>(std::int16_t x) { 346*5f39d1b3SJooyung Han return vdupq_n_s16(x); 347*5f39d1b3SJooyung Han } 348*5f39d1b3SJooyung Han 349*5f39d1b3SJooyung Han // So far this is only needed for int16. 350*5f39d1b3SJooyung Han template <> 351*5f39d1b3SJooyung Han inline int16x8_t SaturatingAdd(int16x8_t a, int16x8_t b) { 352*5f39d1b3SJooyung Han return vqaddq_s16(a, b); 353*5f39d1b3SJooyung Han } 354*5f39d1b3SJooyung Han 355*5f39d1b3SJooyung Han } // end namespace gemmlowp 356*5f39d1b3SJooyung Han 357*5f39d1b3SJooyung Han #endif // GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ 358