Part Number: MSP432P401R
Tool/software: TI C/C++ Compiler
Hi,
I was working with the CMSIS v5 DSPLib and noticed a difference in behavior when using the TI ARM Compiler v16.9.9.LTS versus the TI ARM Compiler v18.1.3.LTS.
I narrowed the issue down to the _sxtb16() intrinsic function:
Table 5-4 of ARM Optimizing C/C++ Compiler User's Guide
Section 4.6.186 of ARM Architecture Reference Manual Thumb-2 Supplement
Assembly code for correct implementation on TI ARM Compiler v16.9.9.LTS:
Assembly code for incorrect implementation on TI ARM Compiler v18.1.3.LTS
You can see the difference in the way the data is loaded with ldr or ldrsb.w. I've attached a main.c file with minimal code to reproduce the issue.
#include "msp.h" #include <stdint.h> #define __SIMD32_TYPE int32_t #define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) #define __SXTB16(VAL) ((unsigned int)_sxtb16(VAL, 0)) /** * \brief Rotate Right in unsigned value (32 bit) * \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. * \param [in] VAL Value to rotate * \param [in] SHIFT Number of Bits to rotate * \return Rotated value */ #define __ROR(VAL, SHIFT) ((unsigned int)__ror(VAL, SHIFT)) /** * @brief 32-bit fractional data type in 1.31 format. */ typedef int32_t q31_t; /** * @brief 16-bit fractional data type in 1.15 format. */ typedef int16_t q15_t; /** * @brief 8-bit fractional data type in 1.7 format. */ typedef int8_t q7_t; /** * main.c * * Converts an array of q7_t values to an array of q15_t values */ void main(void) { WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer q31_t in = 0x00000000; q31_t in1 = 0x00000000; q31_t in2 = 0x00000000; q15_t dst[4] = {0x0000}; q7_t src[4] = {0xD7, 0x0A, 0x00, 0x08}; q15_t *pDst = dst; const q7_t *pIn = src; /* Src pointer */ /* C = (q15_t) A << 8 */ /* convert from q7 to q15 and then store the results in the destination buffer */ in = *__SIMD32(pIn)++; /* rotate in by 8 and extend two q7_t values to q15_t values */ int ror8 = __ROR(in, 8); in1 = __SXTB16(ror8); // Expected output: 0x0008000A /* extend remainig two q7_t values to q15_t values */ in2 = __SXTB16(in); // Expected output: 0x0000FFD7 *__SIMD32(pDst)++ = in2; *__SIMD32(pDst)++ = in1; while(1); }
Can you verify if this is a real issue?
Best regards,
Caleb Overbay