mirror of
https://github.com/partic2/libffi
synced 2026-11-11 02:27:19 +00:00
Move closure tests so we can easily XFAIL them for some targets
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2019 Anthony Green
|
||||
|
||||
# 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 $compiler_vendor "microsoft"] } {
|
||||
# -wd4005 macro redefinition
|
||||
# -wd4244 implicit conversion to type of smaller size
|
||||
# -wd4305 truncation to smaller type
|
||||
# -wd4477 printf %lu of uintptr_t
|
||||
# -wd4312 implicit conversion to type of greater size
|
||||
# -wd4311 pointer truncation to unsigned long
|
||||
# -EHsc C++ Exception Handling (no SEH exceptions)
|
||||
set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
|
||||
} else {
|
||||
set additional_options "";
|
||||
}
|
||||
|
||||
set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]]
|
||||
|
||||
if { [libffi_feature_test "#if FFI_CLOSURES"] } {
|
||||
run-many-tests $tlist ""
|
||||
} else {
|
||||
foreach test $tlist {
|
||||
unsupported "$test"
|
||||
}
|
||||
}
|
||||
|
||||
dg-finish
|
||||
|
||||
# Local Variables:
|
||||
# tcl-indent-level:4
|
||||
# End:
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Area: closure_call
|
||||
Purpose: Check simple closure handling with all ABIs
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <twalljava@dev.java.net> */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void
|
||||
closure_test(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 (ABI_ATTR *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;
|
||||
|
||||
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, ABI_NUM, 4,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test,
|
||||
(void *) 3 /* userdata */, code) == FFI_OK);
|
||||
|
||||
res = (*(closure_test_type0)code)(0, 1, 2, 3);
|
||||
/* { dg-output "0 1 2 3: 9" } */
|
||||
|
||||
printf("res: %d\n",res);
|
||||
/* { dg-output "\nres: 9" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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: <compnerd@compnerd.org> 20171026 */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_3float {
|
||||
float f;
|
||||
float g;
|
||||
float h;
|
||||
} cls_struct_3float;
|
||||
|
||||
cls_struct_3float cls_struct_3float_fn(struct cls_struct_3float a1,
|
||||
struct cls_struct_3float a2)
|
||||
{
|
||||
struct cls_struct_3float result;
|
||||
|
||||
result.f = a1.f + a2.f;
|
||||
result.g = a1.g + a2.g;
|
||||
result.h = a1.h + a2.h;
|
||||
|
||||
printf("%g %g %g %g %g %g: %g %g %g\n", a1.f, a1.g, a1.h,
|
||||
a2.f, a2.g, a2.h, result.f, result.g, result.h);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_3float_gn(ffi_cif *cif __UNUSED__, void* resp, void **args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_3float a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_3float*)(args[0]);
|
||||
a2 = *(struct cls_struct_3float*)(args[1]);
|
||||
|
||||
*(cls_struct_3float*)resp = cls_struct_3float_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_3float g_dbl = { 1.0f, 2.0f, 3.0f };
|
||||
struct cls_struct_3float f_dbl = { 1.0f, 2.0f, 3.0f };
|
||||
struct cls_struct_3float res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_float;
|
||||
cls_struct_fields[1] = &ffi_type_float;
|
||||
cls_struct_fields[2] = &ffi_type_float;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
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_3float_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 3 1 2 3: 2 4 6" } */
|
||||
printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
|
||||
/* { dg-output "\nres: 2 4 6" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3float_gn, NULL, code) ==
|
||||
FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_3float(*)(cls_struct_3float,
|
||||
cls_struct_3float))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
|
||||
printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
|
||||
/* { dg-output "\nres: 2 4 6" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of long double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of long double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/18/2007
|
||||
*/
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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" } */
|
||||
|
||||
closure_test_fn(arg);
|
||||
/* { dg-output "\n1.0 2.0" } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* 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" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL,
|
||||
code) == FFI_OK);
|
||||
|
||||
res = ((int(*)(char*, ...))(code))(format, doubleArg);
|
||||
/* { dg-output "\n7.0" } */
|
||||
printf("res: %d\n", (int) res);
|
||||
/* { dg-output "\nres: 4" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check long double arguments.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin */
|
||||
|
||||
/* 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* } } */
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* 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" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL,
|
||||
code) == FFI_OK);
|
||||
|
||||
res = ((int(*)(char*, ...))(code))(format, ldArg);
|
||||
/* { dg-output "\n7.0" } */
|
||||
printf("res: %d\n", (int) res);
|
||||
/* { dg-output "\nres: 4" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/* Area: closure_call
|
||||
Purpose: Check closures called with many args of mixed types
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <david.schneider@picle.org> */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#define NARGS 16
|
||||
|
||||
static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
int i;
|
||||
double r = 0;
|
||||
double t;
|
||||
for(i = 0; i < NARGS; i++)
|
||||
{
|
||||
if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
|
||||
{
|
||||
t = *(long int *)args[i];
|
||||
CHECK(t == i+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = *(double *)args[i];
|
||||
CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON);
|
||||
}
|
||||
r += t;
|
||||
}
|
||||
*(double *)resp = r;
|
||||
}
|
||||
typedef double (*cls_ret_double)(double, double, double, double, long int,
|
||||
double, double, double, double, long int, double, long int, double, long int,
|
||||
double, 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[NARGS];
|
||||
double res;
|
||||
int i;
|
||||
double expected = 64.9;
|
||||
|
||||
for(i = 0; i < NARGS; i++)
|
||||
{
|
||||
if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
|
||||
cl_arg_types[i] = &ffi_type_slong;
|
||||
else
|
||||
cl_arg_types[i] = &ffi_type_double;
|
||||
}
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS,
|
||||
&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))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
|
||||
1.1, 12, 1.3, 14, 1.5, 16);
|
||||
if (fabs(res - expected) < FLT_EPSILON)
|
||||
exit(0);
|
||||
else
|
||||
abort();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Area: closure_call
|
||||
Purpose: Check register allocation for closure calls with many float and double arguments
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <david.schneider@picle.org> */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#define NARGS 16
|
||||
|
||||
static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
double r = 0;
|
||||
unsigned int i;
|
||||
double t;
|
||||
for(i=0; i < cif->nargs; i++)
|
||||
{
|
||||
if(cif->arg_types[i] == &ffi_type_double) {
|
||||
t = *(((double**)(args))[i]);
|
||||
} else {
|
||||
t = *(((float**)(args))[i]);
|
||||
}
|
||||
r += t;
|
||||
}
|
||||
*((double*)ret) = r;
|
||||
}
|
||||
typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float);
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_closure *closure;
|
||||
void* code;
|
||||
ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double,
|
||||
&ffi_type_double, &ffi_type_double, &ffi_type_double,
|
||||
&ffi_type_double, &ffi_type_float, &ffi_type_float,
|
||||
&ffi_type_double, &ffi_type_float, &ffi_type_float};
|
||||
|
||||
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code);
|
||||
if(closure ==NULL)
|
||||
abort();
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK);
|
||||
CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK);
|
||||
double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2);
|
||||
ffi_closure_free(closure);
|
||||
if(fabs(ret - 7.8) < FLT_EPSILON)
|
||||
exit(0);
|
||||
else
|
||||
abort();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
* (ffi_arg*) 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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__)
|
||||
{
|
||||
*(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_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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#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) (void)(!(x) ? (abort(), 1) : 0)
|
||||
|
||||
/* Define macros so that compilers other than gcc can run the tests. */
|
||||
#undef __UNUSED__
|
||||
#if defined(__GNUC__)
|
||||
#define __UNUSED__ __attribute__((__unused__))
|
||||
#define __STDCALL__ __attribute__((stdcall))
|
||||
#define __THISCALL__ __attribute__((thiscall))
|
||||
#define __FASTCALL__ __attribute__((fastcall))
|
||||
#define __MSABI__ __attribute__((ms_abi))
|
||||
#else
|
||||
#define __UNUSED__
|
||||
#define __STDCALL__ __stdcall
|
||||
#define __THISCALL__ __thiscall
|
||||
#define __FASTCALL__ __fastcall
|
||||
#endif
|
||||
|
||||
#ifndef ABI_NUM
|
||||
#define ABI_NUM FFI_DEFAULT_ABI
|
||||
#define ABI_ATTR
|
||||
#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. */
|
||||
#if defined(_WIN64) | defined(_WIN32)
|
||||
#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
|
||||
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
|
||||
#define PRIuPTR "lu"
|
||||
#define PRIu8 "u"
|
||||
#define PRId8 "d"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRId64 "I64d"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIuPTR
|
||||
#define PRIuPTR "u"
|
||||
#endif
|
||||
Reference in New Issue
Block a user