Inline assembly and clobbered registers

Ludovic Courtès ludo@gnu.org
Mon Oct 25 18:06:00 GMT 2010


Hello,

Ian Lance Taylor <iant@google.com> writes:

> ludo@gnu.org (Ludovic Courtès) writes:
>
>> Ian Lance Taylor <iant@google.com> writes:
>>
>>> ludo@gnu.org (Ludovic Courtès) writes:
>>>
>>>> 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?
>>>
>>> When your asm modifies a register, you need to tell gcc that that is
>>> happening.  E.g., list the value in the list of outputs and give it a +
>>> constraint.
>>
>> That doesn’t work because ‘asm goto’ doesn’t support output variables as
>> of GCC 4.5 (info "(gcc) Extended Asm").
>
> Whoops, sorry about that.  That should really be fixed.
>
> Still, your asm simply can not change registers and not tell gcc about
> it.  That is certain to break.  I think you're going to have to force
> the use of an explicit register or use a regular asm rather than an asm
> goto.

Yes, that’s why I’m asking for ideas to work around this.  :-)

Namely, clobbering a specific register doesn’t sound wise here since
this asm snippet will be part of the bytecode interpreter, where GCC’s
register allocator can supposedly do a better job if I don’t make its
life harder by clobbering an arbitrarily-chosen register.

Likewise, using ‘asm’ instead of ‘asm goto’ doesn’t seem doable, since
the cost would outweigh the benefits AFAICS (e.g., one of the output
variables would have to be a boolean indicating whether an overflow
occurred...).

Thanks,
Ludo’.



More information about the Gcc-help mailing list