$NetBSD: patch-ag,v 1.1 2008/03/03 21:41:30 tnn Exp $ --- avcall/avcall-sparc.c.orig 2004-01-26 15:58:38.000000000 +0100 +++ avcall/avcall-sparc.c @@ -2,7 +2,7 @@ #define _avcall_sparc_c /** Copyright 1993 Bill Triggs, - Copyright 1995-1999 Bruno Haible, + Copyright 1995-1999, 2005 Bruno Haible, This is free software distributed under the GNU General Public Licence described in the file COPYING. Contact the author if @@ -77,7 +77,7 @@ __builtin_avcall(av_alist* l) int arglen = l->aptr - l->args; __avword i; - if ((l->rtype == __AVstruct) && !(l->flags & __AV_SUNCC_STRUCT_RETURN)) + if (l->rtype == __AVstruct) argframe[-1] = (__avword)l->raddr; /* push struct return address */ { @@ -108,7 +108,7 @@ __builtin_avcall(av_alist* l) } /* call function with 1st 6 args */ - i = ({ __avword iret; /* %o0 */ + i = ({ register __avword iret __asm__("%o0"); iret = (*l->func)(l->args[0], l->args[1], l->args[2], l->args[3], l->args[4], l->args[5]); asm ("nop"); /* struct returning functions skip this instruction */ @@ -167,70 +167,36 @@ __builtin_avcall(av_alist* l) RETURN(void*, i); } else if (l->rtype == __AVstruct) { - /* This is a kludge for old Sun cc and is probably fragile. */ - if (l->flags & __AV_SUNCC_STRUCT_RETURN) { - /* Sun cc struct return convention */ + if (l->flags & __AV_PCC_STRUCT_RETURN) { + /* pcc struct return convention: need a *(TYPE*)l->raddr = *(TYPE*)i; */ if (l->rsize == sizeof(char)) { - RETURN(char, ((char*)sp)[-1]); + RETURN(char, *(char*)i); } else if (l->rsize == sizeof(short)) { - RETURN(short, ((short*)sp)[-1]); + RETURN(short, *(short*)i); } else if (l->rsize == sizeof(int)) { - RETURN(int, ((int*)sp)[-1]); + RETURN(int, *(int*)i); } else if (l->rsize == sizeof(double)) { - ((int*)l->raddr)[0] = ((int*)sp)[-2]; - ((int*)l->raddr)[1] = ((int*)sp)[-1]; - } else - if (l->rsize % 4) { - char* dstaddr = (char*)l->raddr; - char* srcaddr = (char*)((long)sp - l->rsize); - unsigned int count = l->rsize; - if (count > 4) - srcaddr = (char*)((long)srcaddr & -4); - while (count > 0) { - *dstaddr++ = *srcaddr++; - count--; - } + ((int*)l->raddr)[0] = ((int*)i)[0]; + ((int*)l->raddr)[1] = ((int*)i)[1]; } else { - __avword* dstaddr = (__avword*)l->raddr; - __avword* srcaddr = (__avword*)((long)sp - l->rsize); - while (srcaddr < sp) - *dstaddr++ = *srcaddr++; + int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword); + while (--n >= 0) + ((__avword*)l->raddr)[n] = ((__avword*)i)[n]; } } else { - if (l->flags & __AV_PCC_STRUCT_RETURN) { - /* pcc struct return convention: need a *(TYPE*)l->raddr = *(TYPE*)i; */ + /* normal struct return convention */ + if (l->flags & __AV_SMALL_STRUCT_RETURN) { if (l->rsize == sizeof(char)) { - RETURN(char, *(char*)i); + RETURN(char, i); } else if (l->rsize == sizeof(short)) { - RETURN(short, *(short*)i); + RETURN(short, i); } else if (l->rsize == sizeof(int)) { - RETURN(int, *(int*)i); - } else - if (l->rsize == sizeof(double)) { - ((int*)l->raddr)[0] = ((int*)i)[0]; - ((int*)l->raddr)[1] = ((int*)i)[1]; - } else { - int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword); - while (--n >= 0) - ((__avword*)l->raddr)[n] = ((__avword*)i)[n]; - } - } else { - /* normal struct return convention */ - if (l->flags & __AV_SMALL_STRUCT_RETURN) { - if (l->rsize == sizeof(char)) { - RETURN(char, i); - } else - if (l->rsize == sizeof(short)) { - RETURN(short, i); - } else - if (l->rsize == sizeof(int)) { - RETURN(int, i); - } + RETURN(int, i); } } }