On Fri, Oct 08, 2021 at 12:39:15PM -0500, Segher Boessenkool wrote: > On Thu, Oct 07, 2021 at 08:04:23PM -0500, Paul A. Clarke wrote: > > On Thu, Oct 07, 2021 at 06:39:06PM -0500, Segher Boessenkool wrote: > > > > + __asm__ __volatile__ ("mffsce %0" : "=f" (__fpscr_save.__fr)); > > > > > > The __volatile__ does likely not do what you want. As far as I can see > > > you do not want one here anyway? > > > > > > "volatile" does not order asm wrt fp insns, which you likely *do* want. > > > > Reading the GCC docs, it looks like the "volatile" qualifier for "asm" > > has no effect at all (6.47.1): > > > > | The optional volatile qualifier has no effect. All basic asm blocks are > > | implicitly volatile. > > > > So, it could be removed without concern. > > This is not a basic asm (it contains a ":"; that is not just an easy way > to see it, it is the *definition* of basic vs. extended asm).
Ah, basic vs extended. I learned something today... thanks for your patience! > The manual explains: > > """ > Note that the compiler can move even 'volatile asm' instructions > relative to other code, including across jump instructions. For > example, on many targets there is a system register that controls the > rounding mode of floating-point operations. Setting it with a 'volatile > asm' statement, as in the following PowerPC example, does not work > reliably. > > asm volatile("mtfsf 255, %0" : : "f" (fpenv)); > sum = x + y; > > The compiler may move the addition back before the 'volatile asm' > statement. To make it work as expected, add an artificial dependency to > the 'asm' by referencing a variable in the subsequent code, for example: > > asm volatile ("mtfsf 255,%1" : "=X" (sum) : "f" (fpenv)); > sum = x + y; > """ I see. Thanks for the reference. If I understand correctly, volatile prevents some optimizations based on the defined inputs/outputs, but the asm could still be subject to reordering. In this particular case, I don't think it's an issue with respect to reordering. The code in question is: + __asm__ __volatile__ ("mffsce %0" : "=f" (__fpscr_save.__fr)); + __enables_save.__fpscr = __fpscr_save.__fpscr & 0xf8; The output (__fpscr_save) is a source for the following assignment, so the order should be respected, no? With respect to volatile, I worry about removing it, because I do indeed need that instruction to execute in order to clear the FPSCR exception enable bits. That side-effect is not otherwise known to the compiler. > > > You do not need any of that __ either. > > > > I'm surprised that I don't. A .h file needs to be concerned about the > > namespace it inherits, no? > > These are local variables in a function though. You get such > complexities in macros, but never in functions, where everything is > scoped. Local variables are a great thing. And macros are a bad thing! They are local variables in a function *in an include file*, though. If a user's preprocessor macro just happens to match a local variable name there could be problems, right? a.h: inline void foo () { int A = 0; } a.c: #define A a+b #include <a.h> $ gcc -c -I. a.c In file included from a.c:1: a.c: In function ‘foo’: a.h:1:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘+’ token #define A a+b ^ a.c:2:17: note: in expansion of macro ‘A’ int foo() { int A = 0; } ^ a.h:1:13: error: ‘b’ undeclared (first use in this function) #define A a+b ^ a.c:2:17: note: in expansion of macro ‘A’ int foo() { int A = 0; } ^ a.h:1:13: note: each undeclared identifier is reported only once for each function it appears in #define A a+b ^ a.c:2:17: note: in expansion of macro ‘A’ int foo() { int A = 0; } ^ PC