Re: gcc arm inline asm: how to output value for .set directive?

Liste des GroupesRevenir à ca embedded 
Sujet : Re: gcc arm inline asm: how to output value for .set directive?
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.arch.embedded
Date : 04. Apr 2025, 10:25:08
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vso8hl$34cmn$1@dont-email.me>
References : 1 2
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 04/04/2025 01:06, Grant Edwards wrote:
On 2025-04-03, Grant Edwards <invalid@invalid.invalid> wrote:
How do I convince ARM GCC's extended asm() to emit a value that can be
used in a .set directive?  Here's a simplified example:
 
       asm("\t.set foo_offset, %[off]" : : [off] "i" ( __builtin_offsetof(shm_t, foo) ) : );
 That didn't work, because gcc emits #40 instead of 40:
 
   35              .set foo_offset, #40
 I finally stumbled across some example code that showed me the
answer. It's not the _constraint_ in the input operand list (the "i"
above) that matters (I had tried all upper/lower ascii letters).
 You need a modifier in the _template_ string that references that
input operand:
    asm("\t.set foo_offset, %c[off]" : : [off] "i" ( __builtin_offsetof(shm_t, foo) ) : );
                            The secret is the 'c' in "%c[off]"
 Now that I know what to look for, I found it in the manual
 https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Generic-Operand-Modifiers
    6.11.2.8 Generic Operand Modifiers
 I had completely missed the difference between a qualifier and a
modifier...
 
Thank you for posting the answer after you figured it out!  I have probably read about gcc extended assembly more than most, and have no doubt also read about these modifiers, but I certainly did not remember them.  It's another little trick for the future.
(Note - you, Grant, are probably familiar with the ideas below, but other people might not be.)
I find that some of the inline assembly statements in my code are actually empty assembly and merely manipulate the dependencies and clobbers:
#define forceDependency(val) \
                 asm volatile("" :: "" (val) : )
This lets you force an evaluation within the volatile ordering of the code, as it tells the compiler that "val" is used in the assembly.  For example :
volatile uint64_t * pv;
uint64_t x = long_calculation...
disable interrupts
*pv = x;
enable interrupts
Your aim here is to calculate the value, then do a 64-bit atomic store with minimal interrupt disabled time.  But the compiler can, and in some cases will, re-order the disable interrupt code with part or all of the long calculation code.  Putting a "forceDependency(x)" before the disable interrupt code blocks that.
#define forgetCompilerKnowledge(v) \
                 asm ("" : "+g" (v))
#define forgetCompilerBlock(start, size) \
     do { typedef struct { char x[size]; } XS; XS *p = (XS *) start; \
         asm ("" : "+m" (*p)); \
     } while (0);
This tells the compiler that "v" might be changed - the compiler has to forget any extra information it knows about it.  I've used this in connection with structures declared and defined in code, but modified post-link.  (I've also used it to work around a compiler bug.)
#define unspecifiedInt() \
     ({ int x; asm ("" : "=g" (x)); x; })
This creates an int out of thin air - an appropriate register is picked, and the int value is whatever was in the register before.  It is the absolute minimum code for when you want an object but don't care about the value - you just care that you are not invoking undefined behaviour or triggering a compiler warning or error message.
These kinds of tricks can also be very useful in benchmarking, testing, or isolating bits of code for examining the generated assembly.

Date Sujet#  Auteur
3 Apr 25 * gcc arm inline asm: how to output value for .set directive?3Grant Edwards
4 Apr 25 `* Re: gcc arm inline asm: how to output value for .set directive?2Grant Edwards
4 Apr 25  `- Re: gcc arm inline asm: how to output value for .set directive?1David Brown

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal