1 /*-----------------------------------------------------------------------------
3 * Purpose: CMSIS CORE validation tests implementation
4 *-----------------------------------------------------------------------------
5 * Copyright (c) 2017 ARM Limited. All rights reserved.
6 *----------------------------------------------------------------------------*/
8 #include "CV_Framework.h"
11 #if defined(__CORTEX_M)
12 #elif defined(__CORTEX_A)
15 #error __CORTEX_M or __CORTEX_A must be defined!
18 /*-----------------------------------------------------------------------------
20 *----------------------------------------------------------------------------*/
22 /*-----------------------------------------------------------------------------
24 *----------------------------------------------------------------------------*/
26 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
28 \brief Test case: TC_CoreInstr_NOP
30 - Check if __NOP instrinsic is available
31 - No real assertion is deployed, just a compile time check.
33 void TC_CoreInstr_NOP (void) {
35 ASSERT_TRUE(1U == 1U);
38 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
40 \brief Test case: TC_CoreInstr_REV
42 - Check if __REV instrinsic swaps all bytes in a word.
44 void TC_CoreInstr_REV (void) {
45 uint32_t result = __REV(0x47110815U);
46 ASSERT_TRUE(result == 0x15081147U);
48 result = __REV(0x80000000U);
49 ASSERT_TRUE(result == 0x00000080U);
51 result = __REV(0x00000080U);
52 ASSERT_TRUE(result == 0x80000000U);
55 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
57 \brief Test case: TC_CoreInstr_REV16
59 - Check if __REV16 instrinsic swaps the bytes in both halfwords independendly.
61 void TC_CoreInstr_REV16(void) {
62 uint32_t result = __REV16(0x47110815U);
63 ASSERT_TRUE(result == 0x11471508U);
66 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
68 \brief Test case: TC_CoreInstr_REVSH
70 - Check if __REVSH instrinsic swaps bytes in a signed halfword keeping the sign.
72 void TC_CoreInstr_REVSH(void) {
73 int16_t result = __REVSH(0x4711);
74 ASSERT_TRUE(result == 0x1147);
76 result = __REVSH((int16_t)0x8000);
77 ASSERT_TRUE(result == 0x0080);
79 result = __REVSH(0x0080);
80 ASSERT_TRUE(result == (int16_t)0x8000);
83 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
85 \brief Test case: TC_CoreInstr_ROT
87 - Check if __ROR instrinsic moves all bits as expected.
89 void TC_CoreInstr_ROR(void) {
90 uint32_t result = __ROR(0x01U, 1U);
91 ASSERT_TRUE(result == 0x80000000U);
93 result = __ROR(0x80000000U, 1U);
94 ASSERT_TRUE(result == 0x40000000U);
96 result = __ROR(0x40000000U, 30U);
97 ASSERT_TRUE(result == 0x00000001U);
99 result = __ROR(0x01U, 32U);
100 ASSERT_TRUE(result == 0x00000001U);
102 result = __ROR(0x08154711U, 8U);
103 ASSERT_TRUE(result == 0x11081547U);
106 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
108 \brief Test case: TC_CoreInstr_RBIT
110 - Check if __RBIT instrinsic revserses the bit order of arbitrary words.
112 void TC_CoreInstr_RBIT (void) {
113 uint32_t result = __RBIT(0xAAAAAAAAU);
114 ASSERT_TRUE(result == 0x55555555U);
116 result = __RBIT(0x55555555U);
117 ASSERT_TRUE(result == 0xAAAAAAAAU);
119 result = __RBIT(0x00000001U);
120 ASSERT_TRUE(result == 0x80000000U);
122 result = __RBIT(0x80000000U);
123 ASSERT_TRUE(result == 0x00000001U);
125 result = __RBIT(0xDEADBEEFU);
126 ASSERT_TRUE(result == 0xF77DB57BU);
129 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
131 \brief Test case: TC_CoreInstr_CLZ
133 - Check if __CLZ instrinsic counts leading zeros.
135 void TC_CoreInstr_CLZ (void) {
136 uint32_t result = __CLZ(0x00U);
137 ASSERT_TRUE(result == 32);
139 result = __CLZ(0x00000001U);
140 ASSERT_TRUE(result == 31);
142 result = __CLZ(0x40000000U);
143 ASSERT_TRUE(result == 1);
145 result = __CLZ(0x80000000U);
146 ASSERT_TRUE(result == 0);
148 result = __CLZ(0xFFFFFFFFU);
149 ASSERT_TRUE(result == 0);
151 result = __CLZ(0x80000001U);
152 ASSERT_TRUE(result == 0);
155 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
156 #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
157 (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
158 (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
159 (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
160 (defined(__CORTEX_A) ) )
162 /// Exclusive byte value
163 static volatile uint8_t TC_CoreInstr_Exclusives_byte = 0x47U;
165 /// Exclusive halfword value
166 static volatile uint16_t TC_CoreInstr_Exclusives_hword = 0x0815U;
168 /// Exclusive word value
169 static volatile uint32_t TC_CoreInstr_Exclusives_word = 0x08154711U;
172 \brief Interrupt function for TC_CoreInstr_Exclusives
174 The interrupt manipulates all the global data
175 which disrupts the exclusive sequences in the test
177 static void TC_CoreInstr_ExclusivesIRQHandler(void) {
178 const uint8_t b = __LDREXB(&TC_CoreInstr_Exclusives_byte);
179 __STREXB((uint8_t)~b, &TC_CoreInstr_Exclusives_byte);
180 const uint16_t hw = __LDREXH(&TC_CoreInstr_Exclusives_hword);
181 __STREXH((uint16_t)~hw, &TC_CoreInstr_Exclusives_hword);
182 const uint32_t w = __LDREXW(&TC_CoreInstr_Exclusives_word);
183 __STREXW((uint32_t)~w, &TC_CoreInstr_Exclusives_word);
187 \brief Helper function for TC_CoreInstr_Exclusives to enable test interrupt.
189 This helper function implements interrupt enabling according to target
190 architecture, i.e. Cortex-A or Cortex-M.
192 static void TC_CoreInstr_ExclusivesIRQEnable(void) {
193 #if defined(__CORTEX_M)
194 TST_IRQHandler = TC_CoreInstr_ExclusivesIRQHandler;
195 NVIC_EnableIRQ(WDT_IRQn);
196 #elif defined(__CORTEX_A)
197 IRQ_SetHandler(SGI0_IRQn, TC_CoreInstr_ExclusivesIRQHandler);
198 IRQ_Enable(SGI0_IRQn);
200 #error __CORTEX_M or __CORTEX_A must be defined!
206 \brief Helper function for TC_CoreInstr_Exclusives to set test interrupt pending.
208 This helper function implements set pending the test interrupt according to target
209 architecture, i.e. Cortex-A or Cortex-M.
211 static void TC_CoreInstr_ExclusivesIRQPend(void) {
212 #if defined(__CORTEX_M)
213 NVIC_SetPendingIRQ(WDT_IRQn);
214 #elif defined(__CORTEX_A)
215 IRQ_SetPending(SGI0_IRQn);
217 #error __CORTEX_M or __CORTEX_A must be defined!
219 for(uint32_t i = 10U; i > 0U; --i) {}
223 \brief Helper function for TC_CoreInstr_Exclusives to disable test interrupt.
225 This helper function implements interrupt disabling according to target
226 architecture, i.e. Cortex-A or Cortex-M.
228 static void TC_CoreInstr_ExclusivesIRQDisable(void) {
230 #if defined(__CORTEX_M)
231 NVIC_DisableIRQ(WDT_IRQn);
232 TST_IRQHandler = NULL;
233 #elif defined(__CORTEX_A)
234 IRQ_Disable(SGI0_IRQn);
235 IRQ_SetHandler(SGI0_IRQn, NULL);
237 #error __CORTEX_M or __CORTEX_A must be defined!
242 \brief Test case: TC_CoreInstr_Exclusives
244 Checks exclusive load and store instructions:
245 - LDREXB, LDREXH, LDREXW
246 - STREXB, STREXH, STREXW
249 void TC_CoreInstr_Exclusives (void) {
250 /* 1. Test exclusives without interruption */
252 const uint8_t v = __LDREXB(&TC_CoreInstr_Exclusives_byte);
253 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_byte);
255 const uint32_t result = __STREXB(v+1U, &TC_CoreInstr_Exclusives_byte);
256 ASSERT_TRUE(result == 0U);
257 ASSERT_TRUE(TC_CoreInstr_Exclusives_byte == v+1U);
261 const uint16_t v = __LDREXH(&TC_CoreInstr_Exclusives_hword);
262 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_hword);
264 const uint32_t result = __STREXH(v+1U, &TC_CoreInstr_Exclusives_hword);
265 ASSERT_TRUE(result == 0U);
266 ASSERT_TRUE(TC_CoreInstr_Exclusives_hword == v+1U);
270 const uint32_t v = __LDREXW(&TC_CoreInstr_Exclusives_word);
271 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_word);
273 const uint32_t result = __STREXW(v+1U, &TC_CoreInstr_Exclusives_word);
274 ASSERT_TRUE(result == 0U);
275 ASSERT_TRUE(TC_CoreInstr_Exclusives_word == v+1U);
278 /* 2. Test exclusives with clear */
280 const uint8_t v = __LDREXB(&TC_CoreInstr_Exclusives_byte);
281 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_byte);
285 const uint32_t result = __STREXB(v+1U, &TC_CoreInstr_Exclusives_byte);
286 ASSERT_TRUE(result == 1U);
287 ASSERT_TRUE(TC_CoreInstr_Exclusives_byte == v);
291 const uint16_t v = __LDREXH(&TC_CoreInstr_Exclusives_hword);
292 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_hword);
296 const uint32_t result = __STREXH(v+1U, &TC_CoreInstr_Exclusives_hword);
297 ASSERT_TRUE(result == 1U);
298 ASSERT_TRUE(TC_CoreInstr_Exclusives_hword == v);
302 const uint32_t v = __LDREXW(&TC_CoreInstr_Exclusives_word);
303 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_word);
307 const uint32_t result = __STREXW(v+1U, &TC_CoreInstr_Exclusives_word);
308 ASSERT_TRUE(result == 1U);
309 ASSERT_TRUE(TC_CoreInstr_Exclusives_word == v);
312 /* 3. Test exclusives with interruption */
314 TC_CoreInstr_ExclusivesIRQEnable();
317 const uint8_t v = __LDREXB(&TC_CoreInstr_Exclusives_byte);
318 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_byte);
320 TC_CoreInstr_ExclusivesIRQPend();
322 const uint32_t result = __STREXB(v+1U, &TC_CoreInstr_Exclusives_byte);
323 ASSERT_TRUE(result == 1U);
324 ASSERT_TRUE(TC_CoreInstr_Exclusives_byte == (uint8_t)~v);
328 const uint16_t v = __LDREXH(&TC_CoreInstr_Exclusives_hword);
329 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_hword);
331 TC_CoreInstr_ExclusivesIRQPend();
333 const uint32_t result = __STREXH(v+1U, &TC_CoreInstr_Exclusives_hword);
334 ASSERT_TRUE(result == 1U);
335 ASSERT_TRUE(TC_CoreInstr_Exclusives_hword == (uint16_t)~v);
339 const uint32_t v = __LDREXW(&TC_CoreInstr_Exclusives_word);
340 ASSERT_TRUE(v == TC_CoreInstr_Exclusives_word);
342 TC_CoreInstr_ExclusivesIRQPend();
344 const uint32_t result = __STREXW(v+1U, &TC_CoreInstr_Exclusives_word);
345 ASSERT_TRUE(result == 1U);
346 ASSERT_TRUE(TC_CoreInstr_Exclusives_word == ~v);
349 TC_CoreInstr_ExclusivesIRQDisable();
353 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
355 \brief Test case: TC_CoreInstr_SSAT
357 - Check if __SSAT instrinsic saturates signed integer values.
359 void TC_CoreInstr_SSAT (void) {
360 int32_t result = __SSAT(INT32_MAX, 32U);
361 ASSERT_TRUE(result == INT32_MAX);
363 result = __SSAT(INT32_MAX, 16U);
364 ASSERT_TRUE(result == INT16_MAX);
366 result = __SSAT(INT32_MAX, 8U);
367 ASSERT_TRUE(result == INT8_MAX);
369 result = __SSAT(INT32_MAX, 1U);
370 ASSERT_TRUE(result == 0);
372 result = __SSAT(INT32_MIN, 32U);
373 ASSERT_TRUE(result == INT32_MIN);
375 result = __SSAT(INT32_MIN, 16U);
376 ASSERT_TRUE(result == INT16_MIN);
378 result = __SSAT(INT32_MIN, 8U);
379 ASSERT_TRUE(result == INT8_MIN);
381 result = __SSAT(INT32_MIN, 1U);
382 ASSERT_TRUE(result == -1);
385 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
387 \brief Test case: TC_CoreInstr_USAT
389 - Check if __USAT instrinsic saturates unsigned integer values.
391 void TC_CoreInstr_USAT (void) {
392 uint32_t result = __USAT(INT32_MAX, 31U);
393 ASSERT_TRUE(result == (UINT32_MAX>>1U));
395 result = __USAT(INT32_MAX, 16U);
396 ASSERT_TRUE(result == UINT16_MAX);
398 result = __USAT(INT32_MAX, 8U);
399 ASSERT_TRUE(result == UINT8_MAX);
401 result = __USAT(INT32_MAX, 0U);
402 ASSERT_TRUE(result == 0U);
404 result = __USAT(INT32_MIN, 31U);
405 ASSERT_TRUE(result == 0U);
407 result = __USAT(INT32_MIN, 16U);
408 ASSERT_TRUE(result == 0U);
410 result = __USAT(INT32_MIN, 8U);
411 ASSERT_TRUE(result == 0U);
413 result = __USAT(INT32_MIN, 0U);
414 ASSERT_TRUE(result == 0U);