arm_negate_q15.c
1 /* ---------------------------------------------------------------------- 2 * Project: CMSIS DSP Library 3 * Title: arm_negate_q15.c 4 * Description: Negates Q15 vectors 5 * 6 * $Date: 23 April 2021 7 * $Revision: V1.9.0 8 * 9 * Target Processor: Cortex-M and Cortex-A cores 10 * -------------------------------------------------------------------- */ 11 /* 12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. 13 * 14 * SPDX-License-Identifier: Apache-2.0 15 * 16 * Licensed under the Apache License, Version 2.0 (the License); you may 17 * not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * 20 * www.apache.org/licenses/LICENSE-2.0 21 * 22 * Unless required by applicable law or agreed to in writing, software 23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 * See the License for the specific language governing permissions and 26 * limitations under the License. 27 */ 28 29 #include "dsp/basic_math_functions.h" 30 31 /** 32 @ingroup groupMath 33 */ 34 35 /** 36 @addtogroup BasicNegate 37 @{ 38 */ 39 40 /** 41 @brief Negates the elements of a Q15 vector. 42 @param[in] pSrc points to the input vector. 43 @param[out] pDst points to the output vector. 44 @param[in] blockSize number of samples in each vector. 45 @return none 46 47 @par Conditions for optimum performance 48 Input and output buffers should be aligned by 32-bit 49 @par Scaling and Overflow Behavior 50 The function uses saturating arithmetic. 51 The Q15 value -1 (0x8000) is saturated to the maximum allowable positive value 0x7FFF. 52 */ 53 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE) 54 55 #include "arm_helium_utils.h" 56 57 void arm_negate_q15( 58 const q15_t * pSrc, 59 q15_t * pDst, 60 uint32_t blockSize) 61 { 62 uint32_t blkCnt; /* loop counters */ 63 q15x8_t vecSrc; 64 65 /* Compute 8 outputs at a time */ 66 blkCnt = blockSize >> 3; 67 while (blkCnt > 0U) 68 { 69 /* 70 * C = -A 71 * Negate and then store the results in the destination buffer. 72 */ 73 vecSrc = vld1q(pSrc); 74 vst1q(pDst, vqnegq(vecSrc)); 75 /* 76 * Decrement the blockSize loop counter 77 */ 78 blkCnt--; 79 /* 80 * advance vector source and destination pointers 81 */ 82 pSrc += 8; 83 pDst += 8; 84 } 85 /* 86 * tail 87 */ 88 blkCnt = blockSize & 7; 89 if (blkCnt > 0U) 90 { 91 mve_pred16_t p0 = vctp16q(blkCnt); 92 vecSrc = vld1q(pSrc); 93 vstrhq_p(pDst, vqnegq(vecSrc), p0); 94 } 95 } 96 97 #else 98 void arm_negate_q15( 99 const q15_t * pSrc, 100 q15_t * pDst, 101 uint32_t blockSize) 102 { 103 uint32_t blkCnt; /* Loop counter */ 104 q15_t in; /* Temporary input variable */ 105 106 #if defined (ARM_MATH_LOOPUNROLL) 107 108 #if defined (ARM_MATH_DSP) 109 q31_t in1; /* Temporary input variables */ 110 #endif 111 112 /* Loop unrolling: Compute 4 outputs at a time */ 113 blkCnt = blockSize >> 2U; 114 115 while (blkCnt > 0U) 116 { 117 /* C = -A */ 118 119 #if defined (ARM_MATH_DSP) 120 /* Negate and store result in destination buffer (2 samples at a time). */ 121 in1 = read_q15x2_ia (&pSrc); 122 write_q15x2_ia (&pDst, __QSUB16(0, in1)); 123 124 in1 = read_q15x2_ia (&pSrc); 125 write_q15x2_ia (&pDst, __QSUB16(0, in1)); 126 #else 127 in = *pSrc++; 128 *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; 129 130 in = *pSrc++; 131 *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; 132 133 in = *pSrc++; 134 *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; 135 136 in = *pSrc++; 137 *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; 138 #endif 139 140 /* Decrement loop counter */ 141 blkCnt--; 142 } 143 144 /* Loop unrolling: Compute remaining outputs */ 145 blkCnt = blockSize % 0x4U; 146 147 #else 148 149 /* Initialize blkCnt with number of samples */ 150 blkCnt = blockSize; 151 152 #endif /* #if defined (ARM_MATH_LOOPUNROLL) */ 153 154 while (blkCnt > 0U) 155 { 156 /* C = -A */ 157 158 /* Negate and store result in destination buffer. */ 159 in = *pSrc++; 160 *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; 161 162 /* Decrement loop counter */ 163 blkCnt--; 164 } 165 166 } 167 #endif /* defined(ARM_MATH_MVEI) */ 168 169 /** 170 @} end of BasicNegate group 171 */