diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 7523e45a4d..ee878af3b5 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -148,22 +148,6 @@ char *thread_stack_init(thread_task_func_t task_func, *stk = ~((uint32_t)STACK_MARKER); } -#if defined(CPU_ARCH_CORTEX_M4F) || (CPU_ARCH_CORTEX_M7) - /* TODO: fix FPU handling for Cortex-M4f */ - /* - stk--; - *stk = (unsigned int) 0; - */ - - /* S0 - S15 */ - /* - for (int i = 15; i >= 0; i--) { - stk--; - *stk = i; - } - */ -#endif - /* ****************************** */ /* Automatically popped registers */ /* ****************************** */ @@ -299,7 +283,7 @@ void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) { __asm__ volatile ( /* PendSV handler entry point */ /* save context by pushing unsaved registers to the stack */ - /* {r0-r3,r12,LR,PC,xPSR} are saved automatically on exception entry */ + /* {r0-r3,r12,LR,PC,xPSR,s0-s15,FPSCR} are saved automatically on exception entry */ ".thumb_func \n" "mrs r0, psp \n" /* get stack pointer from user mode */ #if defined(CPU_ARCH_CORTEX_M0) || defined(CPU_ARCH_CORTEX_M0PLUS) @@ -317,11 +301,13 @@ void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) { "mov r0, sp \n" /* switch back to the exception SP */ "mov sp, r12 \n" #else +#if (defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7)) && defined(MODULE_CORTEXM_FPU) + "tst lr, #0x10 \n" + "it eq \n" + "vstmdbeq r0!, {s16-s31} \n" /* save FPU registers if FPU is used */ +#endif "stmdb r0!,{r4-r11} \n" /* save regs */ "stmdb r0!,{lr} \n" /* exception return value */ -#if defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) -/* "vstmdb sp!, {s16-s31} \n" */ /* TODO save FPU registers */ -#endif #endif "ldr r1, =sched_active_thread \n" /* load address of current tcb */ "ldr r1, [r1] \n" /* dereference pdc */ @@ -364,14 +350,16 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) { "ldr r0, [r0] \n" /* dereference TCB */ "ldr r1, [r0] \n" /* load tcb->sp to register 1 */ "ldmia r1!, {r0} \n" /* restore exception return value */ -#if defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7) -/* "pop {s16-s31} \n" */ /* TODO load FPU registers */ -#endif "ldmia r1!, {r4-r11} \n" /* restore other registers */ +#if (defined(CPU_ARCH_CORTEX_M4F) || defined(CPU_ARCH_CORTEX_M7)) && defined(MODULE_CORTEXM_FPU) + "tst r0, #0x10 \n" + "it eq \n" + "vldmiaeq r1!, {s16-s31} \n" /* load FPU registers if saved */ +#endif "msr psp, r1 \n" /* restore user mode SP to PSP reg */ "bx r0 \n" /* load exception return value to PC, * causes end of exception*/ #endif - /* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */ + /* {r0-r3,r12,LR,PC,xPSR,s0-s15,FPSCR} are restored automatically on exception return */ ); } diff --git a/makefiles/arch/cortexm.inc.mk b/makefiles/arch/cortexm.inc.mk index 6a29f27a19..617afc5ad2 100644 --- a/makefiles/arch/cortexm.inc.mk +++ b/makefiles/arch/cortexm.inc.mk @@ -63,14 +63,29 @@ ARCH = $(shell echo $(CPU_ARCH) | tr 'a-z-' 'A-Z_') export CFLAGS += -DCPU_ARCH_$(ARCH) # set the compiler specific CPU and FPU options -ifeq ($(CPU_ARCH),cortex-m4f) -# TODO: enable hard floating points for the M4F once the context save/restore -# code is adjusted to take care of FPU registers -#export CFLAGS_FPU += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -export MCPU := cortex-m4 -endif +ifneq (,$(filter $(CPU_ARCH),cortex-m4f cortex-m7)) + ifneq (,$(filter cortexm_fpu,$(DISABLE_MODULE))) + export CFLAGS_FPU ?= -mfloat-abi=soft + else + USEMODULE += cortexm_fpu + # clang assumes there is an FPU + ifneq (llvm,$(TOOLCHAIN)) + ifeq ($(CPU_ARCH),cortex-m7) + export CFLAGS_FPU ?= -mfloat-abi=hard -mfpu=fpv5-d16 + else + export CFLAGS_FPU ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 + endif + endif + endif + ifeq ($(CPU_ARCH),cortex-m4f) + export MCPU := cortex-m4 + else + export MCPU ?= $(CPU_ARCH) + endif +else CFLAGS_FPU ?= -mfloat-abi=soft export MCPU ?= $(CPU_ARCH) +endif # CMSIS DSP needs to know about the CPU core ifneq (,$(filter cmsis-dsp,$(USEPKG))) diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 497dbdb71e..3de942f165 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -8,6 +8,7 @@ PSEUDOMODULES += conn_can_isotp_multi PSEUDOMODULES += cord_ep_standalone PSEUDOMODULES += cord_epsim_standalone PSEUDOMODULES += core_% +PSEUDOMODULES += cortexm_fpu PSEUDOMODULES += ecc_% PSEUDOMODULES += emb6_router PSEUDOMODULES += event_%