mirror of git://gcc.gnu.org/git/gcc.git
float1.c (value_type): New typedef.
* testsuite/libffi.call/float1.c (value_type): New typedef. (CANARY): New define. (main): Check for result buffer overflow. * src/powerpc/linux64.S: Handle linux64 long double returns. * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. (ffi_prep_cif_machdep): Handle linux64 long double returns. From-SVN: r104660
This commit is contained in:
parent
608af77dc1
commit
d674eb2f5c
|
@ -1,3 +1,12 @@
|
||||||
|
2005-09-26 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* testsuite/libffi.call/float1.c (value_type): New typedef.
|
||||||
|
(CANARY): New define.
|
||||||
|
(main): Check for result buffer overflow.
|
||||||
|
* src/powerpc/linux64.S: Handle linux64 long double returns.
|
||||||
|
* src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
|
||||||
|
(ffi_prep_cif_machdep): Handle linux64 long double returns.
|
||||||
|
|
||||||
2005-08-25 Alan Modra <amodra@bigpond.net.au>
|
2005-08-25 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
PR target/23404
|
PR target/23404
|
||||||
|
|
|
@ -39,6 +39,7 @@ enum {
|
||||||
FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
|
FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
|
||||||
FLAG_RETURNS_FP = 1 << (31-29),
|
FLAG_RETURNS_FP = 1 << (31-29),
|
||||||
FLAG_RETURNS_64BITS = 1 << (31-28),
|
FLAG_RETURNS_64BITS = 1 << (31-28),
|
||||||
|
FLAG_RETURNS_128BITS = 1 << (31-27),
|
||||||
|
|
||||||
FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
|
FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
|
||||||
FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
|
FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
|
||||||
|
@ -543,6 +544,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
/* else fall through. */
|
/* else fall through. */
|
||||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
|
||||||
|
{
|
||||||
|
flags |= FLAG_RETURNS_128BITS;
|
||||||
|
flags |= FLAG_RETURNS_FP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
intarg_count++;
|
intarg_count++;
|
||||||
flags |= FLAG_RETVAL_REFERENCE;
|
flags |= FLAG_RETVAL_REFERENCE;
|
||||||
|
|
|
@ -120,9 +120,13 @@ ffi_call_LINUX64:
|
||||||
blr
|
blr
|
||||||
|
|
||||||
.Lfp_return_value:
|
.Lfp_return_value:
|
||||||
|
bt 27, .Lfd_return_value
|
||||||
bf 28, .Lfloat_return_value
|
bf 28, .Lfloat_return_value
|
||||||
stfd %f1, 0(%r30)
|
stfd %f1, 0(%r30)
|
||||||
stfd %f2, 8(%r30) /* It might be a long double */
|
b .Ldone_return_value
|
||||||
|
.Lfd_return_value:
|
||||||
|
stfd %f1, 0(%r30)
|
||||||
|
stfd %f2, 8(%r30)
|
||||||
b .Ldone_return_value
|
b .Ldone_return_value
|
||||||
.Lfloat_return_value:
|
.Lfloat_return_value:
|
||||||
stfs %f1, 0(%r30)
|
stfs %f1, 0(%r30)
|
||||||
|
|
|
@ -8,6 +8,14 @@
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
#include "float.h"
|
#include "float.h"
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
unsigned char c[sizeof (double)];
|
||||||
|
} value_type;
|
||||||
|
|
||||||
|
#define CANARY 0xba
|
||||||
|
|
||||||
static double dblit(float f)
|
static double dblit(float f)
|
||||||
{
|
{
|
||||||
return f/3.0;
|
return f/3.0;
|
||||||
|
@ -19,8 +27,8 @@ int main (void)
|
||||||
ffi_type *args[MAX_ARGS];
|
ffi_type *args[MAX_ARGS];
|
||||||
void *values[MAX_ARGS];
|
void *values[MAX_ARGS];
|
||||||
float f;
|
float f;
|
||||||
double d;
|
value_type result[2];
|
||||||
|
int i;
|
||||||
|
|
||||||
args[0] = &ffi_type_float;
|
args[0] = &ffi_type_float;
|
||||||
values[0] = &f;
|
values[0] = &f;
|
||||||
|
@ -31,11 +39,19 @@ int main (void)
|
||||||
|
|
||||||
f = 3.14159;
|
f = 3.14159;
|
||||||
|
|
||||||
ffi_call(&cif, FFI_FN(dblit), &d, values);
|
/* Put a canary in the return array. This is a regression test for
|
||||||
|
a buffer overrun. */
|
||||||
|
memset(result[1].c, CANARY, sizeof (double));
|
||||||
|
|
||||||
|
ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
|
||||||
|
|
||||||
/* These are not always the same!! Check for a reasonable delta */
|
/* These are not always the same!! Check for a reasonable delta */
|
||||||
|
|
||||||
CHECK(d - dblit(f) < DBL_EPSILON);
|
CHECK(result[0].d - dblit(f) < DBL_EPSILON);
|
||||||
|
|
||||||
|
/* Check the canary. */
|
||||||
|
for (i = 0; i < sizeof (double); ++i)
|
||||||
|
CHECK(result[1].c[i] == CANARY);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue