Mail Archives: djgpp/1997/06/12/23:33:02
On Thu, 12 Jun 1997 00:34:19 GMT, candrian AT pcnet DOT pcnet DOT ro (Calin
Andrian) wrote:
> >extern __inline__ long fixmul(long op_a, long op_b)
> >{
> > long result;
> > __asm__ __volatile__ ("imull %0; shrdl $16,%1,%0"
> > : "=a" (result)
> > : "0" (op_a), "d" (op_b));
> > return result;
> >}
> IT'S WRONG ! Sorry.
> I looked again, and discovered. The center line should read:
>
> __asm__ __volatile__ ("imull %2; shrdl $16,%2,%0"
>
> This time I tested it. It's OK.
It is not OK. %edx was changed in imull but was not listed
as clobbered. Correct is:
asm ("imull %2\n\t"
"shrdl $16, %%edx, %%eax"
: "=a" (result) : "0" (op_a), "d" (op_b) : "%edx");
(using `\n\t' or `;' is a matter of taste, but if asm sentence is
too large and there is only `;', then assembler may choke on it).
Even if input register was not changed inside asm, it may be
put in clobber list, but then gcc will reload variable
in register when it will need it again. But gcc knows nothing
about what happens in assembler, that's why there is clobber list.
BTW, even when clobbered register is not listed as clobbered
the result may be correct, but things may change with different
optimization level or layout of program.
E.g. try `fixed_mul (fixed_mul (a, b), fixed_mul (a, c))'
- Raw text -