11#include <stdio.h>
22#include <stdlib.h>
3+ #include <assert.h>
4+
5+ /*
6+ This test bench is used to test various ARM Cortex-M instructions.
7+ If you want to test exact instruction, use inline assembly.
8+ If you want to test a general concept, use C code. The latter
9+ has downside of unpredictable compiler code generation.
10+ */
11+
12+ /*
13+
14+ Potentially useful defines lookup:
15+
16+ arm-none-eabi-gcc ... -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16
17+
18+ #define __VFP_FP__ 1
19+ #define __ARM_PCS_VFP 1
20+ #define __ARM_ARCH_PROFILE 77
21+ #define __ARM_ARCH_7EM__ 1
22+ #define __ARM_FEATURE_DSP 1
23+
24+
25+ */
26+
27+ #if defined(__ARM_PCS_VFP ) && defined(__VFP_FP__ )
28+ // Hard floating-point is enabled, and VFP instructions are available
29+ #define HARD_FLOATING_POINT_ENABLED 1
30+ #else
31+ // Hard floating-point is not enabled or VFP support is absent
32+ #define HARD_FLOATING_POINT_ENABLED 0
33+ #endif
34+
335
436#if __ARM_ARCH >= 7
537unsigned int bfc_0_32 (int value )
638{
7- asm volatile (
39+ asm volatile (
840 "bfc %[value], 0, 32"
9- : [value ] "+r" (value ));
41+ : [value ] "+r" (value ));
1042 return value ;
1143}
1244unsigned int bfc_0_16 (int value )
1345{
14- asm volatile (
46+ asm volatile (
1547 "bfc %[value], 0, 16"
16- : [value ] "+r" (value ));
48+ : [value ] "+r" (value ));
1749 return value ;
1850}
1951unsigned int bfc_15_16 (int value )
2052{
21- asm volatile (
53+ asm volatile (
2254 "bfc %[value], 15, 16"
23- : [value ] "+r" (value ));
55+ : [value ] "+r" (value ));
2456 return value ;
2557}
26- #endif
27- // [lsb] "I" (lsb), [width] "I" (width)
28- int main (void )
58+
59+ void bfc (void )
2960{
30-
31- #if __ARM_ARCH >= 7
61+ assert (bfc_0_32 (0xffffffff ) == 0xffffffff );
3262 printf ("bfc(0xffffffff, 0, 32) = 0x%08x\n" , bfc_0_32 (0xffffffff ));
3363 printf ("bfc(0xffffffff, 0, 16) = 0x%08x\n" , bfc_0_16 (0xffffffff ));
3464 printf ("bfc(0xffffffff, 15, 16) = 0x%08x\n" , bfc_15_16 (0xffffffff ));
35- #endif
65+ }
66+
67+ #endif
68+
69+ #if HARD_FLOATING_POINT_ENABLED
70+ float vabs (float value )
71+ {
72+ float result ;
73+
74+ asm volatile (
75+ "VABS.F32 %0, %1"
76+ : "=t" (result )
77+ : "t" (value ));
78+
79+ return result ;
80+ }
81+
82+ void floating_point (void )
83+ {
84+ // Try to generate floating-point data-processing instructions
85+ // VABS, VADD, VCMP, VCVT, VDIV, VFMA, VFNMA, VMAXNM
86+ // VMLA, VMOV, VMOV, VMUL, VNEG, VNMLA, VRINTA, VRINTZ
87+ // VSEL, VSQRT, VSUB
88+
89+ assert (vabs (-1.0f ) == 1.0f );
90+ assert (vabs (-42.0f ) == 42.0f );
91+ assert (vabs (0.0f ) == 0.0f );
92+ assert (vabs (1.0f ) == 1.0f );
93+ }
94+ #endif
95+ int main (void )
96+ {
97+
98+ #if __ARM_ARCH >= 7
99+ bfc ();
100+ #endif
101+
102+ #if HARD_FLOATING_POINT_ENABLED
103+ floating_point ();
104+ #endif
36105}
37106
38107void SystemInit (void )
@@ -48,5 +117,11 @@ void _start(void)
48117 exit (0 );
49118}
50119
51- __attribute__((used ))
52- void _fini (void ) { }
120+ __attribute__((used )) void _fini (void ) {}
121+
122+
123+ void __assert_func ( const char * filename , int line , const char * assert_func , const char * expr )
124+ {
125+ printf ("assert_failed: %s:%d\n" , filename , line );
126+ exit (1 );
127+ }
0 commit comments