nfschlen@IDUNNO.PRINCETON.EDU (Norbert Fred Schlenker) (02/16/89)
Environment: Sun 4/??? running SunOS 4.0 The buggy program (severely excerpted): struct hnode { int key; int ip; } h[50]; static int entries = 20; void copy(void) { h[1] = h[entries]; /* <--- Note this is an 8 byte structure copy */ } GCC's invocation: idunno% gcc -v -S bug.c gcc version 1.32 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ bug.c /tmp/cca08445.cpp GNU CPP version 1.32 /usr/local/lib/gcc-cc1 /tmp/cca08445.cpp -quiet -dumpbase bug.c -version -o bug.s GNU C version 1.32 (sparc) compiled by GNU C version 1.32. idunno% The assembly output: gcc_compiled.: .data .align 4 _entries: .word 20 .text .align 4 .global _copy .proc 1 _copy: !#PROLOGUE# 0 save %sp,-80,%sp !#PROLOGUE# 1 set _h+8,%o0 sethi %hi(_entries),%g1 ld [%g1+%lo(_entries)],%o1 set _h,%o2 sll %o1,3,%o1 ld [%o2+%o1],%o4 <-- Note that the first word of the structure ld [%o2+%o1],%o5 <-- is copied into two registers and then st %o4,[%o0] <-- summarily stuffed into both words of st %o5,[%o0+4] <-- the target. L1: ret restore .global _h .common _h,400,"bss" A couple of further notes: - Replacing the variable 'entries' with its constant value results in correct code. Unfortunately, the real program can't afford such a luxury. - The code for: struct hnode { ... } h1, h2; ... h1 = h2; is also correct. Additionally, the two loads and stores are replaced by a single ldd/std combination.