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.