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...)