[comp.lang.c] Address error quietly fixed on 680x0 systems

ian@puivax.UUCP (Ian Wilson) (01/25/89)

A piece of code I inherited recently contained the fragment:

	*((INT_16 *) charbuf_p) = x; charbuf_p += sizeof(INT_16);

where charbuf_p had no alignment restrictions enforced, including
no restriction on being an odd address. To my surprise, this turns
out to work on 680x0 systems, both Sun3 and a vanilla Mac.

Looking at the code generated by cc I see a long move: no smarts
in the compiler therefore. So the only mechanism that I can be fixing
this is an address error trap that quietly moves unaligned objects
byte-by-byte as requested.

Simple timing experiments on the Sun3 don't appear to bear this out,
however; I saw a 50% increase in runtime with writes to an odd address
but would have expected more (the trap mechanisms on the 68k aren't
super fast after all). Enlightenment?

I readily agree that code fragments like the above are to be avoided;
here is my offering in the name of portability: improvements welcomed.
(Note: checks on buffer size exceeded omitted for clarity).

#define WRITE_ANY(x, type) /* eg. WRITE_ANY(f, float) */ \
  { type temp = (type) x; \
	char *cp  = (char *) &temp; \
	size_t n = sizeof(type); \
	do { *charbuf_p++ = *cp++; } while( --n ); }

 -- ian wilson

 PS. the strange loop construct was the only way we could find
	 to get Greenhills C to use `dbf' -- a year or so back though.










 

guy@auspex.UUCP (Guy Harris) (01/28/89)

>Looking at the code generated by cc I see a long move: no smarts
>in the compiler therefore. So the only mechanism that I can be fixing
>this is an address error trap that quietly moves unaligned objects
>byte-by-byte as requested.

Wrongo.  The 68020 (as appears in the Sun-3), and a variety of other
chips/machines, don't *take* address error traps when you give them an
unaligned address; they just fetch the data.  RTFM (TFM being, in this
case, Motorola's 68020 book).  Furthermore, the 68000 (as appears in
most Macs) and 68010 only require 2-byte alignment, even for 4-byte
quantities (TFM being, in this case, Motorola's 68000/68008/68010 book). 

>Simple timing experiments on the Sun3 don't appear to bear this out,
>however; I saw a 50% increase in runtime with writes to an odd address
>but would have expected more (the trap mechanisms on the 68k aren't
>super fast after all). Enlightenment?

Off-boundary references are, however, slower than on-boundary references.

blarson@skat.usc.edu (Bob Larson) (01/29/89)

[note re-directed folloups, this isn't a C issue.]

In article <302@puivax.UUCP> ian@puivax.UUCP (Ian Wilson) writes:
>A piece of code I inherited recently contained the fragment:
>	*((INT_16 *) charbuf_p) = x; charbuf_p += sizeof(INT_16);
>where charbuf_p had no alignment restrictions enforced, including
>no restriction on being an odd address. To my surprise, this turns
>out to work on 680x0 systems, both Sun3 and a vanilla Mac.

The 680n0, with n>=2 does handle this by doing multiple bus cycles.
Thus, the Sun3 (68020) would not need any trap handler to run this
non-portable code.

-- 
Bob Larson	Arpa: Blarson@Ecla.Usc.Edu	blarson@skat.usc.edu
Uucp: {sdcrdcf,cit-vax}!oberon!skat!blarson
Prime mailing list:	info-prime-request%ais1@ecla.usc.edu
			oberon!ais1!info-prime-request

bobmon@iuvax.cs.indiana.edu (RAMontante) (01/29/89)

Are you sure the compiler wasn't word-aligning the data space when it
built the executable?  I know other compilers for other systems
sometimes do this (i.e., I'm making an educated guess...)