Add moxie support. Release 3.0.12.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
eabi.S - Copyright (c) 2012 Anthony Green
|
||||
eabi.S - Copyright (c) 2012, 2013 Anthony Green
|
||||
|
||||
Moxie Assembly glue.
|
||||
|
||||
@@ -41,24 +41,61 @@
|
||||
# $r4 : ecif.rvalue
|
||||
# $r5 : fn
|
||||
|
||||
ffi_call_EABI:
|
||||
ffi_call_EABI:
|
||||
push $sp, $r6
|
||||
push $sp, $r7
|
||||
push $sp, $r8
|
||||
dec $sp, 24
|
||||
|
||||
/* Store incoming args on stack. */
|
||||
sto.l 0($sp), $r0
|
||||
sto.l 4($sp), $r1
|
||||
sto.l 8($sp), $r2
|
||||
sto.l 12($sp), $r3
|
||||
sto.l 16($sp), $r4
|
||||
sto.l 20($sp), $r5
|
||||
sto.l 0($sp), $r0 /* ffi_prep_args */
|
||||
sto.l 4($sp), $r1 /* ecif */
|
||||
sto.l 8($sp), $r2 /* bytes */
|
||||
sto.l 12($sp), $r3 /* flags */
|
||||
sto.l 16($sp), $r4 /* &rvalue */
|
||||
sto.l 20($sp), $r5 /* fn */
|
||||
|
||||
/* Call ffi_prep_args. */
|
||||
jsr $r0
|
||||
mov $r6, $r4 /* Save result buffer */
|
||||
mov $r7, $r5 /* Save the target fn */
|
||||
mov $r8, $r3 /* Save the flags */
|
||||
sub.l $sp, $r2 /* Allocate stack space */
|
||||
mov $r0, $sp /* We can stomp over $r0 */
|
||||
/* $r1 is already set up */
|
||||
jsra ffi_prep_args
|
||||
|
||||
/* Load register arguments. */
|
||||
ldo.l $r0, 0($sp)
|
||||
ldo.l $r1, 4($sp)
|
||||
ldo.l $r2, 8($sp)
|
||||
ldo.l $r3, 12($sp)
|
||||
ldo.l $r4, 16($sp)
|
||||
ldo.l $r5, 20($sp)
|
||||
|
||||
/* Call the target function. */
|
||||
jsr $r5
|
||||
jsr $r7
|
||||
|
||||
ldi.l $r7, 0xffffffff
|
||||
cmp $r8, $r7
|
||||
beq retstruct
|
||||
|
||||
ldi.l $r7, 4
|
||||
cmp $r8, $r7
|
||||
bgt ret2reg
|
||||
|
||||
st.l ($r6), $r0
|
||||
jmpa retdone
|
||||
|
||||
ret2reg:
|
||||
st.l ($r6), $r0
|
||||
sto.l 4($r6), $r1
|
||||
|
||||
retstruct:
|
||||
retdone:
|
||||
/* Return. */
|
||||
ldo.l $r6, -4($fp)
|
||||
ldo.l $r7, -8($fp)
|
||||
ldo.l $r8, -12($fp)
|
||||
ret
|
||||
.size ffi_call_EABI, .-ffi_call_EABI
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (C) 2012 Anthony Green
|
||||
ffi.c - Copyright (C) 2012, 2013 Anthony Green
|
||||
|
||||
Moxie Foreign Function Interface
|
||||
|
||||
@@ -43,6 +43,12 @@ void *ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
p_argv = ecif->avalue;
|
||||
argp = stack;
|
||||
|
||||
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*(void **) argp = ecif->rvalue;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0);
|
||||
i--, p_arg++)
|
||||
@@ -136,8 +142,7 @@ void ffi_call(ffi_cif *cif,
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_EABI:
|
||||
@@ -154,19 +159,25 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
|
||||
unsigned arg4, unsigned arg5, unsigned arg6)
|
||||
{
|
||||
/* This function is called by a trampoline. The trampoline stows a
|
||||
pointer to the ffi_closure object in gr7. We must save this
|
||||
pointer to the ffi_closure object in $r7. We must save this
|
||||
pointer in a place that will persist while we do our work. */
|
||||
register ffi_closure *creg __asm__ ("$r7");
|
||||
register ffi_closure *creg __asm__ ("$r12");
|
||||
ffi_closure *closure = creg;
|
||||
|
||||
/* Arguments that don't fit in registers are found on the stack
|
||||
at a fixed offset above the current frame pointer. */
|
||||
register char *frame_pointer __asm__ ("$fp");
|
||||
char *stack_args = frame_pointer + 16;
|
||||
|
||||
/* Pointer to a struct return value. */
|
||||
void *struct_rvalue = (void *) arg1;
|
||||
|
||||
/* 6 words reserved for register args + 3 words from jsr */
|
||||
char *stack_args = frame_pointer + 9*4;
|
||||
|
||||
/* Lay the register arguments down in a continuous chunk of memory. */
|
||||
unsigned register_args[6] =
|
||||
{ arg1, arg2, arg3, arg4, arg5, arg6 };
|
||||
char *register_args_ptr = (char *) register_args;
|
||||
|
||||
ffi_cif *cif = closure->cif;
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
@@ -174,6 +185,12 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
|
||||
char *ptr = (char *) register_args;
|
||||
int i;
|
||||
|
||||
/* preserve struct type return pointer passing */
|
||||
if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) {
|
||||
ptr += 4;
|
||||
register_args_ptr = (char *)®ister_args[1];
|
||||
}
|
||||
|
||||
/* Find the address of each argument. */
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
@@ -190,6 +207,7 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_POINTER:
|
||||
avalue[i] = ptr;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
@@ -205,30 +223,21 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
|
||||
|
||||
/* If we've handled more arguments than fit in registers,
|
||||
start looking at the those passed on the stack. */
|
||||
if (ptr == ((char *)register_args + (6*4)))
|
||||
if (ptr == ®ister_args[6])
|
||||
ptr = stack_args;
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
/* The caller allocates space for the return structure, and
|
||||
passes a pointer to this space in gr3. Use this value directly
|
||||
as the return value. */
|
||||
register void *return_struct_ptr __asm__("$r0");
|
||||
(closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
|
||||
(closure->fun) (cif, struct_rvalue, avalue, closure->user_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate space for the return value and call the function. */
|
||||
long long rvalue;
|
||||
(closure->fun) (cif, &rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Functions return 4-byte or smaller results in gr8. 8-byte
|
||||
values also use gr9. We fill the both, even for small return
|
||||
values, just to avoid a branch. */ /*
|
||||
asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue));
|
||||
asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1])); */
|
||||
asm ("mov $r12, %0\n ld.l $r0, ($r12)\n ldo.l $r1, 4($r12)" : : "r" (&rvalue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,18 +248,21 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
unsigned int *tramp = (unsigned int *) &closure->tramp[0];
|
||||
unsigned short *tramp = (unsigned short *) &closure->tramp[0];
|
||||
unsigned long fn = (long) ffi_closure_eabi;
|
||||
unsigned long cls = (long) codeloc;
|
||||
int i;
|
||||
|
||||
if (cif->abi != FFI_EABI)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
fn = (unsigned long) ffi_closure_eabi;
|
||||
|
||||
tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
|
||||
tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
|
||||
tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
|
||||
tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
|
||||
tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */
|
||||
tramp[0] = 0x01e0; /* ldi.l $r7, .... */
|
||||
tramp[1] = cls >> 16;
|
||||
tramp[2] = cls & 0xffff;
|
||||
tramp[3] = 0x1a00; /* jmpa .... */
|
||||
tramp[4] = fn >> 16;
|
||||
tramp[5] = fn & 0xffff;
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
ffitarget.h - Copyright (c) 2012, 2013 Anthony Green
|
||||
Target configuration macros for Moxie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -35,12 +35,8 @@ typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
#ifdef MOXIE
|
||||
FFI_EABI,
|
||||
FFI_DEFAULT_ABI = FFI_EABI,
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
@@ -50,7 +46,7 @@ typedef enum ffi_abi {
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
/* Trampolines are 5 4-byte instructions long. */
|
||||
#define FFI_TRAMPOLINE_SIZE (5*4)
|
||||
/* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */
|
||||
#define FFI_TRAMPOLINE_SIZE (12)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user