summaryrefslogtreecommitdiff
path: root/src/aarch64
diff options
context:
space:
mode:
authorAndreRH <andre.hentschel@ok.de>2020-11-10 12:27:59 +0100
committerGitHub <noreply@github.com>2020-11-10 06:27:59 -0500
commit56f7df711f70414d4f3663b34e54b122b38bab88 (patch)
treeeb5e80eca84aa55a375883100f4d37a1d6244d85 /src/aarch64
parent8111cd06921e80d5d7192ce8d1f64733072fdbcd (diff)
downloadlibffi-56f7df711f70414d4f3663b34e54b122b38bab88.tar.gz
aarch64: Allow FFI_WIN64 for winelib (#593)
Diffstat (limited to 'src/aarch64')
-rw-r--r--src/aarch64/ffi.c70
-rw-r--r--src/aarch64/ffitarget.h7
-rw-r--r--src/aarch64/internal.h1
3 files changed, 47 insertions, 31 deletions
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
index 508a624..ef09f4d 100644
--- a/src/aarch64/ffi.c
+++ b/src/aarch64/ffi.c
@@ -564,6 +564,14 @@ ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
cif->aarch64_nfixedargs = nfixedargs;
return status;
}
+#else
+ffi_status FFI_HIDDEN
+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs)
+{
+ ffi_status status = ffi_prep_cif_machdep (cif);
+ cif->flags |= AARCH64_FLAG_VARARG;
+ return status;
+}
#endif /* __APPLE__ */
extern void ffi_call_SYSV (struct call_context *context, void *frame,
@@ -580,7 +588,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
void *stack, *frame, *rvalue;
struct arg_state state;
size_t stack_bytes, rtype_size, rsize;
- int i, nargs, flags;
+ int i, nargs, flags, isvariadic = 0;
ffi_type *rtype;
flags = cif->flags;
@@ -588,6 +596,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
rtype_size = rtype->size;
stack_bytes = cif->bytes;
+ if (flags & AARCH64_FLAG_VARARG)
+ {
+ isvariadic = 1;
+ flags &= ~AARCH64_FLAG_VARARG;
+ }
+
/* If the target function returns a structure via hidden pointer,
then we cannot allow a null rvalue. Otherwise, mash a null
rvalue to void return type. */
@@ -667,35 +681,31 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
h = is_vfp_type (ty);
if (h)
{
- int elems = 4 - (h & 3);
-#ifdef _WIN32 /* for handling armasm calling convention */
- if (cif->is_variadic)
- {
- if (state.ngrn + elems <= N_X_ARG_REG)
- {
- dest = &context->x[state.ngrn];
- state.ngrn += elems;
- extend_hfa_type(dest, a, h);
- break;
- }
- state.nsrn = N_X_ARG_REG;
- dest = allocate_to_stack(&state, stack, ty->alignment, s);
- }
- else
- {
-#endif /* for handling armasm calling convention */
- if (state.nsrn + elems <= N_V_ARG_REG)
- {
- dest = &context->v[state.nsrn];
- state.nsrn += elems;
- extend_hfa_type (dest, a, h);
- break;
- }
- state.nsrn = N_V_ARG_REG;
- dest = allocate_to_stack (&state, stack, ty->alignment, s);
-#ifdef _WIN32 /* for handling armasm calling convention */
- }
-#endif /* for handling armasm calling convention */
+ int elems = 4 - (h & 3);
+ if (cif->abi == FFI_WIN64 && isvariadic)
+ {
+ if (state.ngrn + elems <= N_X_ARG_REG)
+ {
+ dest = &context->x[state.ngrn];
+ state.ngrn += elems;
+ extend_hfa_type(dest, a, h);
+ break;
+ }
+ state.nsrn = N_X_ARG_REG;
+ dest = allocate_to_stack(&state, stack, ty->alignment, s);
+ }
+ else
+ {
+ if (state.nsrn + elems <= N_V_ARG_REG)
+ {
+ dest = &context->v[state.nsrn];
+ state.nsrn += elems;
+ extend_hfa_type (dest, a, h);
+ break;
+ }
+ state.nsrn = N_V_ARG_REG;
+ dest = allocate_to_stack (&state, stack, ty->alignment, s);
+ }
}
else if (s > 16)
{
diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h
index 7a8cabe..d5622e1 100644
--- a/src/aarch64/ffitarget.h
+++ b/src/aarch64/ffitarget.h
@@ -45,8 +45,13 @@ typedef enum ffi_abi
{
FFI_FIRST_ABI = 0,
FFI_SYSV,
+ FFI_WIN64,
FFI_LAST_ABI,
+#if defined(_WIN32)
+ FFI_DEFAULT_ABI = FFI_WIN64
+#else
FFI_DEFAULT_ABI = FFI_SYSV
+#endif
} ffi_abi;
#endif
@@ -72,11 +77,11 @@ typedef enum ffi_abi
#ifdef _WIN32
#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
#endif
+#define FFI_TARGET_SPECIFIC_VARIADIC
/* ---- Internal ---- */
#if defined (__APPLE__)
-#define FFI_TARGET_SPECIFIC_VARIADIC
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
#elif !defined(_WIN32)
/* iOS and Windows reserve x18 for the system. Disable Go closures until
diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h
index 9c3e077..3d4d035 100644
--- a/src/aarch64/internal.h
+++ b/src/aarch64/internal.h
@@ -61,6 +61,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define AARCH64_FLAG_ARG_V_BIT 7
#define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT)
+#define AARCH64_FLAG_VARARG (1 << 8)
#define N_X_ARG_REG 8
#define N_V_ARG_REG 8