Hello,
I am looking to do a moving average function using DSP instructions of ARM Cortex M7. Unfortunately I couldn't find a direct example. My goal is to have variables for
- the sum
- the new value
- the oldest value
Then the algorithm is sum = sum + new value - oldest value and average = sum / ( number of values between oldest and new), ie two instructions
I think instruction UMAAL could be good for this, I found it in instruction set summary, but it is not in CMSIS library. Why is that? Where can I find details about it and how can I create my own C asm caller?
Thanks for any help and hints or other ideas on this topic, I hope it also helps other developers.
Kind regards
Martin
It seems that you are looking for a compiler intrinsic for the umaal instruction. The manual of the compiler should contain the list of intrinsics it supports.
If it is not supported, then one must rely on the assembler/inline-assembly and write it by hand.
Yes, I am looking for a compiler intrinsic for the umaal instruction.
You leave me a bit confused. I thought that exactly that, providing high level access to low level core functions, was the purpose of ARMs CMSIS. There is a CMSIS header file for GCC with an ARM copyright notice at the top:
/**************************************************************************//** * @file cmsis_gcc.h * @brief CMSIS compiler GCC header file * @version V5.0.1 * @date 02. February 2017 ******************************************************************************/ /* * Copyright (c) 2009-2017 ARM Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
But this file does not contain an umaal function. So I wanted to ask if there are special reasons for this. If I have to write it myself I would like to ask for more information about umaal. I only found it in instruction set summary. Where can I find a detailed description, telling me which register to feed with what data?
Thanks again
I am not sure if CMSIS would provide intrinsics for every instruction. From its headers, it seems that they provide wrappers for certain SIMD instructions.
CMSIS supports iccarm compiler (where iccarm does indeed support __umaal as an intrinsic function), but CMSIS still does not expose it in its cmsis_iccarm.h. For such a compiler, it is quite easy to expose the required function by defining as below (or something similar). The signature of the function should be available with the compiler's manual.
#define __UMAAL __iar_builtin_UMAAL
TI's CCS compiler too provides the function.
As for gcc, cmsis_gcc.h has most of the instructions hand-written using inline-assembly, including a few simple ones such as wfe/wfi. It is unlikely that gcc has the required function builtin. But one can attempt to provide one by hand.
The description the instruction is here. Accordingly, the operation can be roughly written as below (as if embedding it inside the cmsis_gcc.h file).
__STATIC_FORCEINLINE uint64_t __UMAAL(uint64_t acc, uint32_t rn, uint32_t rm) { uint32_t lo, hi; lo = acc; hi = acc >> 32; __ASM volatile ("umaal %0, %1, %2, %3" : "+r" (lo), "+r" (hi) : "r" (rn), "r" (rm)); acc = hi; acc <<= 32; acc |= lo; return acc; }
Edit: Replaced "=r" to "+r".
thanks for your answer, it gave valuable information and helped me along