1 /*
2  * Copyright (c) 2017-2024 IAR Systems
3  * Copyright (c) 2018-2023 Arm Limited. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the License); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 /*
21  * CMSIS-Core(A) Compiler ICCARM (IAR Compiler for Arm) Header File
22  */
23 
24 #ifndef __CMSIS_ICCARM_A_H__
25 #define __CMSIS_ICCARM_A_H__
26 
27 #ifndef __ICCARM__
28   #error This file should only be compiled by ICCARM
29 #endif
30 
31 #pragma system_include
32 
33 #define __get_CPSR()                (__arm_rsr("CPSR"))
34 #define __get_mode()                (__get_CPSR() & 0x1FU)
35 
36 #define __set_CPSR(VALUE)           (__arm_wsr("CPSR", (VALUE)))
37 #define __set_mode(VALUE)           (__arm_wsr("CPSR_c", (VALUE)))
38 
39 
40 #if (defined (__ARM_FP)      && (__ARM_FP >= 1))
41   #define __get_FPEXC() (__arm_rsr("FPEXC"))
42   #define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE))
43 #else
44   #define __get_FPEXC()             ( 0 )
45   #define __set_FPEXC(VALUE)        ((void)VALUE)
46 #endif
47 
48 #define __get_CP(cp, op1, RT, CRn, CRm, op2) \
49   ((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2))
50 
51 #define __set_CP(cp, op1, RT, CRn, CRm, op2) \
52   (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT)))
53 
54 #define __get_CP64(cp, op1, Rt, CRm) \
55   __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : "=r" (Rt) : : "memory" )
56 
57 #define __set_CP64(cp, op1, Rt, CRm) \
58   __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm  : : "r" (Rt) : "memory" )
59 
60 #include "cmsis_cp15.h"
61 
__get_SP_usr(void)62 __IAR_FT uint32_t __get_SP_usr(void)
63 {
64   uint32_t cpsr;
65   uint32_t result;
66   __ASM volatile(
67     "MRS     %0, cpsr   \n"
68     "CPS     #0x1F      \n" // no effect in USR mode
69     "MOV     %1, sp     \n"
70     "MSR     cpsr_c, %2 \n" // no effect in USR mode
71     "ISB" :  "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
72    );
73   return result;
74 }
75 
__set_SP_usr(uint32_t topOfProcStack)76 __IAR_FT void __set_SP_usr(uint32_t topOfProcStack)
77 {
78   uint32_t cpsr;
79   __ASM volatile(
80     "MRS     %0, cpsr   \n"
81     "CPS     #0x1F      \n" // no effect in USR mode
82     "MOV     sp, %1     \n"
83     "MSR     cpsr_c, %2 \n" // no effect in USR mode
84     "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
85    );
86 }
87 
88 #define __get_mode()                (__get_CPSR() & 0x1FU)
89 
90 __STATIC_INLINE
__FPU_Enable(void)91 void __FPU_Enable(void)
92 {
93   __ASM volatile(
94     //Permit access to VFP/NEON, registers by modifying CPACR
95     "        MRC     p15,0,R1,c1,c0,2  \n"
96     "        ORR     R1,R1,#0x00F00000 \n"
97     "        MCR     p15,0,R1,c1,c0,2  \n"
98 
99     //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
100     "        ISB                       \n"
101 
102     //Enable VFP/NEON
103     "        VMRS    R1,FPEXC          \n"
104     "        ORR     R1,R1,#0x40000000 \n"
105     "        VMSR    FPEXC,R1          \n"
106 
107     //Initialise VFP/NEON registers to 0
108     "        MOV     R2,#0             \n"
109 
110     //Initialise D16 registers to 0
111     "        VMOV    D0, R2,R2         \n"
112     "        VMOV    D1, R2,R2         \n"
113     "        VMOV    D2, R2,R2         \n"
114     "        VMOV    D3, R2,R2         \n"
115     "        VMOV    D4, R2,R2         \n"
116     "        VMOV    D5, R2,R2         \n"
117     "        VMOV    D6, R2,R2         \n"
118     "        VMOV    D7, R2,R2         \n"
119     "        VMOV    D8, R2,R2         \n"
120     "        VMOV    D9, R2,R2         \n"
121     "        VMOV    D10,R2,R2         \n"
122     "        VMOV    D11,R2,R2         \n"
123     "        VMOV    D12,R2,R2         \n"
124     "        VMOV    D13,R2,R2         \n"
125     "        VMOV    D14,R2,R2         \n"
126     "        VMOV    D15,R2,R2         \n"
127 
128 #ifdef __ARM_ADVANCED_SIMD__
129     //Initialise D32 registers to 0
130     "        VMOV    D16,R2,R2         \n"
131     "        VMOV    D17,R2,R2         \n"
132     "        VMOV    D18,R2,R2         \n"
133     "        VMOV    D19,R2,R2         \n"
134     "        VMOV    D20,R2,R2         \n"
135     "        VMOV    D21,R2,R2         \n"
136     "        VMOV    D22,R2,R2         \n"
137     "        VMOV    D23,R2,R2         \n"
138     "        VMOV    D24,R2,R2         \n"
139     "        VMOV    D25,R2,R2         \n"
140     "        VMOV    D26,R2,R2         \n"
141     "        VMOV    D27,R2,R2         \n"
142     "        VMOV    D28,R2,R2         \n"
143     "        VMOV    D29,R2,R2         \n"
144     "        VMOV    D30,R2,R2         \n"
145     "        VMOV    D31,R2,R2         \n"
146 #endif
147 
148     //Initialise FPSCR to a known state
149     "        VMRS    R1,FPSCR          \n"
150     "        MOV32   R2,#0x00086060    \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
151     "        AND     R1,R1,R2          \n"
152     "        VMSR    FPSCR,R1          \n"
153     : : : "cc", "r1", "r2"
154   );
155 }
156 
157 
158 
159 #undef __IAR_FT
160 #undef __ICCARM_V8
161 
162 #pragma diag_default=Pe940
163 #pragma diag_default=Pe177
164 
165 #endif /* __CMSIS_ICCARM_A_H__ */
166