8000 Various MIPS Fixes (#425) · python/cpython-source-deps@159b94e · GitHub
[go: up one dir, main page]

Skip to content

Commit 159b94e

Browse files
jcowgillatgreen
authored andcommitted
Various MIPS Fixes (#425)
* mips: simplify closure #defines This commit should have no visible effect. * mips: add special handling of variadic functions MIPS requires special handling of variadic functions which pass floating point arguments: * In the o32 ABI, all float arguments are passed in integer registers. * In the n32/n64 ABIs, float arguments after the ellipsis are passed in integer registers. Implement this in libffi. To support this in n32/n64 closures, we need to add a new mips_nfixedargs field to ffi_cif which will break the libffi ABI. This fixes the libffi.call/cls_longdouble_va.c test which was failing on 64-bit MIPS. * mips: align argn for all 64-bit types in o32 closure handler Ensure that argn is pre-aligned for all 64-bit argument types (including doubles) and not just integer types. This fixes closures of the form "f(float, double, <some integer args>)". Previously the first integer argument would be read from a2 which is garbage at this point (the float arguments have already "consumed" a0-a3). After this commit, argn is correctly padded between the "float" and "double" arguments so that the first integer argument is read from the stack. Fixes "double f(float,double,int)" test in #371 * mips: do not read from floating point register if returning a struct In the o32 ABI, the pointer passed in a0 used to return structures indirectly is treated as the first argument for argument allocation purposes. This means that it should inhibit floating point registers the same way that other integer arguments do. Fixes "Double f(float,Double,double)" test in #371 * mips: fix pointer cast warnings Fix two pointer cast warnings when compiled on 64-bit mips by casting through uintptr_t. Fixes mips64el part of #404
1 parent f2afda0 commit 159b94e

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed

src/mips/ffi.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <ffi.h>
3030
#include <ffi_common.h>
3131

32+
#include <stdint.h>
3233
#include <stdlib.h>
3334

3435
#ifdef __GNUC__
@@ -322,9 +323,10 @@ calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
322323
#endif
323324

324325
/* Perform machine dependent cif processing */
325-
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
326+
static ffi_status ffi_prep_cif_machdep_int(ffi_cif *cif, unsigned nfixedargs)
326327
{
327328
cif->flags = 0;
329+
cif->mips_nfixedargs = nfixedargs;
328330

329331
#ifdef FFI_MIPS_O32
330332
/* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
@@ -333,7 +335,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
333335

334336
if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
335337
{
336-
if (cif->nargs > 0)
338+
if (cif->nargs > 0 && cif->nargs == nfixedargs)
337339
{
338340
switch ((cif->arg_types)[0]->type)
339341
{
@@ -450,7 +452,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
450452
while (count-- > 0 && arg_reg < 8)
451453
{
452454
type = (cif->arg_types)[index]->type;
453-
if (soft_float)
455+
456+
// Pass variadic arguments in integer registers even if they're floats
457+
if (soft_float || index >= nfixedargs)
454458
{
455459
switch (type)
456460
{
@@ -476,7 +480,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
476480
/* Align it. */
477481
arg_reg = FFI_ALIGN(arg_reg, 2);
478482
/* Treat it as two adjacent doubles. */
479-
if (soft_float)
483+
if (soft_float || index >= nfixedargs)
480484
{
481485
arg_reg += 2;
482486
}
@@ -493,7 +497,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
493497

494498
case FFI_TYPE_STRUCT:
495499
loc = arg_reg * FFI_SIZEOF_ARG;
496-
cif->flags += calc_n32_struct_flags(soft_float,
500+
cif->flags += calc_n32_struct_flags(soft_float || index >= nfixedargs,
497501
(cif->arg_types)[index],
498502
&loc, &arg_reg);
499503
break;
@@ -578,6 +582,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
578582
return FFI_OK;
579583
}
580584

585+
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
586+
{
587+
return ffi_prep_cif_machdep_int(cif, cif->nargs);
588+
}
589+
590+
ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
591+
unsigned nfixedargs,
592+
unsigned ntotalargs MAYBE_UNUSED)
593+
{
594+
return ffi_prep_cif_machdep_int(cif, nfixedargs);
595+
}
596+
581597
/* Low level routine for calling O32 functions */
582598
extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
583599
extended_cif *, unsigned,
@@ -801,13 +817,14 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
801817
avalue = alloca (cif->nargs * sizeof (ffi_arg));
802818
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
803819

804-
seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
820+
seen_int = (cif->abi == FFI_O32_SOFT_FLOAT) || (cif->mips_nfixedargs != cif->nargs);
805821
argn = 0;
806822

807823
if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
808824
{
809-
rvalue = (void *)(UINT32)ar[0];
825+
rvalue = (void *)(uintptr_t)ar[0];
810826
argn = 1;
827+
seen_int = 1;
811828
}
812829

813830
i = 0;
@@ -816,6 +833,8 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
816833

817834
while (i < avn)
818835
{
836+
if (arg_types[i]->alignment == 8 && (argn & 0x1))
837+
argn++;
819838
if (i < 2 && !seen_int &&
820839
(arg_types[i]->type == FFI_TYPE_FLOAT ||
821840
arg_types[i]->type == FFI_TYPE_DOUBLE ||
@@ -830,8 +849,6 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
830849
}
831850
else
832851
{
833-
if (arg_types[i]->alignment == 8 && (argn & 0x1))
834-
argn++;
835852
switch (arg_types[i]->type)
836853
{
837854
case FFI_TYPE_SINT8:
@@ -981,8 +998,8 @@ ffi_closure_mips_inner_N32 (ffi_cif *cif,
981998
|| arg_types[i]->type == FFI_TYPE_DOUBLE
982999
|| arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
9831000
{
984-
argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
985-
if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
1001+
argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;
1002+
if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1)))
9861003
{
9871004
argp=(ffi_arg*)FFI_ALIGN(argp,arg_types[i]->alignment);
9881005
argn++;
@@ -1050,7 +1067,7 @@ ffi_closure_mips_inner_N32 (ffi_cif *cif,
10501067
it was passed in registers. */
10511068
avaluep[i] = alloca(arg_types[i]->size);
10521069
copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1053-
argn, 0, ar, fpr, soft_float);
1070+
argn, 0, ar, fpr, i >= cif->mips_nfixedargs || soft_float);
10541071

10551072
break;
10561073
}

src/mips/ffitarget.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -224,26 +224,21 @@ typedef enum ffi_abi {
224224
#endif
225225
} ffi_abi;
226226

227-
#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
227+
#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag; unsigned mips_nfixedargs
228+
#define FFI_TARGET_SPECIFIC_VARIADIC
228229
#endif /* !LIBFFI_ASM */
229230

230231
/* ---- Definitions for closures ----------------------------------------- */
231232

232-
#if defined(FFI_MIPS_O32)
233233
#define FFI_CLOSURES 1
234234
#define FFI_GO_CLOSURES 1
235-
#define FFI_TRAMPOLINE_SIZE 20
236-
#else
237-
/* N32/N64. */
238-
# define FFI_CLOSURES 1
239-
#define FFI_GO_CLOSURES 1
240-
#if _MIPS_SIM==_ABI64
241-
#define FFI_TRAMPOLINE_SIZE 56
235+
#define FFI_NATIVE_RAW_API 0
236+
237+
#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
238+
# define FFI_TRAMPOLINE_SIZE 20
242239
#else
243-
#define FFI_TRAMPOLINE_SIZE 20
240+
# define FFI_TRAMPOLINE_SIZE 56
244241
#endif
245-
#endif /* FFI_MIPS_O32 */
246-
#define FFI_NATIVE_RAW_API 0
247242

248243
#endif
249244

0 commit comments

Comments
 (0)
0