Hi, I'm using __asm on a cortex-m4 to enable/disable/restore interrupts. I have defined a couple of macros to manipulate registers only available by using the msr/mrs opcodes: > #define mrs(x) ({ \ > volatile unsigned int __r = 0; \ > __asm__ __volatile__("" : : : "memory"); \ > __asm__("mrs %[R]," __STRING(x) : [R] "=r" (__r) : : "cc", "memory");\ > __r; \ > }) > > #define msr(x, r) \ > __asm__ __volatile__("msr " __STRING(x) ",%[R]": : [R] "r" (r) : "cc", "memory"); Using this I define dfi (disable fast/high priority interrupts), efi (enable fast/high priority interrupts) and rfi (restore fast/high priority interrupts): > typedef unsigned int ilevel_t; > #define dfi() ({ \ > ilevel_t __sr; \ > __sr = mrs(primask); \ > __asm__ __volatile__("" : : : "memory"); \ > __asm__ __volatile__("cpsid i" : : : "memory"); \ > MARK_DFI(); \ > __sr; \ > }) > > #define efi() ({ \ > ilevel_t __sr; \ > MARK_EFI(); \ > __sr = mrs(primask); \ > __asm__ __volatile__("" : : : "memory"); \ > __asm__ __volatile__("cpsie i" : : : "memory"); \ > __sr; \ > }) > Because the "mrs" instruction in the mrs(x) macro is not marked as volatile the compile is free to optimize it away in cases where I just call something like: > dfi(); > ... some code ... > efi(); while it will compile it when I do: > ilevel_t sr; > sr = dfi(); > ... some code ... > rfi(sr) What I do not like is that gcc considers mrs as constant and will optimize away "redundant" mrs instructions in cases like: > ilevel_t sr; > sr = dfi(); > ... some code ... > rfi(sr) > ... some other code ... > sr = dfi(); > ... some code ... > rfi(sr) With code like this, gcc will reuse the return value of the first mrs instruction and will not generate a second one for the second assignment to sr. This is correct in most cases, but when "some other code" calls functions that manipulate primask it will fail... How can I mark the mrs instruction as being not constant/pure? Or to give a different example, if I would have a cpu register that returns random numbers (like e.g. the r on the z80) how could I write a __asm__ that will get deleted when the return value is not used, but will never get deleted when the return value is useds? regards, Matthias -- Matthias Pfaller Software Entwicklung marco Systemanalyse und Entwicklung GmbH Tel +49 8131 5161 41 Hans-Böckler-Str. 2, D 85221 Dachau Fax +49 8131 5161 66 http://www.marco.de/ Email leo@xxxxxxxx Geschäftsführer Martin Reuter HRB 171775 Amtsgericht München