aarch64: Allow FFI_WIN64 for winelib (#593)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
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