@@ -1,10 +1,10 @@ #ifndef _avcall_sparc_c /*-*- C -*-*/ #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 you don't have this or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied, on this software. @@ -75,11 +75,11 @@ __avword space[__AV_ALIST_WORDS]; /* space for callee's stack frame */ __avword *argframe = sp + 17; /* stack offset for argument list */ 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 */ { int i; for (i = 6; i < arglen; i++) /* push excess function args */ @@ -106,11 +106,11 @@ callee = l->func; goto *(void*)trampoline; } /* 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 */ iret; }); @@ -165,77 +165,43 @@ } else if (l->rtype == __AVvoidp) { 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->rsize == sizeof(char)) { - RETURN(char, ((char*)sp)[-1]); - } else - if (l->rsize == sizeof(short)) { - RETURN(short, ((short*)sp)[-1]); - } else - if (l->rsize == sizeof(int)) { - RETURN(int, ((int*)sp)[-1]); - } 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--; - } - } else { - __avword* dstaddr = (__avword*)l->raddr; - __avword* srcaddr = (__avword*)((long)sp - l->rsize); - while (srcaddr < sp) - *dstaddr++ = *srcaddr++; - } - } else { - 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*)i); - } else - if (l->rsize == sizeof(short)) { - RETURN(short, *(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); - } + 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*)i); + } else + if (l->rsize == sizeof(short)) { + RETURN(short, *(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 0; } #endif /*_avcall_sparc_c */