Re: GCC inline assembly question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux