pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pkg/23790
The following reply was made to PR pkg/23790; it has been noted by GNATS.
From: "Valeriy E. Ushakov" <uwe%ptc.spbu.ru@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: pkg/23790
Date: Tue, 17 May 2005 12:34:02 +0400
devel/ffcall has numerous problems on sparc64. clisp ships with and
uses a private copy of ffcall, so the same fixes should be applied to
both.
=== 1 ===
The CL_SMALL_STRUCT_RETURN autoconf test for small struct returns
tests if the return value of the function, that returns:
typedef struct { int x; } foo;
returns an int that is == the int x.
On sparc64 the structure is returned in a register, but the 32bit int
is returned in the MSW of the %o0 register, and so the test, that
checks the LSW of the %o0, fails.
Workaround: I forced cl_cv_c_struct_return_small=yes via environment
when running configure.
=== 2 ===
There's a trivial vacall fix that should be applied twice: once in
vacall, and once in callback/vacall_r. Then the .S file(s) need to be
regenerated (for a package fix, probably just copied over from
FILESDIR).
--- vacall-sparc64.c-dist 2004-06-02 21:00:22.000000000 +0200
+++ vacall-sparc64.c 2005-05-17 01:08:04.000000000 +0200
@@ -110,6 +110,7 @@
list.farg[15] = farg15;
/* Prepare the va_alist. */
list.flags = 0;
+ list.anum = 0;
list.aptr = (long)(&firstword - 6);
list.raddr = (void*)0;
list.rtype = __VAvoid;
=== 3 ===
Then the following patch should be applied to avcall, avcall-sparc64.S
regenerated *and* fixed manually: the "nop" after the avcall that is
necessary to support functions retunring structures should be moved
one instruction up.
. gcc versions prior to gcc3.4 have an ABI bug that affects passing
small structs with a 'float' member in registers. I've fixed the
code to comply to ABI, but it fails passing 'Float' tests with
gcc3.3.3 that we have in-tree.
. returning small structs with fp members doesn't work, as fp members
are returned in fp regs and the generic avcall code doesn't know
what members of the structure are, so it doesn't know if it should
pick the result from fp or from integer registers.
--- avcall-sparc64.c-dist 2004-01-26 15:58:39.000000000 +0100
+++ avcall-sparc64.c 2005-05-16 03:31:07.000000000 +0200
@@ -103,79 +103,44 @@
__avword trampoline[6]; /* room for a trampoline */
__avword space[__AV_ALIST_WORDS]; /* space for callee's stack frame */
- __avword *argframe = sp + 17; /* stack offset for argument
list */
+ __avword *argframe = (void *)((unsigned long)(sp + 16)+2047); /* stack
offset for argument list */
int arglen = l->aptr - l->args;
__avword i;
- if (l->farg_mask) {
- /* push leading float args */
- if (l->farg_mask & (1<<0))
- __asm__("ld %1(%0),%%f1" : : "p" (l), "i" OFFSETOF(av_alist,args[0]));
- if (l->farg_mask & (1<<1))
- __asm__("ld %1(%0),%%f3" : : "p" (l), "i" OFFSETOF(av_alist,args[1]));
- if (l->farg_mask & (1<<2))
- __asm__("ld %1(%0),%%f5" : : "p" (l), "i" OFFSETOF(av_alist,args[2]));
- if (l->farg_mask & (1<<3))
- __asm__("ld %1(%0),%%f7" : : "p" (l), "i" OFFSETOF(av_alist,args[3]));
- if (l->farg_mask & (1<<4))
- __asm__("ld %1(%0),%%f9" : : "p" (l), "i" OFFSETOF(av_alist,args[4]));
- if (l->farg_mask & (1<<5))
- __asm__("ld %1(%0),%%f11" : : "p" (l), "i" OFFSETOF(av_alist,args[5]));
- if (l->farg_mask & (1<<6))
- __asm__("ld %1(%0),%%f13" : : "p" (l), "i" OFFSETOF(av_alist,args[6]));
- if (l->farg_mask & (1<<7))
- __asm__("ld %1(%0),%%f15" : : "p" (l), "i" OFFSETOF(av_alist,args[7]));
- if (l->farg_mask & (1<<8))
- __asm__("ld %1(%0),%%f17" : : "p" (l), "i" OFFSETOF(av_alist,args[8]));
- if (l->farg_mask & (1<<9))
- __asm__("ld %1(%0),%%f19" : : "p" (l), "i" OFFSETOF(av_alist,args[9]));
- if (l->farg_mask & (1<<10))
- __asm__("ld %1(%0),%%f21" : : "p" (l), "i" OFFSETOF(av_alist,args[10]));
- if (l->farg_mask & (1<<11))
- __asm__("ld %1(%0),%%f23" : : "p" (l), "i" OFFSETOF(av_alist,args[11]));
- if (l->farg_mask & (1<<12))
- __asm__("ld %1(%0),%%f25" : : "p" (l), "i" OFFSETOF(av_alist,args[12]));
- if (l->farg_mask & (1<<13))
- __asm__("ld %1(%0),%%f27" : : "p" (l), "i" OFFSETOF(av_alist,args[13]));
- if (l->farg_mask & (1<<14))
- __asm__("ld %1(%0),%%f29" : : "p" (l), "i" OFFSETOF(av_alist,args[14]));
- if (l->farg_mask & (1<<15))
- __asm__("ld %1(%0),%%f31" : : "p" (l), "i" OFFSETOF(av_alist,args[15]));
- }
if (l->darg_mask) {
- /* push leading double args */
+ /* push leading float/double args */
if (l->darg_mask & (1<<0))
- __asm__("ldd %1(%0),%%f0" : : "p" (l), "i" OFFSETOF(av_alist,args[0]));
+ __asm__("ldd [%0+%1],%%f0" : : "p" (l), "i" OFFSETOF(av_alist,args[0]));
if (l->darg_mask & (1<<1))
- __asm__("ldd %1(%0),%%f2" : : "p" (l), "i" OFFSETOF(av_alist,args[1]));
+ __asm__("ldd [%0+%1],%%f2" : : "p" (l), "i" OFFSETOF(av_alist,args[1]));
if (l->darg_mask & (1<<2))
- __asm__("ldd %1(%0),%%f4" : : "p" (l), "i" OFFSETOF(av_alist,args[2]));
+ __asm__("ldd [%0+%1],%%f4" : : "p" (l), "i" OFFSETOF(av_alist,args[2]));
if (l->darg_mask & (1<<3))
- __asm__("ldd %1(%0),%%f6" : : "p" (l), "i" OFFSETOF(av_alist,args[3]));
+ __asm__("ldd [%0+%1],%%f6" : : "p" (l), "i" OFFSETOF(av_alist,args[3]));
if (l->darg_mask & (1<<4))
- __asm__("ldd %1(%0),%%f8" : : "p" (l), "i" OFFSETOF(av_alist,args[4]));
+ __asm__("ldd [%0+%1],%%f8" : : "p" (l), "i" OFFSETOF(av_alist,args[4]));
if (l->darg_mask & (1<<5))
- __asm__("ldd %1(%0),%%f10" : : "p" (l), "i" OFFSETOF(av_alist,args[5]));
+ __asm__("ldd [%0+%1],%%f10" : : "p" (l), "i"
OFFSETOF(av_alist,args[5]));
if (l->darg_mask & (1<<6))
- __asm__("ldd %1(%0),%%f12" : : "p" (l), "i" OFFSETOF(av_alist,args[6]));
+ __asm__("ldd [%0+%1],%%f12" : : "p" (l), "i"
OFFSETOF(av_alist,args[6]));
if (l->darg_mask & (1<<7))
- __asm__("ldd %1(%0),%%f14" : : "p" (l), "i" OFFSETOF(av_alist,args[7]));
+ __asm__("ldd [%0+%1],%%f14" : : "p" (l), "i"
OFFSETOF(av_alist,args[7]));
if (l->darg_mask & (1<<8))
- __asm__("ldd %1(%0),%%f16" : : "p" (l), "i" OFFSETOF(av_alist,args[8]));
+ __asm__("ldd [%0+%1],%%f16" : : "p" (l), "i"
OFFSETOF(av_alist,args[8]));
if (l->darg_mask & (1<<9))
- __asm__("ldd %1(%0),%%f18" : : "p" (l), "i" OFFSETOF(av_alist,args[9]));
+ __asm__("ldd [%0+%1],%%f18" : : "p" (l), "i"
OFFSETOF(av_alist,args[9]));
if (l->darg_mask & (1<<10))
- __asm__("ldd %1(%0),%%f20" : : "p" (l), "i"
OFFSETOF(av_alist,args[10]));
+ __asm__("ldd [%0+%1],%%f20" : : "p" (l), "i"
OFFSETOF(av_alist,args[10]));
if (l->darg_mask & (1<<11))
- __asm__("ldd %1(%0),%%f22" : : "p" (l), "i"
OFFSETOF(av_alist,args[11]));
+ __asm__("ldd [%0+%1],%%f22" : : "p" (l), "i"
OFFSETOF(av_alist,args[11]));
if (l->darg_mask & (1<<12))
- __asm__("ldd %1(%0),%%f24" : : "p" (l), "i"
OFFSETOF(av_alist,args[12]));
+ __asm__("ldd [%0+%1],%%f24" : : "p" (l), "i"
OFFSETOF(av_alist,args[12]));
if (l->darg_mask & (1<<13))
- __asm__("ldd %1(%0),%%f26" : : "p" (l), "i"
OFFSETOF(av_alist,args[13]));
+ __asm__("ldd [%0+%1],%%f26" : : "p" (l), "i"
OFFSETOF(av_alist,args[13]));
if (l->darg_mask & (1<<14))
- __asm__("ldd %1(%0),%%f28" : : "p" (l), "i"
OFFSETOF(av_alist,args[14]));
+ __asm__("ldd [%0+%1],%%f28" : : "p" (l), "i"
OFFSETOF(av_alist,args[14]));
if (l->darg_mask & (1<<15))
- __asm__("ldd %1(%0),%%f30" : : "p" (l), "i"
OFFSETOF(av_alist,args[15]));
+ __asm__("ldd [%0+%1],%%f30" : : "p" (l), "i"
OFFSETOF(av_alist,args[15]));
}
{
@@ -188,7 +153,7 @@
i = ({ __avword iret; /* %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 */
+ asm __volatile__("nop"); /* struct returning functions skip this
instruction */
iret;
});
--- avcall.h.in-dist 2004-01-26 15:58:41.000000000 +0100
+++ avcall.h.in 2005-05-16 03:30:27.000000000 +0200
@@ -382,8 +382,7 @@
#if defined(__sparc64__)
/* store the floating-point arguments in an extra array */
int anum; /* redundant: (LIST).aptr =
&(LIST).args[(LIST).anum] */
- unsigned int farg_mask; /* bitmask of those entries in
farg[] which have a value */
- unsigned int darg_mask; /* bitmask of those entries in
args[] which have a double value */
+ unsigned int darg_mask; /* bitmask of those entries in
args[] which have a float or double value */
#endif
#if defined(__ia64__) || defined(__x86_64__)
/* store the floating-point arguments in an extra array */
@@ -467,7 +466,6 @@
#if defined(__sparc64__)
#define __av_start1(LIST) \
(LIST).anum = 0, \
- (LIST).farg_mask = 0, \
(LIST).darg_mask = 0, \
(LIST).aptr = &(LIST).args[0], \
(LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
@@ -906,8 +904,8 @@
*/
#define __av_float(LIST,VAL) \
((LIST).aptr >= __av_eptr(LIST) \
- ? -1 : (((LIST).anum < 16 && ((LIST).farg_mask |= (1 << (LIST).anum))), \
- (*(float*)(LIST).aptr = (float)(VAL)), \
+ ? -1 : (((LIST).anum < 16 && ((LIST).darg_mask |= (1 << (LIST).anum))), \
+ (((float*)(LIST).aptr)[1] = (float)(VAL)), \
(LIST).anum++, \
(LIST).aptr++, \
0))
@@ -1307,10 +1305,8 @@
? -1 :
(ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
(LIST).aptr =
(__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) &
-(long)sizeof(__avword)),\
((LIST).anum < 16 \
- && ((LIST).farg_mask |= (-1 << (LIST).anum), \
- (LIST).darg_mask |= (-1 << (LIST).anum))), \
+ && ((LIST).darg_mask |= (-1 << (LIST).anum))), \
(LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) &
-(long)(TYPE_ALIGN)) + sizeof(__avword)-1) &
-(long)sizeof(__avword))/sizeof(__avword),\
- (LIST).farg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16))
- 1, \
(LIST).darg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16))
- 1, \
0)))
#endif
SY, Uwe
--
uwe%ptc.spbu.ru@localhost | Zu Grunde kommen
http://www.ptc.spbu.ru/~uwe/ | Ist zu Grunde gehen
Home |
Main Index |
Thread Index |
Old Index