mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 17:11:23 +08:00
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>
|
||||
|
||||
PR target/23404
|
||||
|
@ -39,6 +39,7 @@ enum {
|
||||
FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
|
||||
FLAG_RETURNS_FP = 1 << (31-29),
|
||||
FLAG_RETURNS_64BITS = 1 << (31-28),
|
||||
FLAG_RETURNS_128BITS = 1 << (31-27),
|
||||
|
||||
FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
|
||||
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. */
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
|
||||
{
|
||||
flags |= FLAG_RETURNS_128BITS;
|
||||
flags |= FLAG_RETURNS_FP;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
intarg_count++;
|
||||
flags |= FLAG_RETVAL_REFERENCE;
|
||||
|
@ -120,9 +120,13 @@ ffi_call_LINUX64:
|
||||
blr
|
||||
|
||||
.Lfp_return_value:
|
||||
bt 27, .Lfd_return_value
|
||||
bf 28, .Lfloat_return_value
|
||||
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
|
||||
.Lfloat_return_value:
|
||||
stfs %f1, 0(%r30)
|
||||
|
@ -8,6 +8,14 @@
|
||||
#include "ffitest.h"
|
||||
#include "float.h"
|
||||
|
||||
typedef union
|
||||
{
|
||||
double d;
|
||||
unsigned char c[sizeof (double)];
|
||||
} value_type;
|
||||
|
||||
#define CANARY 0xba
|
||||
|
||||
static double dblit(float f)
|
||||
{
|
||||
return f/3.0;
|
||||
@ -19,8 +27,8 @@ int main (void)
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
float f;
|
||||
double d;
|
||||
|
||||
value_type result[2];
|
||||
int i;
|
||||
|
||||
args[0] = &ffi_type_float;
|
||||
values[0] = &f;
|
||||
@ -31,11 +39,19 @@ int main (void)
|
||||
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user