Inline assembly and clobbered registers

Ludovic Courtès ludo@gnu.org
Sat Oct 23 19:41:00 GMT 2010


Hello,

I’m trying to use ‘asm goto’ with GCC 4.5 to implement tagged integer
arithmetic for Guile’s VM.  For instance, the addition of X and Y looks
like this:

    {
      SCM result = y;
      asm volatile goto ("add %0, %[result]; jo %l[slow_add]; "
			 "sub %[tag], %[result]; "
			 "test %[tag], %[result]; "
			 "je %l[slow_add]; "
			 "mov %[result], (%[vsp])\n"
			 : /* no output */
			 : "r" (x), [result] "r" (result),
			   [vsp] "r" (sp), [tag] "i" (scm_tc2_int)
			 : "memory"
			 : slow_add);
      NEXT; /* Jump to the next virtual IP.  */
    }
  slow_add:
    /* Add X and Y the slow way, using bignums if needed.  */

However, this doesn’t work because GCC doesn’t allocate any new register
for ‘result’ (which it is allowed to do given that ‘result’ is an
input), so the ‘test’ instruction modifies ‘y’, and we may jump to
‘slow_add’ with an erroneous value of ‘y’.

I could add a clobber for a specific register and use that to store the
intermediate result, but I’d rather let GCC choose a register for me.
Unfortunately, only specific register names are allowed in the clobber
list, so I can’t, e.g., use the ‘r’ constraint to achieve this.

Any idea how I can work around this?

Thanks,
Ludo’.



More information about the Gcc-help mailing list