diff --git a/os/ports/GCC/ARM7/chcore.h b/os/ports/GCC/ARM7/chcore.h index 09794da18..359ad3984 100644 --- a/os/ports/GCC/ARM7/chcore.h +++ b/os/ports/GCC/ARM7/chcore.h @@ -196,11 +196,11 @@ struct context { "stmfd sp!, {r0-r3, r12, lr} \n\t" \ "add r0, pc, #1 \n\t" \ "bx r0 \n\t" \ - ".code 16"); \ + ".code 16" : : : "memory"); \ } #else /* !THUMB */ #define PORT_IRQ_PROLOGUE() { \ - asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \ + asm volatile ("stmfd sp!, {r0-r3, r12, lr}" : : : "memory"); \ } #endif /* !THUMB */ @@ -214,11 +214,11 @@ struct context { #ifdef THUMB #define PORT_IRQ_EPILOGUE() { \ asm volatile ("ldr r0, =_port_irq_common \n\t" \ - "bx r0"); \ + "bx r0" : : : "memory"); \ } #else /* !THUMB */ #define PORT_IRQ_EPILOGUE() { \ - asm volatile ("b _port_irq_common"); \ + asm volatile ("b _port_irq_common" : : : "memory"); \ } #endif /* !THUMB */ @@ -252,10 +252,10 @@ struct context { */ #ifdef THUMB #define port_lock() { \ - asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \ + asm volatile ("bl _port_lock_thumb" : : : "r3", "lr", "memory" \ } #else /* !THUMB */ -#define port_lock() asm volatile ("msr CPSR_c, #0x9F") +#define port_lock() asm volatile ("msr CPSR_c, #0x9F" : : : "memory") #endif /* !THUMB */ /** @@ -266,10 +266,10 @@ struct context { */ #ifdef THUMB #define port_unlock() { \ - asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \ + asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr", "memory"); \ } #else /* !THUMB */ -#define port_unlock() asm volatile ("msr CPSR_c, #0x1F") +#define port_unlock() asm volatile ("msr CPSR_c, #0x1F" : : : "memory") #endif /* !THUMB */ /** @@ -299,7 +299,7 @@ struct context { */ #ifdef THUMB #define port_disable() { \ - asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \ + asm volatile ("bl _port_disable_thumb" : : : "r3", "lr", "memory"); \ } #else /* !THUMB */ #define port_disable() { \ @@ -307,7 +307,7 @@ struct context { "orr r3, #0x80 \n\t" \ "msr CPSR_c, r3 \n\t" \ "orr r3, #0x40 \n\t" \ - "msr CPSR_c, r3" : : : "r3"); \ + "msr CPSR_c, r3" : : : "r3", "memory"); \ } #endif /* !THUMB */ @@ -319,10 +319,10 @@ struct context { */ #ifdef THUMB #define port_suspend() { \ - asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \ + asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr", "memory"); \ } #else /* !THUMB */ -#define port_suspend() asm volatile ("msr CPSR_c, #0x9F") +#define port_suspend() asm volatile ("msr CPSR_c, #0x9F" : : : "memory") #endif /* !THUMB */ /** @@ -331,10 +331,10 @@ struct context { */ #ifdef THUMB #define port_enable() { \ - asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \ + asm volatile ("bl _port_enable_thumb" : : : "r3", "lr", "memory"); \ } #else /* !THUMB */ -#define port_enable() asm volatile ("msr CPSR_c, #0x1F") +#define port_enable() asm volatile ("msr CPSR_c, #0x1F" : : : "memory") #endif /* !THUMB */ /** diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 1158b35b7..d0d740d6f 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -77,8 +77,8 @@ void _port_switch_from_irq(void) { "push {r0, r1, lr} \n\t" "ldr r0, =_port_saved_pc \n\t" "ldr r0, [r0] \n\t" - "add r0, r0, #1 \n\t" - "str r0, [sp, #28]"); + "add r0, r0, #1 \n\t" + "str r0, [sp, #28]" : : : "memory"); chSchDoRescheduleI(); @@ -92,7 +92,7 @@ void _port_switch_from_irq(void) { "msr APSR, r0 \n\t" "mov lr, r2 \n\t" "cpsie i \n\t" - "pop {r0, r1, r2, r3, pc}"); + "pop {r0, r1, r2, r3, pc}" : : : "memory"); } #define PUSH_CONTEXT(sp) { \ @@ -101,7 +101,7 @@ void _port_switch_from_irq(void) { "mov r5, r9 \n\t" \ "mov r6, r10 \n\t" \ "mov r7, r11 \n\t" \ - "push {r4, r5, r6, r7}"); \ + "push {r4, r5, r6, r7}" : : : "memory"); \ } #define POP_CONTEXT(sp) { \ @@ -110,7 +110,7 @@ void _port_switch_from_irq(void) { "mov r9, r5 \n\t" \ "mov r10, r6 \n\t" \ "mov r11, r7 \n\t" \ - "pop {r4, r5, r6, r7, pc}" : : "r" (sp)); \ + "pop {r4, r5, r6, r7, pc}" : : "r" (sp) : "memory"); \ } /** diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index afe6fd5b7..53e8ef482 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -190,14 +190,14 @@ struct intctx { * @details Usually this function just disables interrupts but may perform * more actions. */ -#define port_lock() asm volatile ("cpsid i") +#define port_lock() asm volatile ("cpsid i" : : : "memory") /** * @brief Kernel-unlock action. * @details Usually this function just disables interrupts but may perform * more actions. */ -#define port_unlock() asm volatile ("cpsie i") +#define port_unlock() asm volatile ("cpsie i" : : : "memory") /** * @brief Kernel-lock action from an interrupt handler. @@ -220,17 +220,17 @@ struct intctx { /** * @brief Disables all the interrupt sources. */ -#define port_disable() asm volatile ("cpsid i") +#define port_disable() asm volatile ("cpsid i" : : : "memory") /** * @brief Disables the interrupt sources below kernel-level priority. */ -#define port_suspend() asm volatile ("cpsid i") +#define port_suspend() asm volatile ("cpsid i" : : : "memory") /** * @brief Enables all the interrupt sources. */ -#define port_enable() asm volatile ("cpsie i") +#define port_enable() asm volatile ("cpsie i" : : : "memory") /** * @brief Enters an architecture-dependent IRQ-waiting mode. @@ -241,7 +241,7 @@ struct intctx { * @note Implemented as an inlined @p WFI instruction. */ #if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) -#define port_wait_for_interrupt() asm volatile ("wfi") +#define port_wait_for_interrupt() asm volatile ("wfi" : : : "memory") #else #define port_wait_for_interrupt() #endif diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c index e1eb8df31..65bd7c110 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.c +++ b/os/ports/GCC/ARMCMx/chcore_v7m.c @@ -39,34 +39,38 @@ * @brief Internal context stacking. */ #define PUSH_CONTEXT() { \ - asm volatile ("push {r4, r5, r6, r7, r8, r9, r10, r11, lr}"); \ + asm volatile ("push {r4, r5, r6, r7, r8, r9, r10, r11, lr}" \ + : : : "memory"); \ } /** * @brief Internal context unstacking. */ #define POP_CONTEXT() { \ - asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}"); \ + asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}" \ + : : : "memory"); \ } #else /* defined(CH_CURRP_REGISTER_CACHE) */ #define PUSH_CONTEXT() { \ - asm volatile ("push {r4, r5, r6, r8, r9, r10, r11, lr}"); \ + asm volatile ("push {r4, r5, r6, r8, r9, r10, r11, lr}" \ + : : : "memory"); \ } #define POP_CONTEXT() { \ - asm volatile ("pop {r4, r5, r6, r8, r9, r10, r11, pc}"); \ + asm volatile ("pop {r4, r5, r6, r8, r9, r10, r11, pc}" \ + : : : "memory"); \ } #endif /* defined(CH_CURRP_REGISTER_CACHE) */ #if !CH_OPTIMIZE_SPEED void _port_lock(void) { register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); + asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); } void _port_unlock(void) { register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); + asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); } #endif @@ -96,9 +100,9 @@ void SVCallVector(void) { /* Discarding the current exception context and positioning the stack to point to the real one.*/ - asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); ctxp++; - asm volatile ("msr PSP, %0" : : "r" (ctxp)); + asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); port_unlock_from_isr(); } @@ -113,9 +117,9 @@ void _port_irq_epilogue(void) { /* Adding an artificial exception return context, there is no need to populate it fully.*/ - asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); + asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); ctxp--; - asm volatile ("msr PSP, %0" : : "r" (ctxp)); + asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); ctxp->pc = _port_switch_from_isr; ctxp->xpsr = (regarm_t)0x01000000; /* Note, returning without unlocking is intentional, this is done in diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h index 424422d7f..1effe66ec 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.h +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -169,11 +169,11 @@ struct intctx { #if CH_OPTIMIZE_SPEED #define port_lock() { \ register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ + asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \ } #else #define port_lock() { \ - asm volatile ("bl _port_lock" : : : "r3", "lr"); \ + asm volatile ("bl _port_lock" : : : "r3", "lr", "memory"); \ } #endif @@ -186,11 +186,11 @@ struct intctx { #if CH_OPTIMIZE_SPEED #define port_unlock() { \ register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \ + asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \ } #else #define port_unlock() { \ - asm volatile ("bl _port_unlock" : : : "r3", "lr"); \ + asm volatile ("bl _port_unlock" : : : "r3", "lr", "memory"); \ } #endif @@ -218,7 +218,7 @@ struct intctx { * @note In this port it disables all the interrupt sources by raising * the priority mask to level 0. */ -#define port_disable() asm volatile ("cpsid i") +#define port_disable() asm volatile ("cpsid i" : : : "memory") /** * @brief Disables the interrupt sources below kernel-level priority. @@ -228,7 +228,7 @@ struct intctx { #define port_suspend() { \ register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp)); \ + "cpsie i" : : "r" (tmp) : "memory"); \ } /** @@ -238,7 +238,7 @@ struct intctx { #define port_enable() { \ register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp)); \ + "cpsie i" : : "r" (tmp) : "memory"); \ } /** @@ -251,7 +251,7 @@ struct intctx { */ #if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) #define port_wait_for_interrupt() { \ - asm volatile ("wfi"); \ + asm volatile ("wfi" : : : "memory"); \ } #else #define port_wait_for_interrupt() diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h index 0034e29a1..87e036a21 100644 --- a/os/ports/GCC/AVR/chcore.h +++ b/os/ports/GCC/AVR/chcore.h @@ -242,7 +242,7 @@ struct context { * actions. * @note Implemented as global interrupt disable. */ -#define port_lock() asm volatile ("cli") +#define port_lock() asm volatile ("cli" : : : "memory") /** * @brief Kernel-unlock action. @@ -250,7 +250,7 @@ struct context { * actions. * @note Implemented as global interrupt enable. */ -#define port_unlock() asm volatile ("sei") +#define port_unlock() asm volatile ("sei" : : : "memory") /** * @brief Kernel-lock action from an interrupt handler. @@ -275,7 +275,7 @@ struct context { * @note Of course non maskable interrupt sources are not included. * @note Implemented as global interrupt disable. */ -#define port_disable() asm volatile ("cli") +#define port_disable() asm volatile ("cli" : : : "memory") /** * @brief Disables the interrupt sources below kernel-level priority. @@ -283,13 +283,13 @@ struct context { * @note Same as @p port_disable() in this port, there is no difference * between the two states. */ -#define port_suspend() asm volatile ("cli") +#define port_suspend() asm volatile ("cli" : : : "memory") /** * @brief Enables all the interrupt sources. * @note Implemented as global interrupt enable. */ -#define port_enable() asm volatile ("sei") +#define port_enable() asm volatile ("sei" : : : "memory") /** * @brief Enters an architecture-dependent IRQ-waiting mode. @@ -301,8 +301,8 @@ struct context { * reasons. */ #if ENABLE_WFI_IDLE != 0 -#define port_wait_for_interrupt() { \ - asm volatile ("sleep"); \ +#define port_wait_for_interrupt() { \ + asm volatile ("sleep" : : : "memory"); \ } #else #define port_wait_for_interrupt() diff --git a/os/ports/GCC/MSP430/chcore.c b/os/ports/GCC/MSP430/chcore.c index 8b6075a61..892f5e49b 100644 --- a/os/ports/GCC/MSP430/chcore.c +++ b/os/ports/GCC/MSP430/chcore.c @@ -59,7 +59,7 @@ void port_switch(Thread *ntp, Thread *otp) { "push r7 \n\t" \ "push r6 \n\t" \ "push r5 \n\t" \ - "push r4"); + "push r4" : : : "memory"); otp->p_ctx.sp = sp; sp = ntp->p_ctx.sp; asm volatile ("pop r4 \n\t" \ @@ -70,7 +70,7 @@ void port_switch(Thread *ntp, Thread *otp) { "pop r9 \n\t" \ "pop r10 \n\t" \ "pop r11 \n\t" \ - "ret" : : "r" (sp)); + "ret" : : "r" (sp) : "memory"); } /** diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h index d0300054e..fa44aeb31 100644 --- a/os/ports/GCC/MSP430/chcore.h +++ b/os/ports/GCC/MSP430/chcore.h @@ -209,7 +209,7 @@ struct context { * actions. * @note Implemented as global interrupt disable. */ -#define port_lock() asm volatile ("dint") +#define port_lock() asm volatile ("dint" : : : "memory") /** * @brief Kernel-unlock action. @@ -217,7 +217,7 @@ struct context { * actions. * @note Implemented as global interrupt enable. */ -#define port_unlock() asm volatile ("eint") +#define port_unlock() asm volatile ("eint" : : : "memory") /** * @brief Kernel-lock action from an interrupt handler. @@ -242,7 +242,7 @@ struct context { * @note Of course non maskable interrupt sources are not included. * @note Implemented as global interrupt disable. */ -#define port_disable() asm volatile ("dint") +#define port_disable() asm volatile ("dint" : : : "memory") /** * @brief Disables the interrupt sources below kernel-level priority. @@ -250,13 +250,13 @@ struct context { * @note Same as @p port_disable() in this port, there is no difference * between the two states. */ -#define port_suspend() asm volatile ("dint") +#define port_suspend() asm volatile ("dint" : : : "memory") /** * @brief Enables all the interrupt sources. * @note Implemented as global interrupt enable. */ -#define port_enable() asm volatile ("eint") +#define port_enable() asm volatile ("eint" : : : "memory") /** * @brief Enters an architecture-dependent IRQ-waiting mode. @@ -273,7 +273,7 @@ struct context { #if ENABLE_WFI_IDLE != 0 #ifndef port_wait_for_interrupt #define port_wait_for_interrupt() { \ - asm volatile ("nop"); \ + asm volatile ("nop" : : : "memory"); \ } #endif #else diff --git a/os/ports/GCC/PPC/chcore.h b/os/ports/GCC/PPC/chcore.h index bea28e0b1..979bdc7b3 100644 --- a/os/ports/GCC/PPC/chcore.h +++ b/os/ports/GCC/PPC/chcore.h @@ -270,12 +270,12 @@ struct context { /** * @details Implemented as global interrupt disable. */ -#define port_lock() asm ("wrteei 0") +#define port_lock() asm volatile ("wrteei 0" : : : "memory") /** * @details Implemented as global interrupt enable. */ -#define port_unlock() asm ("wrteei 1") +#define port_unlock() asm volatile("wrteei 1" : : : "memory") /** * @details Implemented as global interrupt disable. @@ -290,18 +290,18 @@ struct context { /** * @details Implemented as global interrupt disable. */ -#define port_disable() asm ("wrteei 0") +#define port_disable() asm volatile ("wrteei 0" : : : "memory") /** * @details Same as @p port_disable() in this port, there is no difference * between the two states. */ -#define port_suspend() asm ("wrteei 0") +#define port_suspend() asm volatile ("wrteei 0" : : : "memory") /** * @details Implemented as global interrupt enable. */ -#define port_enable() asm ("wrteei 1") +#define port_enable() asm volatile ("wrteei 1" : : : "memory") /** * @details This port function is implemented as inlined code for performance @@ -310,7 +310,7 @@ struct context { #if ENABLE_WFI_IDLE != 0 #ifndef port_wait_for_interrupt #define port_wait_for_interrupt() { \ - asm ("wait"); \ + asm volatile ("wait" : : : "memory"); \ } #endif #else diff --git a/readme.txt b/readme.txt index 79c19a358..3cb510610 100644 --- a/readme.txt +++ b/readme.txt @@ -59,6 +59,8 @@ ***************************************************************************** *** 2.0.4 *** +- FIX: Fixed potential issue with GCC reorganizing instructions around "asm + volatile" statements (bug 3058731). - FIX: Fixed reduced ARM7 performance with GCC 4.5.x (bug 3056866). *** 2.0.3 ***