GCC inline assembly question

Segher Boessenkool segher@kernel.crashing.org
Wed Feb 12 01:24:00 GMT 2020


Hi!

On Tue, Feb 11, 2020 at 10:27:21PM +0000, Boie, Andrew P wrote:
> __asm__(".globl CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC\n\t"
>         ".equ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,%c0\n\t"
>         ".type CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,@object"
> 		: : "n"(3000000000));
> 
> The problem is the integer value; if it is larger than 2147483647 I get an error:
> 
> zephyr/misc/generated/configs.c: In function '_ConfigAbsSyms':
> ../include/toolchain/gcc.h:404:2: error: invalid 'asm': operand is not a condition code, invalid operand code 'c'
>   404 |  __asm__(".globl\t" #name "\n\t.equ\t" #name \
>       |  ^~~~~~~

The 'c' output modifier is overloaded.  If its operand is a valid
constant address, it is printed without punctuation; if not, the target
code gets to do with it what it wants (which is where that "condition
code" comes from).

The documentation is misleading, it says
  'c'  Require a constant operand and print the constant expression with
       no punctuation.
but it does not mention that requires a constant *address* (nor what it
does when it is not; it doesn't actually *require* it).

Constant addresses that are just an integer have to fit in a (signed)
32-bit integer, on x86 (just like all other constant integers that
are the operand of a machine instruction).

> Any tips on getting this to work right on x86-64? It is not liking the combination of the %c0 input operand modifier 'c' and the 'n' constraint if the provided constant exceeds a signed integer. I imagine some other incantation would work but I'm not sure what.

You can just paste it into the string here, like you have #name already?


Segher



More information about the Gcc-help mailing list