Commit 56f7df711f70414d4f3663b34e54b122b38bab88

AndreRH 2020-11-10T12:27:59

aarch64: Allow FFI_WIN64 for winelib (#593)

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