ludo@xxxxxxx (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. I don't see any reason to put the final mov in the asm, in which case you don't have to clobber memory. I would go for something more like this: asm volatile goto ("add %[addend], %[result]; " "jo %l[slow_add]; " "test %[tag], %[result]; " "je %l[slow_add]" : [result] "+r" (result) : [addend] "r" (x), [tag] "i" (scm_tc2_int) : /* no clobbers */ : slow_add); *vsp = result; NEXT; Ian