SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_arch_arm-cortex-m-asm.h
Go to the documentation of this file.
1/*
2 * SuperTinyKernel(TM) RTOS: Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3 *
4 * Source: https://github.com/SuperTinyKernel-RTOS
5 *
6 * Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7 * License: MIT License, see LICENSE for a full text.
8 */
9
10#ifndef STK_ARCH_ARM_CORTEX_M_ASM_H_
11#define STK_ARCH_ARM_CORTEX_M_ASM_H_
12
13#include "stk_config.h"
14
15// Inline ASM helpers:
16#ifdef __ICCARM__
17 #define STK_ASM_SYNTAX_UNIFIED /* IAR: not needed, unified is default */
18 #define STK_ASM_POOL /* IAR: not needed, handled automatically */
19 #define STK_ASM_ALIGN_2 /* IAR: not needed */
20#else
21 #define STK_ASM_SYNTAX_UNIFIED ".syntax unified \n"
22 #define STK_ASM_POOL ".pool \n"
23 #define STK_ASM_ALIGN_2 ".align 2 \n"
24#endif
25
30#if defined(__ICCARM__)
31 // IAR automatically exports symbol labels in inline assembly; directive is omitted
32 #define STK_ASM_GLOBAL_SYMBOL(name)
33#else
34 // GCC, Clang, and Keil armclang (ARMCC v6+)
35 #define STK_ASM_GLOBAL_SYMBOL(name) ".global " #name "\n"
36#endif
37
38#ifdef _STK_CORTEX_M_TRUSTZONE
39/* ARMv8-M TrustZone (Cortex-M33 / Mainline)
40 EXC_RETURN bit layout (ARMv8-M ARM B1.5.8):
41 bit 6 (0x40): 1 = Secure stack, 0 = Non-Secure stack. <-- S-bit
42 bit 2 (0x04): 1 = PSP, 0 = MSP.
43 We test bit 6 first to select the correct world's stack pointer,
44 then bit 2 to choose MSP vs PSP within that world. */
45#if (__CORTEX_M >= 33U)
46/* -----------------------------------------------------------------
47 Cortex-M33 and later (ARMv8-M Mainline) -- IT/ITE available.
48 ----------------------------------------------------------------- */
49#define STK_ASM_EXTRACT_STACK_POINTER_TO_R0 \
50 "TST LR, #4 \n" /* bit 2: 0 = MSP, 1 = PSP */ \
51 "BNE 1f \n" \
52 /* --- MSP branch --- */ \
53 "TST LR, #64 \n" /* bit 6 (S-bit): 1 = Secure, 0 = Non-Secure */ \
54 "ITE NE \n" \
55 "MRSNE r0, MSP \n" /* r0 = Secure MSP */ \
56 "MRSEQ r0, MSP_NS \n" /* r0 = Non-Secure MSP */ \
57 "B 2f \n" \
58 "1: \n" \
59 "TST LR, #64 \n" /* bit 6 (S-bit): 1 = Secure, 0 = Non-Secure */ \
60 "ITE NE \n" \
61 "MRSNE r0, PSP \n" /* r0 = Secure PSP */ \
62 "MRSEQ r0, PSP_NS \n" /* r0 = Non-Secure PSP */ \
63 "2: \n"
64#else
65/* -----------------------------------------------------------------
66 Cortex-M23 (ARMv8-M Baseline) -- no IT instructions, limited ISA.
67 Shift bits into the sign position and use BMI (Branch if Minus).
68 bit 2 -> sign: LSLS r1, #29 (32 - 3 = 29)
69 bit 6 -> sign: LSLS r1, #25 (32 - 7 = 25)
70 ----------------------------------------------------------------- */
71#define STK_ASM_EXTRACT_STACK_POINTER_TO_R0 \
72 "MOV r1, LR \n" \
73 "LSLS r1, r1, #29 \n" /* shift bit 2 into sign */ \
74 "BMI 3f \n" /* bit 2 set -> PSP branch */ \
75 /* --- MSP branch --- */ \
76 "MOV r1, LR \n" \
77 "LSLS r1, r1, #25 \n" /* shift bit 6 (S-bit) into sign */ \
78 "BMI 4f \n" /* S=1 -> Secure MSP */ \
79 "MRS r0, MSP_NS \n" /* S=0 -> Non-Secure MSP */ \
80 "B 2f \n" \
81 "4: \n" \
82 "MRS r0, MSP \n" /* r0 = Secure MSP */ \
83 "B 2f \n" \
84 "3: \n" \
85 "MOV r1, LR \n" \
86 "LSLS r1, r1, #25 \n" /* shift bit 6 (S-bit) into sign */ \
87 "BMI 5f \n" /* S=1 -> Secure PSP */ \
88 "MRS r0, PSP_NS \n" /* S=0 -> Non-Secure PSP */ \
89 "B 2f \n" \
90 "5: \n" \
91 "MRS r0, PSP \n" /* r0 = Secure PSP */ \
92 "2: \n"
93#endif
94#elif (__CORTEX_M >= 3U)
95/* Cortex-M3/M4/M7 */
96#define STK_ASM_EXTRACT_STACK_POINTER_TO_R0 \
97 "TST LR, #4 \n" /* check EXC_RETURN bit 2 */ \
98 "ITE EQ \n" \
99 "MRSEQ r0, MSP \n" /* r0 = MSP */ \
100 "MRSNE r0, PSP \n" /* else r0 = PSP */
101#else
102/* Cortex-M0/M0+ (limited ISA) */
103#define STK_ASM_EXTRACT_STACK_POINTER_TO_R0 \
104 "MOV r0, LR \n" /* r0 = LR */ \
105 "LSLS r0, r0, #29 \n" /* if (r0 & 4) */ \
106 "BMI 6f \n" /* else */ \
107 "MRS r0, MSP \n" /* r0 = MSP */ \
108 "B 7f \n" \
109 "6: \n" \
110 "MRS r0, PSP \n" /* else r0 = PSP */ \
111 "7: \n"
112#endif
113
114#endif /* STK_ARCH_ARM_CORTEX_M_H_ */