GCC's aarch64 port, from the beginning (2012), supports the constraint"S" to reference a symbol or label. This is nice, as you can create anartificial reference for linker garbage collection, defining sections tohold symbol addresses, or even enabling more creative applications.
1 | namespace ns { extern int a[4]; } |
Using the generic r
or m
constraint in suchcases would instruct GCC to generate instructions to compute theaddress, which can be wasteful if the materialized address isn'tactually needed.
1 | // aarch64 |
C++ templates can make this easier to use. 1
2
3template <class T, T &x>
void ref() { asm (".reloc ., BFD_RELOC_NONE, %0" :: "S"(x)); }
void use() { ref<decltype(ns::a), ns::a>(); }
GCC's RISC-V port, from the beginning (2017), supports the constraint"S" for a similar purpose as well. However, the operand cannot be apreemptible symbol (non-local symbol in GCC's term). I have just filed[PATCH]RISC-V: Allow constraint "S" even if the symbol does not bindlocally to relax the condition.
Unfortunately, there had been no suitable constraint for x86 for along time. We can use the constraint "i" with the modifier "p" to printraw symbol name without syntax-specific prefixes, but it does not workwhen:
-mcmodel=large
is used1 | void foo() { |
I filed the featurerequest for a new constraint in May 2022 and eventually decided toimplement it by myself. The patch landed today, catching the GCC 14release.
BTW, there are a few other modifiers that work similarly to "p", like"c". I think having such a longlist of modifiers is unfortunate.