1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 23:36:00 +02:00

Initial checkin

This commit is contained in:
Brian Fiete 2019-08-23 11:56:54 -07:00
parent c74712dad9
commit 078564ac9e
3242 changed files with 1616395 additions and 0 deletions

View file

@ -0,0 +1,41 @@
# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
dg-init
libffi-init
global srcdir subdir
if { [string match $using_gcc "yes"] } {
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" ""
} else {
# Assume we are using the vendor compiler.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" ""
}
dg-finish
# Local Variables:
# tcl-indent-level:4
# End:

View file

@ -0,0 +1,89 @@
/* Area: closure_call
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void
closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
(int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
(int)(*(signed short *)args[4]) +
(int)(*(unsigned long long *)args[5]) +
(int)*(int *)args[6] + (int)(*(int *)args[7]) +
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
(int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
(int)(*(unsigned long long *)args[2]),
(int)*(int *)args[3], (int)(*(signed short *)args[4]),
(int)(*(unsigned long long *)args[5]),
(int)*(int *)args[6], (int)(*(int *)args[7]),
(int)(*(double *)args[8]), (int)*(int *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]),*(int *)args[15],
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
int, signed short, unsigned long long, int,
int, double, int, int, float, int, int,
int, int);
int main (void)
{
ffi_cif cif;
void * code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_sint;
cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_sint;
cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_uint64;
cl_arg_types[6] = &ffi_type_sint;
cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type0)code))
(1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
19, 21, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 680" } */
exit(0);
}

View file

@ -0,0 +1,81 @@
/* Area: closure_call.
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(float *)args[0] +(int)(*(float *)args[1]) +
(int)(*(float *)args[2]) + (int)*(float *)args[3] +
(int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
(int)*(float *)args[6] + (int)(*(int *)args[7]) +
(int)(*(double*)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
(int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(float *)args[0], (int)(*(float *)args[1]),
(int)(*(float *)args[2]), (int)*(float *)args[3],
(int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
(int)*(float *)args[6], (int)(*(int *)args[7]),
(int)(*(double *)args[8]), (int)*(int *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]), *(int *)args[15],
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type1)(float, float, float, float, signed short,
float, float, int, double, int, int, float,
int, int, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = &ffi_type_float;
cl_arg_types[2] = &ffi_type_float;
cl_arg_types[3] = &ffi_type_float;
cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_float;
cl_arg_types[6] = &ffi_type_float;
cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type1)code))
(1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
19, 21, 1);
/* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 255" } */
exit(0);
}

View file

@ -0,0 +1,81 @@
/* Area: closure_call
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(double *)args[0] +(int)(*(double *)args[1]) +
(int)(*(double *)args[2]) + (int)*(double *)args[3] +
(int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
(int)*(double *)args[6] + (int)(*(int *)args[7]) +
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
(int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(double *)args[0], (int)(*(double *)args[1]),
(int)(*(double *)args[2]), (int)*(double *)args[3],
(int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
(int)*(double *)args[6], (int)(*(int *)args[7]),
(int)(*(double*)args[8]), (int)*(int *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(float *)args[13]),
(int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
(int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type2)(double, double, double, double, signed short,
double, double, int, double, int, int, float,
int, float, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
cl_arg_types[0] = &ffi_type_double;
cl_arg_types[1] = &ffi_type_double;
cl_arg_types[2] = &ffi_type_double;
cl_arg_types[3] = &ffi_type_double;
cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_double;
cl_arg_types[6] = &ffi_type_double;
cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_float;
cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type2)code))
(1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
19.0, 21, 1);
/* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 255" } */
exit(0);
}

View file

@ -0,0 +1,82 @@
/* Area: closure_call
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(float *)args[0] +(int)(*(float *)args[1]) +
(int)(*(float *)args[2]) + (int)*(float *)args[3] +
(int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
(int)*(float *)args[6] + (int)(*(float *)args[7]) +
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
(int)(*(float *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(float *)args[0], (int)(*(float *)args[1]),
(int)(*(float *)args[2]), (int)*(float *)args[3],
(int)(*(float *)args[4]), (int)(*(float *)args[5]),
(int)*(float *)args[6], (int)(*(float *)args[7]),
(int)(*(double *)args[8]), (int)*(int *)args[9],
(int)(*(float *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(float *)args[13]),
(int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
(int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type3)(float, float, float, float, float, float,
float, float, double, int, float, float, int,
float, float, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = &ffi_type_float;
cl_arg_types[2] = &ffi_type_float;
cl_arg_types[3] = &ffi_type_float;
cl_arg_types[4] = &ffi_type_float;
cl_arg_types[5] = &ffi_type_float;
cl_arg_types[6] = &ffi_type_float;
cl_arg_types[7] = &ffi_type_float;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_float;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_float;
cl_arg_types[14] = &ffi_type_float;
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type3)code))
(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
19.19, 21.21, 1);
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 135" } */
exit(0);
}

View file

@ -0,0 +1,89 @@
/* Area: closure_call
Purpose: Check multiple long long values passing.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20031026 */
/* { dg-do run } */
#include "ffitest.h"
static void
closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
(int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
(int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
(int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
(int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
(int)*(unsigned long long *)args[10] +
(int)*(unsigned long long *)args[11] +
(int)*(unsigned long long *)args[12] +
(int)*(unsigned long long *)args[13] +
(int)*(unsigned long long *)args[14] +
*(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
(int)*(unsigned long long *)args[1],
(int)*(unsigned long long *)args[2],
(int)*(unsigned long long *)args[3],
(int)*(unsigned long long *)args[4],
(int)*(unsigned long long *)args[5],
(int)*(unsigned long long *)args[6],
(int)*(unsigned long long *)args[7],
(int)*(unsigned long long *)args[8],
(int)*(unsigned long long *)args[9],
(int)*(unsigned long long *)args[10],
(int)*(unsigned long long *)args[11],
(int)*(unsigned long long *)args[12],
(int)*(unsigned long long *)args[13],
(int)*(unsigned long long *)args[14],
*(int *)args[15],
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int i, res;
for (i = 0; i < 15; i++) {
cl_arg_types[i] = &ffi_type_uint64;
}
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type0)code))
(1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
13LL, 19LL, 21LL, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 680" } */
exit(0);
}

View file

@ -0,0 +1,92 @@
/* Area: closure_call
Purpose: Check multiple long long values passing.
Exceed the limit of gpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20031026 */
/* { dg-do run } */
#include "ffitest.h"
static void
closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
(int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
(int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
(int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
(int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
(int)*(int *)args[10] +
(int)*(unsigned long long *)args[11] +
(int)*(unsigned long long *)args[12] +
(int)*(unsigned long long *)args[13] +
(int)*(unsigned long long *)args[14] +
*(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
(int)*(unsigned long long *)args[1],
(int)*(unsigned long long *)args[2],
(int)*(unsigned long long *)args[3],
(int)*(unsigned long long *)args[4],
(int)*(unsigned long long *)args[5],
(int)*(unsigned long long *)args[6],
(int)*(unsigned long long *)args[7],
(int)*(unsigned long long *)args[8],
(int)*(unsigned long long *)args[9],
(int)*(int *)args[10],
(int)*(unsigned long long *)args[11],
(int)*(unsigned long long *)args[12],
(int)*(unsigned long long *)args[13],
(int)*(unsigned long long *)args[14],
*(int *)args[15],
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, unsigned long long,
int, unsigned long long,
unsigned long long, unsigned long long,
unsigned long long, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int i, res;
for (i = 0; i < 10; i++) {
cl_arg_types[i] = &ffi_type_uint64;
}
cl_arg_types[10] = &ffi_type_sint;
for (i = 11; i < 15; i++) {
cl_arg_types[i] = &ffi_type_uint64;
}
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type0)code))
(1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
13LL, 19LL, 21LL, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 680" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: closure_call
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC.
Limitations: none.
PR: PR23404
Originator: <andreast@gcc.gnu.org> 20050830 */
/* { dg-do run } */
#include "ffitest.h"
static void
closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] +
(int)(*(unsigned long long *)args[1]) +
(int)(*(unsigned long long *)args[2]) +
(int)*(unsigned long long *)args[3] +
(int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
(int)*(double *)args[6] + (int)(*(float *)args[7]) +
(int)(*(double *)args[8]) + (int)*(double *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
(int)(*(double *)args[14]) + (int)*(double *)args[15] +
(intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
(int)(*(unsigned long long *)args[1]),
(int)(*(unsigned long long *)args[2]),
(int)*(unsigned long long *)args[3],
(int)(*(int *)args[4]), (int)(*(double *)args[5]),
(int)*(double *)args[6], (int)(*(float *)args[7]),
(int)(*(double *)args[8]), (int)*(double *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(double *)args[14]), (int)(*(double *)args[15]),
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type0)(unsigned long long,
unsigned long long,
unsigned long long,
unsigned long long,
int, double, double, float, double, double,
int, float, int, int, double, double);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_uint64;
cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_uint64;
cl_arg_types[4] = &ffi_type_sint;
cl_arg_types[5] = &ffi_type_double;
cl_arg_types[6] = &ffi_type_double;
cl_arg_types[7] = &ffi_type_float;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_double;
cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_double;
cl_arg_types[15] = &ffi_type_double;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
(void *) 3 /* userdata */, code) == FFI_OK);
res = (*((closure_test_type0)code))
(1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
19, 21., 1.);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 680" } */
exit(0);
}

View file

@ -0,0 +1,95 @@
/* Area: closure_call
Purpose: Check multiple values passing from different type.
Also, exceed the limit of gpr and fpr registers on PowerPC
Darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void
closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
(int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
(int)(*(signed short *)args[4]) +
(int)(*(unsigned long long *)args[5]) +
(int)*(int *)args[6] + (int)(*(int *)args[7]) +
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
(int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
(int)(*(unsigned long long *)args[2]),
(int)*(int *)args[3], (int)(*(signed short *)args[4]),
(int)(*(unsigned long long *)args[5]),
(int)*(int *)args[6], (int)(*(int *)args[7]),
(int)(*(double *)args[8]), (int)*(int *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]),*(int *)args[15],
(int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long,
int, signed short, unsigned long long, int,
int, double, int, int, float, int, int,
int, int);
int main (void)
{
ffi_cif cif;
ffi_closure *pcl;
ffi_type * cl_arg_types[17];
int res;
void *codeloc;
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_sint;
cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_sint;
cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_uint64;
cl_arg_types[6] = &ffi_type_sint;
cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
CHECK(pcl != NULL);
CHECK(codeloc != NULL);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0,
(void *) 3 /* userdata */, codeloc) == FFI_OK);
CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
res = (*((closure_loc_test_type0)codeloc))
(1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
19, 21, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 680" } */
exit(0);
}

View file

@ -0,0 +1,72 @@
/* Area: closure_call (stdcall convention)
Purpose: Check handling when caller expects stdcall callee
Limitations: none.
PR: none.
Originator: <twalljava@dev.java.net> */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static void
closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(int *)args[0] + (int)(*(int *)args[1])
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ (int)(intptr_t)userdata;
printf("%d %d %d %d: %d\n",
(int)*(int *)args[0], (int)(*(int *)args[1]),
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
(int)*(ffi_arg *)resp);
}
typedef int (__stdcall *closure_test_type0)(int, int, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
void* sp_pre;
void* sp_post;
char buf[1024];
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = &ffi_type_uint;
cl_arg_types[3] = &ffi_type_uint;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
(void *) 3 /* userdata */, code) == FFI_OK);
#ifdef _MSC_VER
__asm { mov sp_pre, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
#endif
res = (*(closure_test_type0)code)(0, 1, 2, 3);
#ifdef _MSC_VER
__asm { mov sp_post, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
#endif
/* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 9" } */
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
/* { dg-output "\nstack pointer match" } */
exit(0);
}

View file

@ -0,0 +1,72 @@
/* Area: closure_call (thiscall convention)
Purpose: Check handling when caller expects thiscall callee
Limitations: none.
PR: none.
Originator: <ktietz@redhat.com> */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static void
closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(int *)args[0] + (int)(*(int *)args[1])
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ (int)(intptr_t)userdata;
printf("%d %d %d %d: %d\n",
(int)*(int *)args[0], (int)(*(int *)args[1]),
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
(int)*(ffi_arg *)resp);
}
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
void* sp_pre;
void* sp_post;
char buf[1024];
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = &ffi_type_uint;
cl_arg_types[3] = &ffi_type_uint;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
(void *) 3 /* userdata */, code) == FFI_OK);
#ifdef _MSC_VER
__asm { mov sp_pre, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
#endif
res = (*(closure_test_type0)code)(0, 1, 2, 3);
#ifdef _MSC_VER
__asm { mov sp_post, esp }
#else
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
#endif
/* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 9" } */
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
/* { dg-output "\nstack pointer match" } */
exit(0);
}

View file

@ -0,0 +1,94 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_12byte {
int a;
int b;
int c;
} cls_struct_12byte;
cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
struct cls_struct_12byte b2)
{
struct cls_struct_12byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
result.c = b1.c + b2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
result.a, result.b, result.c);
return result;
}
static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args , void* userdata __UNUSED__)
{
struct cls_struct_12byte b1, b2;
b1 = *(struct cls_struct_12byte*)(args[0]);
b2 = *(struct cls_struct_12byte*)(args[1]);
*(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_12byte h_dbl = { 7, 4, 9 };
struct cls_struct_12byte j_dbl = { 1, 5, 3 };
struct cls_struct_12byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 4 9 1 5 3: 8 9 12" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
exit(0);
}

View file

@ -0,0 +1,95 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_16byte {
int a;
double b;
int c;
} cls_struct_16byte;
cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
struct cls_struct_16byte b2)
{
struct cls_struct_16byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
result.c = b1.c + b2.c;
printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
result.a, result.b, result.c);
return result;
}
static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_16byte b1, b2;
b1 = *(struct cls_struct_16byte*)(args[0]);
b2 = *(struct cls_struct_16byte*)(args[1]);
*(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
struct cls_struct_16byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 8 9 1 9 3: 8 17 12" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 17 12" } */
res_dbl.a = 0;
res_dbl.b = 0.0;
res_dbl.c = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 17 12" } */
exit(0);
}

View file

@ -0,0 +1,96 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Double alignment check on darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_18byte {
double a;
unsigned char b;
unsigned char c;
double d;
} cls_struct_18byte;
cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
struct cls_struct_18byte a2)
{
struct cls_struct_18byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
a2.a, a2.b, a2.c, a2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_18byte a1, a2;
a1 = *(struct cls_struct_18byte*)(args[0]);
a2 = *(struct cls_struct_18byte*)(args[1]);
*(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
struct cls_struct_18byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_double;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
exit(0);
}

View file

@ -0,0 +1,102 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Double alignment check on darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_19byte {
double a;
unsigned char b;
unsigned char c;
double d;
unsigned char e;
} cls_struct_19byte;
cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
struct cls_struct_19byte a2)
{
struct cls_struct_19byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
result.e = a1.e + a2.e;
printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
a1.a, a1.b, a1.c, a1.d, a1.e,
a2.a, a2.b, a2.c, a2.d, a2.e,
result.a, result.b, result.c, result.d, result.e);
return result;
}
static void
cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_19byte a1, a2;
a1 = *(struct cls_struct_19byte*)(args[0]);
a2 = *(struct cls_struct_19byte*)(args[1]);
*(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[6];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
struct cls_struct_19byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_double;
cls_struct_fields[4] = &ffi_type_uchar;
cls_struct_fields[5] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 5 252 250 8 239" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 5 252 250 8 239" } */
exit(0);
}

View file

@ -0,0 +1,89 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_1_1byte {
unsigned char a;
} cls_struct_1_1byte;
cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
struct cls_struct_1_1byte a2)
{
struct cls_struct_1_1byte result;
result.a = a1.a + a2.a;
printf("%d %d: %d\n", a1.a, a2.a, result.a);
return result;
}
static void
cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_1_1byte a1, a2;
a1 = *(struct cls_struct_1_1byte*)(args[0]);
a2 = *(struct cls_struct_1_1byte*)(args[1]);
*(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[2];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_1_1byte g_dbl = { 12 };
struct cls_struct_1_1byte f_dbl = { 178 };
struct cls_struct_1_1byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 178: 190" } */
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 178: 190" } */
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_20byte {
double a;
double b;
int c;
} cls_struct_20byte;
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
struct cls_struct_20byte a2)
{
struct cls_struct_20byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_20byte a1, a2;
a1 = *(struct cls_struct_20byte*)(args[0]);
a2 = *(struct cls_struct_20byte*)(args[1]);
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
struct cls_struct_20byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
exit(0);
}

View file

@ -0,0 +1,93 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_20byte {
int a;
double b;
double c;
} cls_struct_20byte;
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
struct cls_struct_20byte a2)
{
struct cls_struct_20byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_20byte a1, a2;
a1 = *(struct cls_struct_20byte*)(args[0]);
a2 = *(struct cls_struct_20byte*)(args[1]);
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
struct cls_struct_20byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
exit(0);
}

View file

@ -0,0 +1,113 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_24byte {
double a;
double b;
int c;
float d;
} cls_struct_24byte;
cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
struct cls_struct_24byte b1,
struct cls_struct_24byte b2,
struct cls_struct_24byte b3)
{
struct cls_struct_24byte result;
result.a = b0.a + b1.a + b2.a + b3.a;
result.b = b0.b + b1.b + b2.b + b3.b;
result.c = b0.c + b1.c + b2.c + b3.c;
result.d = b0.d + b1.d + b2.d + b3.d;
printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
b0.a, b0.b, b0.c, b0.d,
b1.a, b1.b, b1.c, b1.d,
b2.a, b2.b, b2.c, b2.d,
b3.a, b3.b, b3.c, b2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_24byte b0, b1, b2, b3;
b0 = *(struct cls_struct_24byte*)(args[0]);
b1 = *(struct cls_struct_24byte*)(args[1]);
b2 = *(struct cls_struct_24byte*)(args[2]);
b3 = *(struct cls_struct_24byte*)(args[3]);
*(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
struct cls_struct_24byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = &ffi_type_float;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = &cls_struct_type;
dbl_arg_types[3] = &cls_struct_type;
dbl_arg_types[4] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = &h_dbl;
args_dbl[4] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
/* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte))
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_2byte {
unsigned char a;
unsigned char b;
} cls_struct_2byte;
cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
struct cls_struct_2byte a2)
{
struct cls_struct_2byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_2byte a1, a2;
a1 = *(struct cls_struct_2byte*)(args[0]);
a2 = *(struct cls_struct_2byte*)(args[1]);
*(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_2byte g_dbl = { 12, 127 };
struct cls_struct_2byte f_dbl = { 1, 13 };
struct cls_struct_2byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 127 1 13: 13 140" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 127 1 13: 13 140" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
exit(0);
}

View file

@ -0,0 +1,95 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_3_1byte {
unsigned char a;
unsigned char b;
unsigned char c;
} cls_struct_3_1byte;
cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
struct cls_struct_3_1byte a2)
{
struct cls_struct_3_1byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_3_1byte a1, a2;
a1 = *(struct cls_struct_3_1byte*)(args[0]);
a2 = *(struct cls_struct_3_1byte*)(args[1]);
*(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
struct cls_struct_3_1byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 13 14 178 179 180: 190 192 194" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_3byte {
unsigned short a;
unsigned char b;
} cls_struct_3byte;
cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
struct cls_struct_3byte a2)
{
struct cls_struct_3byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_3byte a1, a2;
a1 = *(struct cls_struct_3byte*)(args[0]);
a2 = *(struct cls_struct_3byte*)(args[1]);
*(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_3byte g_dbl = { 12, 119 };
struct cls_struct_3byte f_dbl = { 1, 15 };
struct cls_struct_3byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 119 1 15: 13 134" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 119 1 15: 13 134" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_3byte_1 {
unsigned char a;
unsigned short b;
} cls_struct_3byte_1;
cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
struct cls_struct_3byte_1 a2)
{
struct cls_struct_3byte_1 result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_3byte_1 a1, a2;
a1 = *(struct cls_struct_3byte_1*)(args[0]);
a2 = *(struct cls_struct_3byte_1*)(args[1]);
*(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_3byte_1 g_dbl = { 15, 125 };
struct cls_struct_3byte_1 f_dbl = { 9, 19 };
struct cls_struct_3byte_1 res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
/* { dg-output "15 125 9 19: 24 144" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 24 144" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
/* { dg-output "\n15 125 9 19: 24 144" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 24 144" } */
exit(0);
}

View file

@ -0,0 +1,98 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_4_1byte {
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
} cls_struct_4_1byte;
cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
struct cls_struct_4_1byte a2)
{
struct cls_struct_4_1byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
a2.a, a2.b, a2.c, a2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_4_1byte a1, a2;
a1 = *(struct cls_struct_4_1byte*)(args[0]);
a2 = *(struct cls_struct_4_1byte*)(args[1]);
*(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
struct cls_struct_4_1byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_uchar;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 190 192 194 196" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 190 192 194 196" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_4byte {
unsigned short a;
unsigned short b;
} cls_struct_4byte;
cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
struct cls_struct_4byte a2)
{
struct cls_struct_4byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_4byte a1, a2;
a1 = *(struct cls_struct_4byte*)(args[0]);
a2 = *(struct cls_struct_4byte*)(args[1]);
*(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_4byte g_dbl = { 127, 120 };
struct cls_struct_4byte f_dbl = { 12, 128 };
struct cls_struct_4byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 12 128: 139 248" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 139 248" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 12 128: 139 248" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 139 248" } */
exit(0);
}

View file

@ -0,0 +1,109 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_5byte {
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
} cls_struct_5byte;
cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
struct cls_struct_5byte a2)
{
struct cls_struct_5byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
result.e = a1.e + a2.e;
printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
a1.a, a1.b, a1.c, a1.d, a1.e,
a2.a, a2.b, a2.c, a2.d, a2.e,
result.a, result.b, result.c, result.d, result.e);
return result;
}
static void
cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_5byte a1, a2;
a1 = *(struct cls_struct_5byte*)(args[0]);
a2 = *(struct cls_struct_5byte*)(args[1]);
*(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[6];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_uchar;
cls_struct_fields[4] = &ffi_type_uchar;
cls_struct_fields[5] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 139 248 10 6 8" } */
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
res_dbl.d = 0;
res_dbl.e = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 139 248 10 6 8" } */
exit(0);
}

View file

@ -0,0 +1,98 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_5byte {
unsigned short a;
unsigned short b;
unsigned char c;
} cls_struct_5byte;
cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
struct cls_struct_5byte a2)
{
struct cls_struct_5byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_5byte a1, a2;
a1 = *(struct cls_struct_5byte*)(args[0]);
a2 = *(struct cls_struct_5byte*)(args[1]);
*(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_5byte g_dbl = { 127, 120, 1 };
struct cls_struct_5byte f_dbl = { 12, 128, 9 };
struct cls_struct_5byte res_dbl = { 0, 0, 0 };
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 12 128 9: 139 248 10" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 139 248 10" } */
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 139 248 10" } */
exit(0);
}

View file

@ -0,0 +1,124 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check bigger struct which overlaps
the gp and fp register count on Darwin/AIX/ppc64.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_64byte {
double a;
double b;
double c;
double d;
double e;
double f;
double g;
double h;
} cls_struct_64byte;
cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
struct cls_struct_64byte b1,
struct cls_struct_64byte b2,
struct cls_struct_64byte b3)
{
struct cls_struct_64byte result;
result.a = b0.a + b1.a + b2.a + b3.a;
result.b = b0.b + b1.b + b2.b + b3.b;
result.c = b0.c + b1.c + b2.c + b3.c;
result.d = b0.d + b1.d + b2.d + b3.d;
result.e = b0.e + b1.e + b2.e + b3.e;
result.f = b0.f + b1.f + b2.f + b3.f;
result.g = b0.g + b1.g + b2.g + b3.g;
result.h = b0.h + b1.h + b2.h + b3.h;
printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
result.d, result.e, result.f, result.g, result.h);
return result;
}
static void
cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_64byte b0, b1, b2, b3;
b0 = *(struct cls_struct_64byte*)(args[0]);
b1 = *(struct cls_struct_64byte*)(args[1]);
b2 = *(struct cls_struct_64byte*)(args[2]);
b3 = *(struct cls_struct_64byte*)(args[3]);
*(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[9];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
struct cls_struct_64byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double;
cls_struct_fields[3] = &ffi_type_double;
cls_struct_fields[4] = &ffi_type_double;
cls_struct_fields[5] = &ffi_type_double;
cls_struct_fields[6] = &ffi_type_double;
cls_struct_fields[7] = &ffi_type_double;
cls_struct_fields[8] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = &cls_struct_type;
dbl_arg_types[3] = &cls_struct_type;
dbl_arg_types[4] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = &h_dbl;
args_dbl[4] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl);
/* { dg-output "22 15 17 25 6 13 19 18" } */
printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
/* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
cls_struct_64byte,
cls_struct_64byte,
cls_struct_64byte))
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n22 15 17 25 6 13 19 18" } */
printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
/* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
exit(0);
}

View file

@ -0,0 +1,113 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_6byte {
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
} cls_struct_6byte;
cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
struct cls_struct_6byte a2)
{
struct cls_struct_6byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
result.e = a1.e + a2.e;
result.f = a1.f + a2.f;
printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
result.a, result.b, result.c, result.d, result.e, result.f);
return result;
}
static void
cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_6byte a1, a2;
a1 = *(struct cls_struct_6byte*)(args[0]);
a2 = *(struct cls_struct_6byte*)(args[1]);
*(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[7];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_uchar;
cls_struct_fields[4] = &ffi_type_uchar;
cls_struct_fields[5] = &ffi_type_uchar;
cls_struct_fields[6] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f);
/* { dg-output "\nres: 139 248 10 6 8 10" } */
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
res_dbl.d = 0;
res_dbl.e = 0;
res_dbl.f = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f);
/* { dg-output "\nres: 139 248 10 6 8 10" } */
exit(0);
}

View file

@ -0,0 +1,99 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_6byte {
unsigned short a;
unsigned short b;
unsigned char c;
unsigned char d;
} cls_struct_6byte;
cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
struct cls_struct_6byte a2)
{
struct cls_struct_6byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
a2.a, a2.b, a2.c, a2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_6byte a1, a2;
a1 = *(struct cls_struct_6byte*)(args[0]);
a2 = *(struct cls_struct_6byte*)(args[1]);
*(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
struct cls_struct_6byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_uchar;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 255" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 255" } */
exit(0);
}

View file

@ -0,0 +1,117 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_7byte {
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
unsigned char g;
} cls_struct_7byte;
cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
struct cls_struct_7byte a2)
{
struct cls_struct_7byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
result.e = a1.e + a2.e;
result.f = a1.f + a2.f;
result.g = a1.g + a2.g;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
result.a, result.b, result.c, result.d, result.e, result.f, result.g);
return result;
}
static void
cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_7byte a1, a2;
a1 = *(struct cls_struct_7byte*)(args[0]);
a2 = *(struct cls_struct_7byte*)(args[1]);
*(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[8];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_uchar;
cls_struct_fields[4] = &ffi_type_uchar;
cls_struct_fields[5] = &ffi_type_uchar;
cls_struct_fields[6] = &ffi_type_uchar;
cls_struct_fields[7] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 139 248 10 6 8 10 12" } */
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
res_dbl.d = 0;
res_dbl.e = 0;
res_dbl.f = 0;
res_dbl.g = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 139 248 10 6 8 10 12" } */
exit(0);
}

View file

@ -0,0 +1,97 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_7byte {
unsigned short a;
unsigned short b;
unsigned char c;
unsigned short d;
} cls_struct_7byte;
cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
struct cls_struct_7byte a2)
{
struct cls_struct_7byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
a2.a, a2.b, a2.c, a2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_7byte a1, a2;
a1 = *(struct cls_struct_7byte*)(args[0]);
a2 = *(struct cls_struct_7byte*)(args[1]);
*(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
struct cls_struct_7byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_ushort;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
/* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 509" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 509" } */
exit(0);
}

View file

@ -0,0 +1,88 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_8byte {
int a;
float b;
} cls_struct_8byte;
cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
struct cls_struct_8byte a2)
{
struct cls_struct_8byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_8byte a1, a2;
a1 = *(struct cls_struct_8byte*)(args[0]);
a2 = *(struct cls_struct_8byte*)(args[1]);
*(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_8byte g_dbl = { 1, 2.0 };
struct cls_struct_8byte f_dbl = { 4, 5.0 };
struct cls_struct_8byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 4 5: 5 7" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 5 7" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 4 5: 5 7" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 5 7" } */
exit(0);
}

View file

@ -0,0 +1,90 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Darwin/AIX do double-word
alignment of the struct if the first element is a double.
Check that it does not here.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030914 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_9byte {
int a;
double b;
} cls_struct_9byte;
cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
struct cls_struct_9byte b2)
{
struct cls_struct_9byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
printf("%d %g %d %g: %d %g\n", b1.a, b1.b, b2.a, b2.b,
result.a, result.b);
return result;
}
static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_9byte b1, b2;
b1 = *(struct cls_struct_9byte*)(args[0]);
b2 = *(struct cls_struct_9byte*)(args[1]);
*(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_9byte h_dbl = { 7, 8.0};
struct cls_struct_9byte j_dbl = { 1, 9.0};
struct cls_struct_9byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 8 1 9: 8 17" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 1 9: 8 17" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Darwin/AIX do double-word
alignment of the struct if the first element is a double.
Check that it does here.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030914 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_9byte {
double a;
int b;
} cls_struct_9byte;
cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
struct cls_struct_9byte b2)
{
struct cls_struct_9byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
printf("%g %d %g %d: %g %d\n", b1.a, b1.b, b2.a, b2.b,
result.a, result.b);
return result;
}
static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_9byte b1, b2;
b1 = *(struct cls_struct_9byte*)(args[0]);
b2 = *(struct cls_struct_9byte*)(args[1]);
*(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_9byte h_dbl = { 7.0, 8};
struct cls_struct_9byte j_dbl = { 1.0, 9};
struct cls_struct_9byte res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 8 1 9: 8 17" } */
printf("res: %g %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 1 9: 8 17" } */
printf("res: %g %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
exit(0);
}

View file

@ -0,0 +1,93 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of double.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
double b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of float.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
float b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,92 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of long double.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
long double b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,134 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of long double.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
typedef struct cls_struct_align {
long double a;
long double b;
long double c;
long double d;
long double e;
long double f;
long double g;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(
cls_struct_align a1,
cls_struct_align a2)
{
struct cls_struct_align r;
r.a = a1.a + a2.a;
r.b = a1.b + a2.b;
r.c = a1.c + a2.c;
r.d = a1.d + a2.d;
r.e = a1.e + a2.e;
r.f = a1.f + a2.f;
r.g = a1.g + a2.g;
printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
return r;
}
cls_struct_align cls_struct_align_fn2(
cls_struct_align a1)
{
struct cls_struct_align r;
r.a = a1.a + 1;
r.b = a1.b + 1;
r.c = a1.c + 1;
r.d = a1.d + 1;
r.e = a1.e + 1;
r.f = a1.f + 1;
r.g = a1.g + 1;
printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
return r;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[8];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_longdouble;
cls_struct_fields[3] = &ffi_type_longdouble;
cls_struct_fields[4] = &ffi_type_longdouble;
cls_struct_fields[5] = &ffi_type_longdouble;
cls_struct_fields[6] = &ffi_type_longdouble;
cls_struct_fields[7] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
exit(0);
}

View file

@ -0,0 +1,117 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of long double.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/18/2007
*/
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
/* { dg-do run { xfail strongarm*-*-* } } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
typedef struct cls_struct_align {
long double a;
long double b;
long double c;
long double d;
long double e;
double f;
long double g;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(
cls_struct_align a1,
cls_struct_align a2)
{
struct cls_struct_align r;
r.a = a1.a + a2.a;
r.b = a1.b + a2.b;
r.c = a1.c + a2.c;
r.d = a1.d + a2.d;
r.e = a1.e + a2.e;
r.f = a1.f + a2.f;
r.g = a1.g + a2.g;
printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
"%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
return r;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[8];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_longdouble;
cls_struct_fields[2] = &ffi_type_longdouble;
cls_struct_fields[3] = &ffi_type_longdouble;
cls_struct_fields[4] = &ffi_type_longdouble;
cls_struct_fields[5] = &ffi_type_double;
cls_struct_fields[6] = &ffi_type_longdouble;
cls_struct_fields[7] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
exit(0);
}

View file

@ -0,0 +1,95 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of pointer.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
void *b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
result.c = a1.c + a2.c;
printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n",
a1.a, (uintptr_t)a1.b, a1.c,
a2.a, (uintptr_t)a2.b, a2.c,
result.a, (uintptr_t)result.b,
result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_pointer;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of sint16.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
signed short b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sshort;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of sint32.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
signed int b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,92 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of sint64.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
signed long long b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint64;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of uint16.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
unsigned short b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of uint32.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
unsigned int b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,93 @@
/* Area: ffi_call, closure_call
Purpose: Check structure alignment of uint64.
Limitations: none.
PR: none.
Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run } */
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
#include "ffitest.h"
typedef struct cls_struct_align {
unsigned char a;
unsigned long long b;
unsigned char c;
} cls_struct_align;
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align a2)
{
struct cls_struct_align result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
static void
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_align a1, a2;
a1 = *(struct cls_struct_align*)(args[0]);
a2 = *(struct cls_struct_align*)(args[1]);
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
struct cls_struct_align g_dbl = { 12, 4951, 127 };
struct cls_struct_align f_dbl = { 1, 9320, 13 };
struct cls_struct_align res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint64;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
}

View file

@ -0,0 +1,66 @@
/* Area: ffi_call, closure_call
Purpose: Check double arguments in structs.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/23/2007 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct Dbls {
double x;
double y;
} Dbls;
void
closure_test_fn(Dbls p)
{
printf("%.1f %.1f\n", p.x, p.y);
}
void
closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
void** args, void* userdata __UNUSED__)
{
closure_test_fn(*(Dbls*)args[0]);
}
int main(int argc __UNUSED__, char** argv __UNUSED__)
{
ffi_cif cif;
void *code;
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type* cl_arg_types[1];
ffi_type ts1_type;
ffi_type* ts1_type_elements[4];
Dbls arg = { 1.0, 2.0 };
ts1_type.size = 0;
ts1_type.alignment = 0;
ts1_type.type = FFI_TYPE_STRUCT;
ts1_type.elements = ts1_type_elements;
ts1_type_elements[0] = &ffi_type_double;
ts1_type_elements[1] = &ffi_type_double;
ts1_type_elements[2] = NULL;
cl_arg_types[0] = &ts1_type;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_void, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
((void*(*)(Dbls))(code))(arg);
/* { dg-output "1.0 2.0\n" } */
closure_test_fn(arg);
/* { dg-output "1.0 2.0\n" } */
return 0;
}

View file

@ -0,0 +1,43 @@
/* Area: closure_call
Purpose: Check return value double.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(double *)resp = *(double *)args[0];
printf("%f: %f\n",*(double *)args[0],
*(double *)resp);
}
typedef double (*cls_ret_double)(double);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
double res;
cl_arg_types[0] = &ffi_type_double;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_double, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_double)code))(21474.789);
/* { dg-output "21474.789000: 21474.789000" } */
printf("res: %.6f\n", res);
/* { dg-output "\nres: 21474.789000" } */
exit(0);
}

View file

@ -0,0 +1,63 @@
/* Area: ffi_call, closure_call
Purpose: Test doubles passed in variable argument lists.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
#include "ffitest.h"
static void
cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
char* format = *(char**)args[0];
double doubleValue = *(double*)args[1];
*(ffi_arg*)resp = printf(format, doubleValue);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
ffi_type* arg_types[3];
char* format = "%.1f\n";
double doubleArg = 7;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_double;
arg_types[2] = NULL;
/* This printf call is variadic */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
arg_types) == FFI_OK);
args[0] = &format;
args[1] = &doubleArg;
args[2] = NULL;
ffi_call(&cif, FFI_FN(printf), &res, args);
/* { dg-output "7.0" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 4" } */
/* The call to cls_double_va_fn is static, so have to use a normal prep_cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
res = ((int(*)(char*, double))(code))(format, doubleArg);
/* { dg-output "\n7.0" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 4" } */
exit(0);
}

View file

@ -0,0 +1,42 @@
/* Area: closure_call
Purpose: Check return value float.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(float *)resp = *(float *)args[0];
printf("%g: %g\n",*(float *)args[0],
*(float *)resp);
}
typedef float (*cls_ret_float)(float);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
float res;
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_float, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK);
res = ((((cls_ret_float)code)(-2122.12)));
/* { dg-output "\\-2122.12: \\-2122.12" } */
printf("res: %.6f\n", res);
/* { dg-output "\nres: \-2122.120117" } */
exit(0);
}

View file

@ -0,0 +1,107 @@
/* Area: ffi_call, closure_call
Purpose: Check long double arguments.
Limitations: none.
PR: none.
Originator: Blake Chaffin */
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
/* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have
remove the xfail for arm*-*-* below, until we know more. */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
long double cls_ldouble_fn(
long double a1,
long double a2,
long double a3,
long double a4,
long double a5,
long double a6,
long double a7,
long double a8)
{
long double r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
a1, a2, a3, a4, a5, a6, a7, a8, r);
return r;
}
static void
cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
long double a1 = *(long double*)args[0];
long double a2 = *(long double*)args[1];
long double a3 = *(long double*)args[2];
long double a4 = *(long double*)args[3];
long double a5 = *(long double*)args[4];
long double a6 = *(long double*)args[5];
long double a7 = *(long double*)args[6];
long double a8 = *(long double*)args[7];
*(long double*)resp = cls_ldouble_fn(
a1, a2, a3, a4, a5, a6, a7, a8);
}
int main(void)
{
ffi_cif cif;
void* code;
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[9];
ffi_type* arg_types[9];
long double res = 0;
long double arg1 = 1;
long double arg2 = 2;
long double arg3 = 3;
long double arg4 = 4;
long double arg5 = 5;
long double arg6 = 6;
long double arg7 = 7;
long double arg8 = 8;
arg_types[0] = &ffi_type_longdouble;
arg_types[1] = &ffi_type_longdouble;
arg_types[2] = &ffi_type_longdouble;
arg_types[3] = &ffi_type_longdouble;
arg_types[4] = &ffi_type_longdouble;
arg_types[5] = &ffi_type_longdouble;
arg_types[6] = &ffi_type_longdouble;
arg_types[7] = &ffi_type_longdouble;
arg_types[8] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
arg_types) == FFI_OK);
args[0] = &arg1;
args[1] = &arg2;
args[2] = &arg3;
args[3] = &arg4;
args[4] = &arg5;
args[5] = &arg6;
args[6] = &arg7;
args[7] = &arg8;
args[8] = NULL;
ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
/* { dg-output "1 2 3 4 5 6 7 8: 36" } */
printf("res: %Lg\n", res);
/* { dg-output "\nres: 36" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
res = ((long double(*)(long double, long double, long double, long double,
long double, long double, long double, long double))(code))(arg1, arg2,
arg3, arg4, arg5, arg6, arg7, arg8);
/* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
printf("res: %Lg\n", res);
/* { dg-output "\nres: 36" } */
return 0;
}

View file

@ -0,0 +1,64 @@
/* Area: ffi_call, closure_call
Purpose: Test long doubles passed in variable argument lists.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
#include "ffitest.h"
static void
cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
char* format = *(char**)args[0];
long double ldValue = *(long double*)args[1];
*(ffi_arg*)resp = printf(format, ldValue);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
ffi_type* arg_types[3];
char* format = "%.1Lf\n";
long double ldArg = 7;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_longdouble;
arg_types[2] = NULL;
/* This printf call is variadic */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
arg_types) == FFI_OK);
args[0] = &format;
args[1] = &ldArg;
args[2] = NULL;
ffi_call(&cif, FFI_FN(printf), &res, args);
/* { dg-output "7.0" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 4" } */
/* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
res = ((int(*)(char*, long double))(code))(format, ldArg);
/* { dg-output "\n7.0" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 4" } */
exit(0);
}

View file

@ -0,0 +1,74 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple signed char values.
Limitations: none.
PR: PR13221.
Originator: <hos@tamanegi.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
signed char test_func_fn(signed char a1, signed char a2)
{
signed char result;
result = a1 + a2;
printf("%d %d: %d\n", a1, a2, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
signed char a1, a2;
a1 = *(signed char *)avals[0];
a2 = *(signed char *)avals[1];
*(ffi_arg *)rval = test_func_fn(a1, a2);
}
typedef signed char (*test_type)(signed char, signed char);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
signed char a, b, res_closure;
a = 2;
b = 125;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_schar;
cl_arg_types[1] = &ffi_type_schar;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
&ffi_type_schar, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "2 125: 127" } */
printf("res: %d\n", (signed char)res_call);
/* { dg-output "\nres: 127" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(2, 125);
/* { dg-output "\n2 125: 127" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 127" } */
exit(0);
}

View file

@ -0,0 +1,74 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple signed short values.
Limitations: none.
PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
signed short test_func_fn(signed short a1, signed short a2)
{
signed short result;
result = a1 + a2;
printf("%d %d: %d\n", a1, a2, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
signed short a1, a2;
a1 = *(signed short *)avals[0];
a2 = *(signed short *)avals[1];
*(ffi_arg *)rval = test_func_fn(a1, a2);
}
typedef signed short (*test_type)(signed short, signed short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
unsigned short a, b, res_closure;
a = 2;
b = 32765;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_sshort;
cl_arg_types[1] = &ffi_type_sshort;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
&ffi_type_sshort, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "2 32765: 32767" } */
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 32767" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(2, 32765);
/* { dg-output "\n2 32765: 32767" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32767" } */
exit(0);
}

View file

@ -0,0 +1,86 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple signed short/char values.
Limitations: none.
PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
signed short test_func_fn(signed char a1, signed short a2,
signed char a3, signed short a4)
{
signed short result;
result = a1 + a2 + a3 + a4;
printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
signed char a1, a3;
signed short a2, a4;
a1 = *(signed char *)avals[0];
a2 = *(signed short *)avals[1];
a3 = *(signed char *)avals[2];
a4 = *(signed short *)avals[3];
*(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
}
typedef signed short (*test_type)(signed char, signed short,
signed char, signed short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
signed char a, c;
signed short b, d, res_closure;
a = 1;
b = 32765;
c = 127;
d = -128;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = &c;
args_dbl[3] = &d;
args_dbl[4] = NULL;
cl_arg_types[0] = &ffi_type_schar;
cl_arg_types[1] = &ffi_type_sshort;
cl_arg_types[2] = &ffi_type_schar;
cl_arg_types[3] = &ffi_type_sshort;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
&ffi_type_sshort, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "1 32765 127 -128: 32765" } */
printf("res: %d\n", (signed short)res_call);
/* { dg-output "\nres: 32765" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(1, 32765, 127, -128);
/* { dg-output "\n1 32765 127 -128: 32765" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32765" } */
exit(0);
}

View file

@ -0,0 +1,91 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple unsigned char values.
Limitations: none.
PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
unsigned char test_func_fn(unsigned char a1, unsigned char a2,
unsigned char a3, unsigned char a4)
{
unsigned char result;
result = a1 + a2 + a3 + a4;
printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
unsigned char a1, a2, a3, a4;
a1 = *(unsigned char *)avals[0];
a2 = *(unsigned char *)avals[1];
a3 = *(unsigned char *)avals[2];
a4 = *(unsigned char *)avals[3];
*(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
}
typedef unsigned char (*test_type)(unsigned char, unsigned char,
unsigned char, unsigned char);
void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
void *data __UNUSED__)
{
printf("%d %d %d %d\n", *(unsigned char *)avals[0],
*(unsigned char *)avals[1], *(unsigned char *)avals[2],
*(unsigned char *)avals[3]);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
unsigned char a, b, c, d, res_closure;
a = 1;
b = 2;
c = 127;
d = 125;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = &c;
args_dbl[3] = &d;
args_dbl[4] = NULL;
cl_arg_types[0] = &ffi_type_uchar;
cl_arg_types[1] = &ffi_type_uchar;
cl_arg_types[2] = &ffi_type_uchar;
cl_arg_types[3] = &ffi_type_uchar;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
&ffi_type_uchar, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "1 2 127 125: 255" } */
printf("res: %d\n", (unsigned char)res_call);
/* { dg-output "\nres: 255" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(1, 2, 127, 125);
/* { dg-output "\n1 2 127 125: 255" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 255" } */
exit(0);
}

View file

@ -0,0 +1,74 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple unsigned short values.
Limitations: none.
PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
unsigned short test_func_fn(unsigned short a1, unsigned short a2)
{
unsigned short result;
result = a1 + a2;
printf("%d %d: %d\n", a1, a2, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
unsigned short a1, a2;
a1 = *(unsigned short *)avals[0];
a2 = *(unsigned short *)avals[1];
*(ffi_arg *)rval = test_func_fn(a1, a2);
}
typedef unsigned short (*test_type)(unsigned short, unsigned short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
unsigned short a, b, res_closure;
a = 2;
b = 32765;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_ushort;
cl_arg_types[1] = &ffi_type_ushort;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
&ffi_type_ushort, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "2 32765: 32767" } */
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 32767" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(2, 32765);
/* { dg-output "\n2 32765: 32767" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32767" } */
exit(0);
}

View file

@ -0,0 +1,86 @@
/* Area: ffi_call, closure_call
Purpose: Check passing of multiple unsigned short/char values.
Limitations: none.
PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run } */
#include "ffitest.h"
unsigned short test_func_fn(unsigned char a1, unsigned short a2,
unsigned char a3, unsigned short a4)
{
unsigned short result;
result = a1 + a2 + a3 + a4;
printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
return result;
}
static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{
unsigned char a1, a3;
unsigned short a2, a4;
a1 = *(unsigned char *)avals[0];
a2 = *(unsigned short *)avals[1];
a3 = *(unsigned char *)avals[2];
a4 = *(unsigned short *)avals[3];
*(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
}
typedef unsigned short (*test_type)(unsigned char, unsigned short,
unsigned char, unsigned short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
unsigned char a, c;
unsigned short b, d, res_closure;
a = 1;
b = 2;
c = 127;
d = 128;
args_dbl[0] = &a;
args_dbl[1] = &b;
args_dbl[2] = &c;
args_dbl[3] = &d;
args_dbl[4] = NULL;
cl_arg_types[0] = &ffi_type_uchar;
cl_arg_types[1] = &ffi_type_ushort;
cl_arg_types[2] = &ffi_type_uchar;
cl_arg_types[3] = &ffi_type_ushort;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
&ffi_type_ushort, cl_arg_types) == FFI_OK);
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "1 2 127 128: 258" } */
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 258" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
res_closure = (*((test_type)code))(1, 2, 127, 128);
/* { dg-output "\n1 2 127 128: 258" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 258" } */
exit(0);
}

View file

@ -0,0 +1,74 @@
/* Area: ffi_call, closure_call
Purpose: Check pointer arguments.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
#include "ffitest.h"
void* cls_pointer_fn(void* a1, void* a2)
{
void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
printf("0x%08x 0x%08x: 0x%08x\n",
(unsigned int)(uintptr_t) a1,
(unsigned int)(uintptr_t) a2,
(unsigned int)(uintptr_t) result);
return result;
}
static void
cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
void* a1 = *(void**)(args[0]);
void* a2 = *(void**)(args[1]);
*(void**)resp = cls_pointer_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
/* ffi_type cls_pointer_type; */
ffi_type* arg_types[3];
/* cls_pointer_type.size = sizeof(void*);
cls_pointer_type.alignment = 0;
cls_pointer_type.type = FFI_TYPE_POINTER;
cls_pointer_type.elements = NULL;*/
void* arg1 = (void*)0x12345678;
void* arg2 = (void*)0x89abcdef;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_pointer;
arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
arg_types) == FFI_OK);
args[0] = &arg1;
args[1] = &arg2;
args[2] = NULL;
ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
/* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
printf("res: 0x%08x\n", (unsigned int) res);
/* { dg-output "\nres: 0x9be02467" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
/* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
printf("res: 0x%08x\n", (unsigned int) res);
/* { dg-output "\nres: 0x9be02467" } */
exit(0);
}

View file

@ -0,0 +1,142 @@
/* Area: ffi_call, closure_call
Purpose: Check pointer arguments across multiple hideous stack frames.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/7/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
#include "ffitest.h"
static long dummyVar;
long dummy_func(
long double a1, char b1,
long double a2, char b2,
long double a3, char b3,
long double a4, char b4)
{
return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
}
void* cls_pointer_fn2(void* a1, void* a2)
{
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
char trample4 = trample2 + ((char*)&a1)[1];
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
char trample6 = trample4 + ((char*)&a2)[1];
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
char trample8 = trample6 + trample2;
void* result;
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
trample5, trample6, trample7, trample8);
result = (void*)((intptr_t)a1 + (intptr_t)a2);
printf("0x%08x 0x%08x: 0x%08x\n",
(unsigned int)(uintptr_t) a1,
(unsigned int)(uintptr_t) a2,
(unsigned int)(uintptr_t) result);
return result;
}
void* cls_pointer_fn1(void* a1, void* a2)
{
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
char trample4 = trample2 + ((char*)&a1)[1];
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
char trample6 = trample4 + ((char*)&a2)[1];
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
char trample8 = trample6 + trample2;
void* result;
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
trample5, trample6, trample7, trample8);
result = (void*)((intptr_t)a1 + (intptr_t)a2);
printf("0x%08x 0x%08x: 0x%08x\n",
(unsigned int)(intptr_t) a1,
(unsigned int)(intptr_t) a2,
(unsigned int)(intptr_t) result);
result = cls_pointer_fn2(result, a1);
return result;
}
static void
cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
void* a1 = *(void**)(args[0]);
void* a2 = *(void**)(args[1]);
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
char trample4 = trample2 + ((char*)&a1)[1];
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
char trample6 = trample4 + ((char*)&a2)[1];
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
char trample8 = trample6 + trample2;
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
trample5, trample6, trample7, trample8);
*(void**)resp = cls_pointer_fn1(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
/* ffi_type cls_pointer_type; */
ffi_type* arg_types[3];
/* cls_pointer_type.size = sizeof(void*);
cls_pointer_type.alignment = 0;
cls_pointer_type.type = FFI_TYPE_POINTER;
cls_pointer_type.elements = NULL;*/
void* arg1 = (void*)0x01234567;
void* arg2 = (void*)0x89abcdef;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_pointer;
arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
arg_types) == FFI_OK);
args[0] = &arg1;
args[1] = &arg2;
args[2] = NULL;
printf("\n");
ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
printf("res: 0x%08x\n", (unsigned int) res);
/* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
/* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
/* { dg-output "\nres: 0x8bf258bd" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
printf("res: 0x%08x\n", (unsigned int) res);
/* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
/* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
/* { dg-output "\nres: 0x8bf258bd" } */
exit(0);
}

View file

@ -0,0 +1,44 @@
/* Area: closure_call
Purpose: Check return value schar.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20031108 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg*)resp = *(signed char *)args[0];
printf("%d: %d\n",*(signed char *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef signed char (*cls_ret_schar)(signed char);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed char res;
cl_arg_types[0] = &ffi_type_schar;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_schar, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_schar)code))(127);
/* { dg-output "127: 127" } */
printf("res: %d\n", res);
/* { dg-output "\nres: 127" } */
exit(0);
}

View file

@ -0,0 +1,42 @@
/* Area: closure_call
Purpose: Check return value sint32.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20031108 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg*)resp = *(signed int *)args[0];
printf("%d: %d\n",*(signed int *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef signed int (*cls_ret_sint)(signed int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed int res;
cl_arg_types[0] = &ffi_type_sint;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_sint)code))(65534);
/* { dg-output "65534: 65534" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 65534" } */
exit(0);
}

View file

@ -0,0 +1,42 @@
/* Area: closure_call
Purpose: Check return value sshort.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20031108 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg*)resp = *(signed short *)args[0];
printf("%d: %d\n",*(signed short *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef signed short (*cls_ret_sshort)(signed short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed short res;
cl_arg_types[0] = &ffi_type_sshort;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_sshort, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_sshort)code))(255);
/* { dg-output "255: 255" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 255" } */
exit(0);
}

View file

@ -0,0 +1,114 @@
/* Area: ffi_call, closure_call
Purpose: Test doubles passed in variable argument lists.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run } */
/* { dg-output "" { xfail avr32*-*-* } } */
#include "ffitest.h"
struct small_tag
{
unsigned char a;
unsigned char b;
};
struct large_tag
{
unsigned a;
unsigned b;
unsigned c;
unsigned d;
unsigned e;
};
static void
test_fn (ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
int n = *(int*)args[0];
struct small_tag s1 = * (struct small_tag *) args[1];
struct large_tag l1 = * (struct large_tag *) args[2];
struct small_tag s2 = * (struct small_tag *) args[3];
printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
l1.a, l1.b, l1.c, l1.d, l1.e,
s2.a, s2.b);
* (int*) resp = 42;
}
int
main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
ffi_type* arg_types[5];
ffi_arg res = 0;
ffi_type s_type;
ffi_type *s_type_elements[3];
ffi_type l_type;
ffi_type *l_type_elements[6];
struct small_tag s1;
struct small_tag s2;
struct large_tag l1;
int si;
s_type.size = 0;
s_type.alignment = 0;
s_type.type = FFI_TYPE_STRUCT;
s_type.elements = s_type_elements;
s_type_elements[0] = &ffi_type_uchar;
s_type_elements[1] = &ffi_type_uchar;
s_type_elements[2] = NULL;
l_type.size = 0;
l_type.alignment = 0;
l_type.type = FFI_TYPE_STRUCT;
l_type.elements = l_type_elements;
l_type_elements[0] = &ffi_type_uint;
l_type_elements[1] = &ffi_type_uint;
l_type_elements[2] = &ffi_type_uint;
l_type_elements[3] = &ffi_type_uint;
l_type_elements[4] = &ffi_type_uint;
l_type_elements[5] = NULL;
arg_types[0] = &ffi_type_sint;
arg_types[1] = &s_type;
arg_types[2] = &l_type;
arg_types[3] = &s_type;
arg_types[4] = NULL;
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
arg_types) == FFI_OK);
si = 4;
s1.a = 5;
s1.b = 6;
s2.a = 20;
s2.b = 21;
l1.a = 10;
l1.b = 11;
l1.c = 12;
l1.d = 13;
l1.e = 14;
CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
/* { dg-output "4 5 6 10 11 12 13 14 20 21" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 42" } */
exit(0);
}

View file

@ -0,0 +1,42 @@
/* Area: closure_call
Purpose: Check return value uchar.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg*)resp = *(unsigned char *)args[0];
printf("%d: %d\n",*(unsigned char *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef unsigned char (*cls_ret_uchar)(unsigned char);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned char res;
cl_arg_types[0] = &ffi_type_uchar;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uchar, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_uchar)code))(127);
/* { dg-output "127: 127" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 127" } */
exit(0);
}

View file

@ -0,0 +1,44 @@
/* Area: closure_call
Purpose: Test anonymous unsigned char argument.
Limitations: none.
PR: none.
Originator: ARM Ltd. */
/* { dg-do run } */
#include "ffitest.h"
typedef unsigned char T;
static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg *)resp = *(T *)args[0];
printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
}
typedef T (*cls_ret_T)(T, ...);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[3];
T res;
cl_arg_types[0] = &ffi_type_uchar;
cl_arg_types[1] = &ffi_type_uchar;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
&ffi_type_uchar, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
res = ((((cls_ret_T)code)(67, 4)));
/* { dg-output "67: 67 4" } */
printf("res: %d\n", res);
/* { dg-output "\nres: 67" } */
exit(0);
}

View file

@ -0,0 +1,43 @@
/* Area: closure_call
Purpose: Check return value uint.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg *)resp = *(unsigned int *)args[0];
printf("%d: %d\n",*(unsigned int *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef unsigned int (*cls_ret_uint)(unsigned int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned int res;
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_uint)code))(2147483647);
/* { dg-output "2147483647: 2147483647" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 2147483647" } */
exit(0);
}

View file

@ -0,0 +1,45 @@
/* Area: closure_call
Purpose: Test anonymous unsigned int argument.
Limitations: none.
PR: none.
Originator: ARM Ltd. */
/* { dg-do run } */
#include "ffitest.h"
typedef unsigned int T;
static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(T *)resp = *(T *)args[0];
printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
}
typedef T (*cls_ret_T)(T, ...);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[3];
T res;
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
&ffi_type_uint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
res = ((((cls_ret_T)code)(67, 4)));
/* { dg-output "67: 67 4" } */
printf("res: %d\n", res);
/* { dg-output "\nres: 67" } */
exit(0);
}

View file

@ -0,0 +1,45 @@
/* Area: closure_call
Purpose: Test anonymous unsigned long argument.
Limitations: none.
PR: none.
Originator: ARM Ltd. */
/* { dg-do run } */
#include "ffitest.h"
typedef unsigned long T;
static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(T *)resp = *(T *)args[0];
printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
}
typedef T (*cls_ret_T)(T, ...);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[3];
T res;
cl_arg_types[0] = &ffi_type_ulong;
cl_arg_types[1] = &ffi_type_ulong;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
&ffi_type_ulong, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
res = ((((cls_ret_T)code)(67, 4)));
/* { dg-output "67: 67 4" } */
printf("res: %ld\n", res);
/* { dg-output "\nres: 67" } */
exit(0);
}

View file

@ -0,0 +1,47 @@
/* Area: closure_call
Purpose: Check return value long long.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
#include "ffitest.h"
static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
*(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0];
printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
*(unsigned long long *)(resp));
}
typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned long long res;
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uint64, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_ulonglong)code))(214LL);
/* { dg-output "214: 1152921504606846761" } */
printf("res: %" PRIdLL "\n", res);
/* { dg-output "\nres: 1152921504606846761" } */
res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
/* { dg-output "\n9223372035854775808: 8070450533247928831" } */
printf("res: %" PRIdLL "\n", res);
/* { dg-output "\nres: 8070450533247928831" } */
exit(0);
}

View file

@ -0,0 +1,43 @@
/* Area: closure_call
Purpose: Check return value ushort.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg*)resp = *(unsigned short *)args[0];
printf("%d: %d\n",*(unsigned short *)args[0],
(int)*(ffi_arg *)(resp));
}
typedef unsigned short (*cls_ret_ushort)(unsigned short);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned short res;
cl_arg_types[0] = &ffi_type_ushort;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_ushort, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK);
res = (*((cls_ret_ushort)code))(65535);
/* { dg-output "65535: 65535" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 65535" } */
exit(0);
}

View file

@ -0,0 +1,44 @@
/* Area: closure_call
Purpose: Test anonymous unsigned short argument.
Limitations: none.
PR: none.
Originator: ARM Ltd. */
/* { dg-do run } */
#include "ffitest.h"
typedef unsigned short T;
static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
*(ffi_arg *)resp = *(T *)args[0];
printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]);
}
typedef T (*cls_ret_T)(T, ...);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[3];
T res;
cl_arg_types[0] = &ffi_type_ushort;
cl_arg_types[1] = &ffi_type_ushort;
cl_arg_types[2] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
&ffi_type_ushort, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK);
res = ((((cls_ret_T)code)(67, 4)));
/* { dg-output "67: 67 4" } */
printf("res: %d\n", res);
/* { dg-output "\nres: 67" } */
exit(0);
}

View file

@ -0,0 +1,36 @@
/* Area: ffi_prep_cif, ffi_prep_closure
Purpose: Test error return for bad ABIs.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run } */
#include "ffitest.h"
static void
dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
void** args __UNUSED__, void* userdata __UNUSED__)
{}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type* arg_types[1];
arg_types[0] = NULL;
CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
arg_types) == FFI_BAD_ABI);
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
arg_types) == FFI_OK);
cif.abi= 255;
CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
exit(0);
}

View file

@ -0,0 +1,26 @@
/* Area: ffi_prep_cif
Purpose: Test error return for bad typedefs.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run } */
#include "ffitest.h"
int main (void)
{
ffi_cif cif;
ffi_type* arg_types[1];
ffi_type badType = ffi_type_void;
arg_types[0] = NULL;
badType.size = 0;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
arg_types) == FFI_BAD_TYPEDEF);
exit(0);
}

View file

@ -0,0 +1,50 @@
/* Area: ffi_call
Purpose: Check fastcall fct call on X86_WIN32 systems.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static size_t __FASTCALL__ my_fastcall_f(char *s, float a)
{
return (size_t) ((int) strlen(s) + (int) a);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
ffi_arg rint;
char *s;
float v2;
args[0] = &ffi_type_pointer;
args[1] = &ffi_type_float;
values[0] = (void*) &s;
values[1] = (void*) &v2;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
&ffi_type_sint, args) == FFI_OK);
s = "a";
v2 = 0.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 1);
s = "1234567";
v2 = -1.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 6);
s = "1234567890123456789012345";
v2 = 1.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 26);
printf("fastcall fct1 tests passed\n");
exit(0);
}

View file

@ -0,0 +1,50 @@
/* Area: ffi_call
Purpose: Check fastcall fct call on X86_WIN32 systems.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static size_t __FASTCALL__ my_fastcall_f(float a, char *s)
{
return (size_t) ((int) strlen(s) + (int) a);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
ffi_arg rint;
char *s;
float v2;
args[1] = &ffi_type_pointer;
args[0] = &ffi_type_float;
values[1] = (void*) &s;
values[0] = (void*) &v2;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
&ffi_type_sint, args) == FFI_OK);
s = "a";
v2 = 0.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 1);
s = "1234567";
v2 = -1.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 6);
s = "1234567890123456789012345";
v2 = 1.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 26);
printf("fastcall fct2 tests passed\n");
exit(0);
}

View file

@ -0,0 +1,56 @@
/* Area: ffi_call
Purpose: Check fastcall f call on X86_WIN32 systems.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i)
{
return (size_t) ((int) strlen(s) + (int) a + i);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
ffi_arg rint;
char *s;
int v1;
float v2;
args[2] = &ffi_type_sint;
args[1] = &ffi_type_pointer;
args[0] = &ffi_type_float;
values[2] = (void*) &v1;
values[1] = (void*) &s;
values[0] = (void*) &v2;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3,
&ffi_type_sint, args) == FFI_OK);
s = "a";
v1 = 1;
v2 = 0.0;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 2);
s = "1234567";
v2 = -1.0;
v1 = -2;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 4);
s = "1234567890123456789012345";
v2 = 1.0;
v1 = 2;
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
CHECK(rint == 28);
printf("fastcall fct3 tests passed\n");
exit(0);
}

View file

@ -0,0 +1,132 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ffi.h>
#include "fficonfig.h"
#if defined HAVE_STDINT_H
#include <stdint.h>
#endif
#if defined HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#define MAX_ARGS 256
#define CHECK(x) !(x) ? (abort(), 1) : 0
/* Define __UNUSED__ that also other compilers than gcc can run the tests. */
#undef __UNUSED__
#if defined(__GNUC__)
#define __UNUSED__ __attribute__((__unused__))
#else
#define __UNUSED__
#endif
/* Define __FASTCALL__ so that other compilers than gcc can run the tests. */
#undef __FASTCALL__
#if defined _MSC_VER
#define __FASTCALL__ __fastcall
#else
#define __FASTCALL__ __attribute__((fastcall))
#endif
/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
file open. */
#ifdef HAVE_MMAP_ANON
# undef HAVE_MMAP_DEV_ZERO
# include <sys/mman.h>
# ifndef MAP_FAILED
# define MAP_FAILED -1
# endif
# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
# define MAP_ANONYMOUS MAP_ANON
# endif
# define USING_MMAP
#endif
#ifdef HAVE_MMAP_DEV_ZERO
# include <sys/mman.h>
# ifndef MAP_FAILED
# define MAP_FAILED -1
# endif
# define USING_MMAP
#endif
/* MinGW kludge. */
#ifdef _WIN64
#define PRIdLL "I64d"
#define PRIuLL "I64u"
#else
#define PRIdLL "lld"
#define PRIuLL "llu"
#endif
/* Tru64 UNIX kludge. */
#if defined(__alpha__) && defined(__osf__)
/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */
#undef PRIdLL
#define PRIdLL "ld"
#undef PRIuLL
#define PRIuLL "lu"
#define PRId8 "hd"
#define PRIu8 "hu"
#define PRId64 "ld"
#define PRIu64 "lu"
#define PRIuPTR "lu"
#endif
/* PA HP-UX kludge. */
#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
#define PRIuPTR "lu"
#endif
/* IRIX kludge. */
#if defined(__sgi)
/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
compilations. */
#define PRId8 "hhd"
#define PRIu8 "hhu"
#if (_MIPS_SZLONG == 32)
#define PRId64 "lld"
#define PRIu64 "llu"
#endif
/* This doesn't match <inttypes.h>, which always has "lld" here, but the
arguments are uint64_t, int64_t, which are unsigned long, long for
64-bit in <sgidefs.h>. */
#if (_MIPS_SZLONG == 64)
#define PRId64 "ld"
#define PRIu64 "lu"
#endif
/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
are uintptr_t, which is always unsigned long. */
#define PRIuPTR "lu"
#endif
/* Solaris < 10 kludge. */
#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
#if defined(__arch64__) || defined (__x86_64__)
#define PRIuPTR "lu"
#else
#define PRIuPTR "u"
#endif
#endif
/* MSVC kludge. */
#if defined _MSC_VER
#define PRIuPTR "lu"
#define PRIu8 "u"
#define PRId8 "d"
#define PRIu64 "I64u"
#define PRId64 "I64d"
#endif
#ifndef PRIuPTR
#define PRIuPTR "u"
#endif

View file

@ -0,0 +1,59 @@
/* Area: ffi_call
Purpose: Check return value float.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run } */
#include "ffitest.h"
static int floating(int a, float b, double c, long double d)
{
int i;
i = (int) ((float)a/b + ((float)c/(float)d));
return i;
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
ffi_arg rint;
float f;
signed int si1;
double d;
long double ld;
args[0] = &ffi_type_sint;
values[0] = &si1;
args[1] = &ffi_type_float;
values[1] = &f;
args[2] = &ffi_type_double;
values[2] = &d;
args[3] = &ffi_type_longdouble;
values[3] = &ld;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
&ffi_type_sint, args) == FFI_OK);
si1 = 6;
f = 3.14159;
d = (double)1.0/(double)3.0;
ld = 2.71828182846L;
floating (si1, f, d, ld);
ffi_call(&cif, FFI_FN(floating), &rint, values);
printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld));
CHECK((int)rint == floating(si1, f, d, ld));
exit (0);
}

View file

@ -0,0 +1,58 @@
/* Area: ffi_call
Purpose: Check return value double.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run } */
#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;
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
float f;
value_type result[2];
unsigned int i;
args[0] = &ffi_type_float;
values[0] = &f;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_double, args) == FFI_OK);
f = 3.14159;
/* 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(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);
}

View file

@ -0,0 +1,58 @@
/* Area: ffi_call
Purpose: Check return value long double.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-excess-errors "fails" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
#include "float.h"
static long double ldblit(float f)
{
return (long double) (((long double) f)/ (long double) 3.0);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
float f;
long double ld;
args[0] = &ffi_type_float;
values[0] = &f;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_longdouble, args) == FFI_OK);
f = 3.14159;
#if 1
/* This is ifdef'd out for now. long double support under SunOS/gcc
is pretty much non-existent. You'll get the odd bus error in library
routines like printf(). */
printf ("%Lf\n", ldblit(f));
#endif
ld = 666;
ffi_call(&cif, FFI_FN(ldblit), &ld, values);
#if 1
/* This is ifdef'd out for now. long double support under SunOS/gcc
is pretty much non-existent. You'll get the odd bus error in library
routines like printf(). */
printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
#endif
/* These are not always the same!! Check for a reasonable delta */
if (ld - ldblit(f) < LDBL_EPSILON)
puts("long double return value tests ok!");
else
CHECK(0);
exit(0);
}

View file

@ -0,0 +1,72 @@
/* Area: ffi_call
Purpose: Check float arguments with different orders.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run } */
#include "ffitest.h"
#include "float.h"
static double floating_1(float a, double b, long double c)
{
return (double) a + b + (double) c;
}
static double floating_2(long double a, double b, float c)
{
return (double) a + b + (double) c;
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
double rd;
float f;
double d;
long double ld;
args[0] = &ffi_type_float;
values[0] = &f;
args[1] = &ffi_type_double;
values[1] = &d;
args[2] = &ffi_type_longdouble;
values[2] = &ld;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
&ffi_type_double, args) == FFI_OK);
f = 3.14159;
d = (double)1.0/(double)3.0;
ld = 2.71828182846L;
floating_1 (f, d, ld);
ffi_call(&cif, FFI_FN(floating_1), &rd, values);
CHECK(rd - floating_1(f, d, ld) < DBL_EPSILON);
args[0] = &ffi_type_longdouble;
values[0] = &ld;
args[1] = &ffi_type_double;
values[1] = &d;
args[2] = &ffi_type_float;
values[2] = &f;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
&ffi_type_double, args) == FFI_OK);
floating_2 (ld, d, f);
ffi_call(&cif, FFI_FN(floating_2), &rd, values);
CHECK(rd - floating_2(ld, d, f) < DBL_EPSILON);
exit (0);
}

View file

@ -0,0 +1,62 @@
/* Area: ffi_call
Purpose: Check denorm double value.
Limitations: none.
PR: PR26483.
Originator: From the original ffitest.c */
/* { dg-do run } */
/* { dg-options "-mieee" { target alpha*-*-* } } */
#include "ffitest.h"
#include "float.h"
typedef union
{
double d;
unsigned char c[sizeof (double)];
} value_type;
#define CANARY 0xba
static double dblit(double d)
{
return d;
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
double d;
value_type result[2];
unsigned int i;
args[0] = &ffi_type_double;
values[0] = &d;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_double, args) == FFI_OK);
d = DBL_MIN / 2;
/* 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);
/* The standard delta check doesn't work for denorms. Since we didn't do
any arithmetic, we should get the original result back, and hence an
exact check should be OK here. */
CHECK(result[0].d == dblit(d));
/* Check the canary. */
for (i = 0; i < sizeof (double); ++i)
CHECK(result[1].c[i] == CANARY);
exit(0);
}

View file

@ -0,0 +1,107 @@
/* Area: fp and variadics
Purpose: check fp inputs and returns work on variadics, even the fixed params
Limitations: None
PR: none
Originator: <david.gilbert@linaro.org> 2011-01-25
Intended to stress the difference in ABI on ARM vfp
*/
/* { dg-do run } */
#include <stdarg.h>
#include "ffitest.h"
/* prints out all the parameters, and returns the sum of them all.
* 'x' is the number of variadic parameters all of which are double in this test
*/
double float_va_fn(unsigned int x, double y,...)
{
double total=0.0;
va_list ap;
unsigned int i;
total+=(double)x;
total+=y;
printf("%u: %.1f :", x, y);
va_start(ap, y);
for(i=0;i<x;i++)
{
double arg=va_arg(ap, double);
total+=arg;
printf(" %d:%.1f ", i, arg);
}
va_end(ap);
printf(" total: %.1f\n", total);
return total;
}
int main (void)
{
ffi_cif cif;
ffi_type *arg_types[5];
void *values[5];
double doubles[5];
unsigned int firstarg;
double resfp;
/* First test, pass float_va_fn(0,2.0) - note there are no actual
* variadic parameters, but it's declared variadic so the ABI may be
* different. */
/* Call it statically and then via ffi */
resfp=float_va_fn(0,2.0);
/* { dg-output "0: 2.0 : total: 2.0" } */
printf("compiled: %.1f\n", resfp);
/* { dg-output "\ncompiled: 2.0" } */
arg_types[0] = &ffi_type_uint;
arg_types[1] = &ffi_type_double;
arg_types[2] = NULL;
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 2,
&ffi_type_double, arg_types) == FFI_OK);
firstarg = 0;
doubles[0] = 2.0;
values[0] = &firstarg;
values[1] = &doubles[0];
ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
/* { dg-output "\n0: 2.0 : total: 2.0" } */
printf("ffi: %.1f\n", resfp);
/* { dg-output "\nffi: 2.0" } */
/* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
/* Call it statically and then via ffi */
resfp=float_va_fn(2,2.0,3.0,4.0);
/* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */
printf("compiled: %.1f\n", resfp);
/* { dg-output "\ncompiled: 11.0" } */
arg_types[0] = &ffi_type_uint;
arg_types[1] = &ffi_type_double;
arg_types[2] = &ffi_type_double;
arg_types[3] = &ffi_type_double;
arg_types[4] = NULL;
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 4,
&ffi_type_double, arg_types) == FFI_OK);
firstarg = 2;
doubles[0] = 2.0;
doubles[1] = 3.0;
doubles[2] = 4.0;
values[0] = &firstarg;
values[1] = &doubles[0];
values[2] = &doubles[1];
values[3] = &doubles[2];
ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
/* { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } */
printf("ffi: %.1f\n", resfp);
/* { dg-output "\nffi: 11.0" } */
exit(0);
}

View file

@ -0,0 +1,343 @@
/* Area: ffi_call, closure_call
Purpose: Check large structure returns.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/18/2007
*/
/* { dg-excess-errors "" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
/* { dg-options -Wformat=0 { target moxie*-*-elf } } */
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
typedef struct BigStruct{
uint8_t a;
int8_t b;
uint16_t c;
int16_t d;
uint32_t e;
int32_t f;
uint64_t g;
int64_t h;
float i;
double j;
long double k;
char* l;
uint8_t m;
int8_t n;
uint16_t o;
int16_t p;
uint32_t q;
int32_t r;
uint64_t s;
int64_t t;
float u;
double v;
long double w;
char* x;
uint8_t y;
int8_t z;
uint16_t aa;
int16_t bb;
uint32_t cc;
int32_t dd;
uint64_t ee;
int64_t ff;
float gg;
double hh;
long double ii;
char* jj;
uint8_t kk;
int8_t ll;
uint16_t mm;
int16_t nn;
uint32_t oo;
int32_t pp;
uint64_t qq;
int64_t rr;
float ss;
double tt;
long double uu;
char* vv;
uint8_t ww;
int8_t xx;
} BigStruct;
BigStruct
test_large_fn(
uint8_t ui8_1,
int8_t si8_1,
uint16_t ui16_1,
int16_t si16_1,
uint32_t ui32_1,
int32_t si32_1,
uint64_t ui64_1,
int64_t si64_1,
float f_1,
double d_1,
long double ld_1,
char* p_1,
uint8_t ui8_2,
int8_t si8_2,
uint16_t ui16_2,
int16_t si16_2,
uint32_t ui32_2,
int32_t si32_2,
uint64_t ui64_2,
int64_t si64_2,
float f_2,
double d_2,
long double ld_2,
char* p_2,
uint8_t ui8_3,
int8_t si8_3,
uint16_t ui16_3,
int16_t si16_3,
uint32_t ui32_3,
int32_t si32_3,
uint64_t ui64_3,
int64_t si64_3,
float f_3,
double d_3,
long double ld_3,
char* p_3,
uint8_t ui8_4,
int8_t si8_4,
uint16_t ui16_4,
int16_t si16_4,
uint32_t ui32_4,
int32_t si32_4,
uint64_t ui64_4,
int64_t si64_4,
float f_4,
double d_4,
long double ld_4,
char* p_4,
uint8_t ui8_5,
int8_t si8_5)
{
BigStruct retVal = {
ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1),
ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2),
ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3),
ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4),
ui8_5 + 5, si8_5 + 5};
printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
return retVal;
}
static void
cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
{
uint8_t ui8_1 = *(uint8_t*)args[0];
int8_t si8_1 = *(int8_t*)args[1];
uint16_t ui16_1 = *(uint16_t*)args[2];
int16_t si16_1 = *(int16_t*)args[3];
uint32_t ui32_1 = *(uint32_t*)args[4];
int32_t si32_1 = *(int32_t*)args[5];
uint64_t ui64_1 = *(uint64_t*)args[6];
int64_t si64_1 = *(int64_t*)args[7];
float f_1 = *(float*)args[8];
double d_1 = *(double*)args[9];
long double ld_1 = *(long double*)args[10];
char* p_1 = *(char**)args[11];
uint8_t ui8_2 = *(uint8_t*)args[12];
int8_t si8_2 = *(int8_t*)args[13];
uint16_t ui16_2 = *(uint16_t*)args[14];
int16_t si16_2 = *(int16_t*)args[15];
uint32_t ui32_2 = *(uint32_t*)args[16];
int32_t si32_2 = *(int32_t*)args[17];
uint64_t ui64_2 = *(uint64_t*)args[18];
int64_t si64_2 = *(int64_t*)args[19];
float f_2 = *(float*)args[20];
double d_2 = *(double*)args[21];
long double ld_2 = *(long double*)args[22];
char* p_2 = *(char**)args[23];
uint8_t ui8_3 = *(uint8_t*)args[24];
int8_t si8_3 = *(int8_t*)args[25];
uint16_t ui16_3 = *(uint16_t*)args[26];
int16_t si16_3 = *(int16_t*)args[27];
uint32_t ui32_3 = *(uint32_t*)args[28];
int32_t si32_3 = *(int32_t*)args[29];
uint64_t ui64_3 = *(uint64_t*)args[30];
int64_t si64_3 = *(int64_t*)args[31];
float f_3 = *(float*)args[32];
double d_3 = *(double*)args[33];
long double ld_3 = *(long double*)args[34];
char* p_3 = *(char**)args[35];
uint8_t ui8_4 = *(uint8_t*)args[36];
int8_t si8_4 = *(int8_t*)args[37];
uint16_t ui16_4 = *(uint16_t*)args[38];
int16_t si16_4 = *(int16_t*)args[39];
uint32_t ui32_4 = *(uint32_t*)args[40];
int32_t si32_4 = *(int32_t*)args[41];
uint64_t ui64_4 = *(uint64_t*)args[42];
int64_t si64_4 = *(int64_t*)args[43];
float f_4 = *(float*)args[44];
double d_4 = *(double*)args[45];
long double ld_4 = *(long double*)args[46];
char* p_4 = *(char**)args[47];
uint8_t ui8_5 = *(uint8_t*)args[48];
int8_t si8_5 = *(int8_t*)args[49];
*(BigStruct*)resp = test_large_fn(
ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
ui8_5, si8_5);
}
int
main(int argc __UNUSED__, const char** argv __UNUSED__)
{
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_cif cif;
ffi_type* argTypes[51];
void* argValues[51];
ffi_type ret_struct_type;
ffi_type* st_fields[51];
BigStruct retVal;
uint8_t ui8 = 1;
int8_t si8 = 2;
uint16_t ui16 = 3;
int16_t si16 = 4;
uint32_t ui32 = 5;
int32_t si32 = 6;
uint64_t ui64 = 7;
int64_t si64 = 8;
float f = 9;
double d = 10;
long double ld = 11;
char* p = (char*)0x12345678;
memset (&retVal, 0, sizeof(retVal));
ret_struct_type.size = 0;
ret_struct_type.alignment = 0;
ret_struct_type.type = FFI_TYPE_STRUCT;
ret_struct_type.elements = st_fields;
st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8;
st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8;
st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16;
st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16;
st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32;
st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32;
st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64;
st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64;
st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float;
st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double;
st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble;
st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer;
st_fields[50] = NULL;
argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8;
argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8;
argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8;
argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16;
argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16;
argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16;
argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16;
argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32;
argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32;
argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32;
argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32;
argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64;
argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64;
argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64;
argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64;
argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float;
argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f;
argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double;
argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d;
argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble;
argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld;
argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer;
argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p;
argTypes[50] = NULL;
argValues[50] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
/* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
retVal = ((BigStruct(*)(
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
uint8_t, int8_t))(code))(
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
ui8, si8);
/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
/* { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } */
return 0;
}

View file

@ -0,0 +1,69 @@
/* Area: ffi_call
Purpose: Check return value float, with many arguments
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run } */
#include "ffitest.h"
#include <float.h>
static float many(float f1,
float f2,
float f3,
float f4,
float f5,
float f6,
float f7,
float f8,
float f9,
float f10,
float f11,
float f12,
float f13)
{
#if 0
printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
(double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
(double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
(double) f11, (double) f12, (double) f13);
#endif
return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[13];
void *values[13];
float fa[13];
float f, ff;
int i;
for (i = 0; i < 13; i++)
{
args[i] = &ffi_type_float;
values[i] = &fa[i];
fa[i] = (float) i;
}
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
&ffi_type_float, args) == FFI_OK);
ffi_call(&cif, FFI_FN(many), &f, values);
ff = many(fa[0], fa[1],
fa[2], fa[3],
fa[4], fa[5],
fa[6], fa[7],
fa[8], fa[9],
fa[10],fa[11],fa[12]);
if (f - ff < FLT_EPSILON)
exit(0);
else
abort();
}

View file

@ -0,0 +1,57 @@
/* Area: ffi_call
Purpose: Check uint8_t arguments.
Limitations: none.
PR: PR45677.
Originator: Dan Witte <dwitte@gmail.com> 20100916 */
/* { dg-do run } */
#include "ffitest.h"
#define NARGS 7
typedef unsigned char u8;
#ifdef __GNUC__
__attribute__((noinline))
#endif
uint8_t
foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
uint8_t e, uint8_t f, uint8_t g)
{
return a + b + c + d + e + f + g;
}
uint8_t
bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d,
uint8_t e, uint8_t f, uint8_t g)
{
return foo (a, b, c, d, e, f, g);
}
int
main (void)
{
ffi_type *ffitypes[NARGS];
int i;
ffi_cif cif;
ffi_arg result = 0;
uint8_t args[NARGS];
void *argptrs[NARGS];
for (i = 0; i < NARGS; ++i)
ffitypes[i] = &ffi_type_uint8;
CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS,
&ffi_type_uint8, ffitypes) == FFI_OK);
for (i = 0; i < NARGS; ++i)
{
args[i] = i;
argptrs[i] = &args[i];
}
ffi_call (&cif, FFI_FN (bar), &result, argptrs);
CHECK (result == 21);
return 0;
}

View file

@ -0,0 +1,63 @@
/* Area: ffi_call
Purpose: Check stdcall many call on X86_WIN32 systems.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
#include <float.h>
static float __attribute__((fastcall)) fastcall_many(float f1,
float f2,
float f3,
float f4,
float f5,
float f6,
float f7,
float f8,
float f9,
float f10,
float f11,
float f12,
float f13)
{
return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[13];
void *values[13];
float fa[13];
float f, ff;
unsigned long ul;
for (ul = 0; ul < 13; ul++)
{
args[ul] = &ffi_type_float;
values[ul] = &fa[ul];
fa[ul] = (float) ul;
}
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 13,
&ffi_type_float, args) == FFI_OK);
ff = fastcall_many(fa[0], fa[1],
fa[2], fa[3],
fa[4], fa[5],
fa[6], fa[7],
fa[8], fa[9],
fa[10], fa[11], fa[12]);
ffi_call(&cif, FFI_FN(fastcall_many), &f, values);
if (f - ff < FLT_EPSILON)
printf("fastcall many arg tests ok!\n");
else
CHECK(0);
exit(0);
}

View file

@ -0,0 +1,63 @@
/* Area: ffi_call
Purpose: Check stdcall many call on X86_WIN32 systems.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
#include <float.h>
static float __attribute__((stdcall)) stdcall_many(float f1,
float f2,
float f3,
float f4,
float f5,
float f6,
float f7,
float f8,
float f9,
float f10,
float f11,
float f12,
float f13)
{
return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[13];
void *values[13];
float fa[13];
float f, ff;
unsigned long ul;
for (ul = 0; ul < 13; ul++)
{
args[ul] = &ffi_type_float;
values[ul] = &fa[ul];
fa[ul] = (float) ul;
}
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
&ffi_type_float, args) == FFI_OK);
ff = stdcall_many(fa[0], fa[1],
fa[2], fa[3],
fa[4], fa[5],
fa[6], fa[7],
fa[8], fa[9],
fa[10], fa[11], fa[12]);
ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
if (f - ff < FLT_EPSILON)
printf("stdcall many arg tests ok!\n");
else
CHECK(0);
exit(0);
}

View file

@ -0,0 +1,52 @@
/* Area: ffi_call
Purpose: Check that negative integers are passed correctly.
Limitations: none.
PR: none.
Originator: From the original ffitest.c */
/* { dg-do run } */
#include "ffitest.h"
static int checking(int a, short b, signed char c)
{
return (a < 0 && b < 0 && c < 0);
}
int main (void)
{
ffi_cif cif;
ffi_type *args[MAX_ARGS];
void *values[MAX_ARGS];
ffi_arg rint;
signed int si;
signed short ss;
signed char sc;
args[0] = &ffi_type_sint;
values[0] = &si;
args[1] = &ffi_type_sshort;
values[1] = &ss;
args[2] = &ffi_type_schar;
values[2] = &sc;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
&ffi_type_sint, args) == FFI_OK);
si = -6;
ss = -12;
sc = -1;
checking (si, ss, sc);
ffi_call(&cif, FFI_FN(checking), &rint, values);
printf ("%d vs %d\n", (int)rint, checking (si, ss, sc));
CHECK(rint != 0);
exit (0);
}

View file

@ -0,0 +1,152 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_16byte1 {
double a;
float b;
int c;
} cls_struct_16byte1;
typedef struct cls_struct_16byte2 {
int ii;
double dd;
float ff;
} cls_struct_16byte2;
typedef struct cls_struct_combined {
cls_struct_16byte1 d;
cls_struct_16byte2 e;
} cls_struct_combined;
cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
struct cls_struct_16byte2 b1,
struct cls_struct_combined b2)
{
struct cls_struct_combined result;
result.d.a = b0.a + b1.dd + b2.d.a;
result.d.b = b0.b + b1.ff + b2.d.b;
result.d.c = b0.c + b1.ii + b2.d.c;
result.e.ii = b0.c + b1.ii + b2.e.ii;
result.e.dd = b0.a + b1.dd + b2.e.dd;
result.e.ff = b0.b + b1.ff + b2.e.ff;
printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
b0.a, b0.b, b0.c,
b1.ii, b1.dd, b1.ff,
b2.d.a, b2.d.b, b2.d.c,
b2.e.ii, b2.e.dd, b2.e.ff,
result.d.a, result.d.b, result.d.c,
result.e.ii, result.e.dd, result.e.ff);
return result;
}
static void
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_16byte1 b0;
struct cls_struct_16byte2 b1;
struct cls_struct_combined b2;
b0 = *(struct cls_struct_16byte1*)(args[0]);
b1 = *(struct cls_struct_16byte2*)(args[1]);
b2 = *(struct cls_struct_combined*)(args[2]);
*(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type* cls_struct_fields1[5];
ffi_type* cls_struct_fields2[5];
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5];
struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
{3, 1.0, 8.0}};
struct cls_struct_combined res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
cls_struct_fields1[0] = &ffi_type_sint;
cls_struct_fields1[1] = &ffi_type_double;
cls_struct_fields1[2] = &ffi_type_float;
cls_struct_fields1[3] = NULL;
cls_struct_fields2[0] = &cls_struct_type;
cls_struct_fields2[1] = &cls_struct_type1;
cls_struct_fields2[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = &cls_struct_type2;
dbl_arg_types[3] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
/* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
cls_struct_16byte2,
cls_struct_combined))
(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
exit(0);
}

View file

@ -0,0 +1,161 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_16byte1 {
double a;
float b;
int c;
} cls_struct_16byte1;
typedef struct cls_struct_16byte2 {
int ii;
double dd;
float ff;
} cls_struct_16byte2;
typedef struct cls_struct_combined {
cls_struct_16byte1 d;
cls_struct_16byte2 e;
} cls_struct_combined;
cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
struct cls_struct_16byte2 b1,
struct cls_struct_combined b2,
struct cls_struct_16byte1 b3)
{
struct cls_struct_combined result;
result.d.a = b0.a + b1.dd + b2.d.a;
result.d.b = b0.b + b1.ff + b2.d.b;
result.d.c = b0.c + b1.ii + b2.d.c;
result.e.ii = b0.c + b1.ii + b2.e.ii;
result.e.dd = b0.a + b1.dd + b2.e.dd;
result.e.ff = b0.b + b1.ff + b2.e.ff;
printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
b0.a, b0.b, b0.c,
b1.ii, b1.dd, b1.ff,
b2.d.a, b2.d.b, b2.d.c,
b2.e.ii, b2.e.dd, b2.e.ff,
b3.a, b3.b, b3.c,
result.d.a, result.d.b, result.d.c,
result.e.ii, result.e.dd, result.e.ff);
return result;
}
static void
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_16byte1 b0;
struct cls_struct_16byte2 b1;
struct cls_struct_combined b2;
struct cls_struct_16byte1 b3;
b0 = *(struct cls_struct_16byte1*)(args[0]);
b1 = *(struct cls_struct_16byte2*)(args[1]);
b2 = *(struct cls_struct_combined*)(args[2]);
b3 = *(struct cls_struct_16byte1*)(args[3]);
*(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type* cls_struct_fields1[5];
ffi_type* cls_struct_fields2[5];
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5];
struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
{3, 1.0, 8.0}};
struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
struct cls_struct_combined res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
cls_struct_fields1[0] = &ffi_type_sint;
cls_struct_fields1[1] = &ffi_type_double;
cls_struct_fields1[2] = &ffi_type_float;
cls_struct_fields1[3] = NULL;
cls_struct_fields2[0] = &cls_struct_type;
cls_struct_fields2[1] = &cls_struct_type1;
cls_struct_fields2[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = &cls_struct_type2;
dbl_arg_types[3] = &cls_struct_type;
dbl_arg_types[4] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = &h_dbl;
args_dbl[4] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
/* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
cls_struct_16byte2,
cls_struct_combined,
cls_struct_16byte1))
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
/* CHECK( 1 == 0); */
exit(0);
}

View file

@ -0,0 +1,133 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20051010 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
unsigned long long a;
unsigned char b;
} A;
typedef struct B {
unsigned char y;
struct A x;
unsigned int z;
} B;
typedef struct C {
unsigned long long d;
unsigned char e;
} C;
static B B_fn(struct A b2, struct B b3, struct C b4)
{
struct B result;
result.x.a = b2.a + b3.x.a + b3.z + b4.d;
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
result.y = b2.b + b3.x.b + b4.e;
printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
(int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e,
(int)result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
struct C b2;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
b2 = *(struct C*)(args[2]);
*(B*)resp = B_fn(b0, b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[4];
ffi_type* cls_struct_fields2[3];
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
struct A e_dbl = { 1LL, 7};
struct B f_dbl = { 99, {12LL , 127}, 255};
struct C g_dbl = { 2LL, 9};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &ffi_type_uchar;
cls_struct_fields1[1] = &cls_struct_type;
cls_struct_fields1[2] = &ffi_type_uint;
cls_struct_fields1[3] = NULL;
cls_struct_fields2[0] = &ffi_type_uint64;
cls_struct_fields2[1] = &ffi_type_uchar;
cls_struct_fields2[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = &cls_struct_type2;
dbl_arg_types[3] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
exit(0);
}

View file

@ -0,0 +1,121 @@
/* Area: ffi_call, closure_call
Purpose: Check parameter passing with nested structs
of a single type. This tests the special cases
for homogenous floating-point aggregates in the
AArch64 PCS.
Limitations: none.
PR: none.
Originator: ARM Ltd. */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
float a_x;
float a_y;
} A;
typedef struct B {
float b_x;
float b_y;
} B;
typedef struct C {
A a;
B b;
} C;
static C C_fn (int x, int y, int z, C source, int i, int j, int k)
{
C result;
result.a.a_x = source.a.a_x;
result.a.a_y = source.a.a_y;
result.b.b_x = source.b.b_x;
result.b.b_y = source.b.b_y;
printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k);
printf ("%.1f, %.1f, %.1f, %.1f, "
"%.1f, %.1f, %.1f, %.1f\n",
source.a.a_x, source.a.a_y,
source.b.b_x, source.b.b_y,
result.a.a_x, result.a.a_y,
result.b.b_x, result.b.b_y);
return result;
}
int main (void)
{
ffi_cif cif;
ffi_type* struct_fields_source_a[3];
ffi_type* struct_fields_source_b[3];
ffi_type* struct_fields_source_c[3];
ffi_type* arg_types[8];
ffi_type struct_type_a, struct_type_b, struct_type_c;
struct A source_fld_a = {1.0, 2.0};
struct B source_fld_b = {4.0, 8.0};
int k = 1;
struct C result;
struct C source = {source_fld_a, source_fld_b};
struct_type_a.size = 0;
struct_type_a.alignment = 0;
struct_type_a.type = FFI_TYPE_STRUCT;
struct_type_a.elements = struct_fields_source_a;
struct_type_b.size = 0;
struct_type_b.alignment = 0;
struct_type_b.type = FFI_TYPE_STRUCT;
struct_type_b.elements = struct_fields_source_b;
struct_type_c.size = 0;
struct_type_c.alignment = 0;
struct_type_c.type = FFI_TYPE_STRUCT;
struct_type_c.elements = struct_fields_source_c;
struct_fields_source_a[0] = &ffi_type_float;
struct_fields_source_a[1] = &ffi_type_float;
struct_fields_source_a[2] = NULL;
struct_fields_source_b[0] = &ffi_type_float;
struct_fields_source_b[1] = &ffi_type_float;
struct_fields_source_b[2] = NULL;
struct_fields_source_c[0] = &struct_type_a;
struct_fields_source_c[1] = &struct_type_b;
struct_fields_source_c[2] = NULL;
arg_types[0] = &ffi_type_sint32;
arg_types[1] = &ffi_type_sint32;
arg_types[2] = &ffi_type_sint32;
arg_types[3] = &struct_type_c;
arg_types[4] = &ffi_type_sint32;
arg_types[5] = &ffi_type_sint32;
arg_types[6] = &ffi_type_sint32;
arg_types[7] = NULL;
void *args[7];
args[0] = &k;
args[1] = &k;
args[2] = &k;
args[3] = &source;
args[4] = &k;
args[5] = &k;
args[6] = &k;
CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c,
arg_types) == FFI_OK);
ffi_call (&cif, FFI_FN (C_fn), &result, args);
/* { dg-output "1, 1, 1, 1, 1, 1\n" } */
/* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */
CHECK (result.a.a_x == source.a.a_x);
CHECK (result.a.a_y == source.a.a_y);
CHECK (result.b.b_x == source.b.b_x);
CHECK (result.b.b_y == source.b.b_y);
exit (0);
}

View file

@ -0,0 +1,110 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030911 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
unsigned long a;
unsigned char b;
} A;
typedef struct B {
struct A x;
unsigned char y;
} B;
B B_fn(struct A b0, struct B b1)
{
struct B result;
result.x.a = b0.a + b1.x.a;
result.x.b = b0.b + b1.x.b + b1.y;
result.y = b0.b + b1.x.b;
printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
*(B*)resp = B_fn(b0, b1);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
struct A e_dbl = { 1, 7};
struct B f_dbl = {{12 , 127}, 99};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_fields[0] = &ffi_type_ulong;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &cls_struct_type;
cls_struct_fields1[1] = &ffi_type_uchar;
cls_struct_fields1[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
exit(0);
}

View file

@ -0,0 +1,111 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030911 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
unsigned long long a;
unsigned char b;
} A;
typedef struct B {
struct A x;
unsigned char y;
} B;
B B_fn(struct A b0, struct B b1)
{
struct B result;
result.x.a = b0.a + b1.x.a;
result.x.b = b0.b + b1.x.b + b1.y;
result.y = b0.b + b1.x.b;
printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
(int)b1.x.a, b1.x.b, b1.y,
(int)result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
*(B*)resp = B_fn(b0, b1);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
struct A e_dbl = { 1LL, 7};
struct B f_dbl = {{12LL , 127}, 99};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_fields[0] = &ffi_type_uint64;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &cls_struct_type;
cls_struct_fields1[1] = &ffi_type_uchar;
cls_struct_fields1[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
exit(0);
}

View file

@ -0,0 +1,111 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: PR 25630.
Originator: <andreast@gcc.gnu.org> 20051010 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
double a;
unsigned char b;
} A;
typedef struct B {
struct A x;
unsigned char y;
} B;
static B B_fn(struct A b2, struct B b3)
{
struct B result;
result.x.a = b2.a + b3.x.a;
result.x.b = b2.b + b3.x.b + b3.y;
result.y = b2.b + b3.x.b;
printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
(int)b3.x.a, b3.x.b, b3.y,
(int)result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
*(B*)resp = B_fn(b0, b1);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
struct A e_dbl = { 1.0, 7};
struct B f_dbl = {{12.0 , 127}, 99};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &cls_struct_type;
cls_struct_fields1[1] = &ffi_type_uchar;
cls_struct_fields1[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
exit(0);
}

View file

@ -0,0 +1,112 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20051010 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
long double a;
unsigned char b;
} A;
typedef struct B {
struct A x;
unsigned char y;
} B;
static B B_fn(struct A b2, struct B b3)
{
struct B result;
result.x.a = b2.a + b3.x.a;
result.x.b = b2.b + b3.x.b + b3.y;
result.y = b2.b + b3.x.b;
printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
(int)b3.x.a, b3.x.b, b3.y,
(int)result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
*(B*)resp = B_fn(b0, b1);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
struct A e_dbl = { 1.0, 7};
struct B f_dbl = {{12.0 , 127}, 99};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_fields[0] = &ffi_type_longdouble;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &cls_struct_type;
cls_struct_fields1[1] = &ffi_type_uchar;
cls_struct_fields1[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
exit(0);
}

View file

@ -0,0 +1,131 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Contains structs as parameter of the struct itself.
Sample taken from Alan Modras patch to src/prep_cif.c.
Limitations: none.
PR: PR 25630.
Originator: <andreast@gcc.gnu.org> 20051010 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct A {
double a;
unsigned char b;
} A;
typedef struct B {
struct A x;
unsigned char y;
} B;
typedef struct C {
long d;
unsigned char e;
} C;
static B B_fn(struct A b2, struct B b3, struct C b4)
{
struct B result;
result.x.a = b2.a + b3.x.a + b4.d;
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
result.y = b2.b + b3.x.b + b4.e;
printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
(int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
(int)result.x.a, result.x.b, result.y);
return result;
}
static void
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct A b0;
struct B b1;
struct C b2;
b0 = *(struct A*)(args[0]);
b1 = *(struct B*)(args[1]);
b2 = *(struct C*)(args[2]);
*(B*)resp = B_fn(b0, b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type* cls_struct_fields2[3];
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
struct A e_dbl = { 1.0, 7};
struct B f_dbl = {{12.0 , 127}, 99};
struct C g_dbl = { 2, 9};
struct B res_dbl;
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
cls_struct_fields1[0] = &cls_struct_type;
cls_struct_fields1[1] = &ffi_type_uchar;
cls_struct_fields1[2] = NULL;
cls_struct_fields2[0] = &ffi_type_slong;
cls_struct_fields2[1] = &ffi_type_uchar;
cls_struct_fields2[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = &cls_struct_type2;
dbl_arg_types[3] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = NULL;
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
/* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
exit(0);
}

Some files were not shown because too many files have changed in this diff Show more