-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cm3/cortex.h mixed bool/uint32_t usage #475
Comments
(TL;DR summary at the end) I think that the functions that get/set u32 values (PRIMASK and FAULTMASK, any others?) should not be cast to/from bool. While it's true that they probably always are 1-bit, the economy is extremely dubious (and premature, in any case), not future-proof, and in my opinion provides no improvement in clarity. For the 'register' keyword, I would agree that it should be irrelevant. Parsing the
**** however **** 1- with no optimizations, as expected the generated code is silly and implements quite literally what was written, i.e. a local variable on stack if the "register" keyword is removed. Interestingly, gcc spews 5 instructions before "cmp rn, 0" :
2- with -Os and -O2, gcc takes liberties and exposes an issue: in some cases, depending on the test code, it can optimize away some "MRS rn, primask" instructions if cm_is_masked_interrupts() is called multiple times in the same context / scope. This is most probably due to the lack of "volatile" keyword on the __asm line. From the gcc docs : 3- with -Os and -O2, the "register" keyword has no effect on the generated code. **** TL; DR summary ****
|
Seems like a gcc quirk, what does clang do when you do this? |
…erations could be optimized out by gcc. This adds the "volatile" keyword to all the inline assembly. gcc docs say "You can prevent an asm instruction from being deleted by writing the keyword volatile after the asm.". Testing (see comments of github issue libopencm3#475) shows that indeed gcc can remove some inline asm, in at least this situation: -multiple calls to cm_is_masked_interrupts() in the same scope/context - -Os or -O2 optimization This is problem because the value of PRIMASK could change between two calls to cm_is_masked_interrupts(). Adding the volatile keyword fixes this, and probably costs less than adding a full barrier (like adding "memory" to the clobber list).
A quick inspection of the libopencm3-examples repo shows only 1 use of the cm_* functions defined in cortex.h , in examples\stm32\f4\stm32f429i-discovery\usart_irq_console/usart_irq_console.c . However, for the functions named "cm_is_masked_*" , I think returning u32 is not ideal; the naming suggests a true/false result. Returning a u32 would fit better with names like "cm_get_intmask" and "cm_get_faultmask". In any case, I'll start with a less objectionable PR that only changes some of the functions to use u32. |
… of bool. This is more in line with the actual hardware (u32 registers), and will still work if PRIMASK or FAULTMASK ever have more than 1 bit defined. The functions cm_is_masked_interrupts() and cm_is_masked_faults() are unchanged, since returning 'bool' fits with the function naming. Fixes most of github issue libopencm3#475 . What remains "unfixed" is the absence of functions to simply 'get' the u32 value of PRIMASK and FAULTMASK registers.
This is more in line with the actual hardware (u32 registers), and will still work if PRIMASK or FAULTMASK ever have more than 1 bit defined. The functions cm_is_masked_interrupts() and cm_is_masked_faults() are unchanged, since returning 'bool' fits with the function naming. Fixes most of github issue #475. What remains "unfixed" is the absence of functions to simply 'get' the u32 value of PRIMASK and FAULTMASK registers.
…erations could be optimized out by gcc. This adds the "volatile" keyword to all the inline assembly. gcc docs say "You can prevent an asm instruction from being deleted by writing the keyword volatile after the asm.". Testing (see comments of github issue libopencm3#475) shows that indeed gcc can remove some inline asm, in at least this situation: -multiple calls to cm_is_masked_interrupts() in the same scope/context - -Os or -O2 optimization This is problem because the value of PRIMASK could change between two calls to cm_is_masked_interrupts(). Adding the volatile keyword fixes this, and probably costs less than adding a full barrier (like adding "memory" to the clobber list).
This is more in line with the actual hardware (u32 registers), and will still work if PRIMASK or FAULTMASK ever have more than 1 bit defined. The functions cm_is_masked_interrupts() and cm_is_masked_faults() are unchanged, since returning 'bool' fits with the function naming. Fixes most of github issue libopencm3#475. What remains "unfixed" is the absence of functions to simply 'get' the u32 value of PRIMASK and FAULTMASK registers.
As indicated in the comments for #323 there's some somewhat unusual mixes of bool and uint32_t in the cm3/cortex.h file.
Arguably, many of the bool types should be uint32_t, as they're dealing with registers anyway. Further, the register keyword is almost entirely irrelevant, but should probably be double checked with the inline asm.
The text was updated successfully, but these errors were encountered: