Multiplying two shorts...

braner braner at batcomputer.tn.cornell.edu
Fri Aug 12 03:25:49 AEST 1988


[]

I ran into a related bug in Laser C on the Atari ST.  The (legal) code was:
	struct foo *p;		/* 32-bit pointers */
	int n;			/* 16-bit ints <<<<<<<<<<<<<<<<<<<< */
				/* (In my view the right thing on a 68000) */
	...
	p += n;			/* <<<< here was the bug */
The compiler, turns out, did the last instruction as follows:
	load n
	load sizeof(struct foo)
	multiply using the 68000 mulu instruction (16*16=32 bits)
	truncate to an int (16 bits)	<<<<<<<<<< !!!!!!
	extend to a long (32 bits)
		(actually the last two were done together as ext.l d#)
	long-add to p
Of course, for (n > 64K/sizeof(struct foo)) the address thus calculated
was wrong.  The ironic part of it was that the compiler had the 32 bit
result right there, and had to stomp on it with the extra "ext.l"...
When coding the related C expression
	&p[n]
the same compiler did it correctly -- but slowly, as:
	load n
	extend to long
	load sizeof(struct foo) as a LONG constant
	call the long-multiply library function (32*32=32 bits)
	long-add result to p
this time not using the perfectly adequate "mulu" machine instruction,
which could be recognized as adequate since 'n' was a 16-bit int and
sizeof(struct foo), a constant known at compile time, was 6 bytes (< 64K).

I was forced to replace "p+=n;" with "p=&p[n];" and take the performance loss.

Happy debugging!

- Moshe Braner

(Try debugging on a parallel machine :-)



More information about the Comp.lang.c mailing list