GCC inline assembly question

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

 



Hello,

I work on a codebase (Zephyr RTOS) which uses Kconfig for configuration. We have some logic which tries to declare linker symbols with the contents of configuration directives. I've run into some problems for configs that are larger than MAX_INT.

What gets generated through macros looks like this:

__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 \
      |  ^~~~~~~
zephyr/misc/generated/configs.c:14:1: note: in expansion of macro 'GEN_ABSOLUTE_SYM'
   14 | GEN_ABSOLUTE_SYM(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, 2147483648);
      | ^~~~~~~~~~~~~~~~

In a 32-bit build, I see different behavior, a constant like 3000000000 works just fine, but if I exceed the bounds of an unsigned integer I get a much more comprehensible overflow warning message, it still compiles but the value is truncated:

/home/apboie/projects/zephyr/zephyr/tests/kernel/mem_protect/userspace/out/zephyr/include/generated/autoconf.h:3:44: warning: overflow in conversion from 'long long int' to 'int' changes value from '9000000000' to '410065408' [-Woverflow]
    3 | #define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 9000000000
      |                                            ^~~~~~~~~~
/home/apboie/projects/zephyr/zephyr/kernel/timeout.c:33:33: note: in expansion of macro 'CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC'
   33 | int z_clock_hw_cycles_per_sec = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
      |                      

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.

Regards,
Andrew





[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