Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
29fe0479
Commit
29fe0479
authored
Dec 08, 2000
by
Richard Henderson
Committed by
Anthony Green
Dec 08, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libffi closures for Alpha
From-SVN: r38136
parent
859230d4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
295 additions
and
159 deletions
+295
-159
libffi/ChangeLog
+16
-0
libffi/include/ffi.h.in
+7
-1
libffi/src/alpha/ffi.c
+150
-100
libffi/src/alpha/osf.S
+122
-58
No files found.
libffi/ChangeLog
View file @
29fe0479
2000-12-07 Dec 8 11:23:29 2000 Richard Henderson <rth@redhat.com>
* src/raw_api.c (ffi_translate_args): Fix typo.
(ffi_prep_closure): Likewise.
* include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
FFI_TRAMPOLINE_SIZE.
* src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
cif->bytes for new ffi_call_osf implementation.
(ffi_prep_args): Absorb into ...
(ffi_call): ... here. Do all stack allocation here and
avoid a callback function.
(ffi_prep_closure, ffi_closure_osf_inner): New.
* src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
(ffi_closure_osf): New.
2000-09-10 Alexandre Oliva <aoliva@redhat.com>
* config.guess, config.sub, install-sh: Removed.
...
...
libffi/include/ffi.h.in
View file @
29fe0479
/* -----------------------------------------------------------------*-C-*-
libffi @VERSION@ - Copyright (c) 1996-1999 Cygnus Solutions
$Id: ffi.h.in,v 1.
4 2000/02/25 19:13:44 tromey
Exp $
$Id: ffi.h.in,v 1.
5 2000/04/17 02:15:31 green
Exp $
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
...
...
@@ -368,6 +368,12 @@ struct ffi_ia64_trampoline_struct {
};
#define FFI_NATIVE_RAW_API 0
#elif defined(ALPHA)
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
#define FFI_CLOSURES 0
...
...
libffi/src/alpha/ffi.c
View file @
29fe0479
...
...
@@ -30,170 +30,220 @@
#include <stdlib.h>
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
extern
void
ffi_call_osf
(
void
*
,
unsigned
long
,
unsigned
,
void
*
,
void
(
*
)());
extern
void
ffi_closure_osf
(
void
);
static
void
ffi_prep_args
(
char
*
stack
,
extended_cif
*
ecif
,
int
bytes
,
int
flags
)
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
)
{
register
long
i
,
avn
;
register
void
**
p_argv
;
register
char
*
argp
;
register
ffi_type
**
p_arg
;
/* To streamline things in the assembly code, we always allocate 12
words for loading up the int and fp argument registers. The layout
is as when processing varargs: the 6 fp args, the 6 int args, then
the incoming stack. ARGP points to the first int slot. */
argp
=
stack
+
6
*
SIZEOF_ARG
;
memset
(
stack
,
0
,
12
*
SIZEOF_ARG
);
if
(
ecif
->
cif
->
rtype
->
type
==
FFI_TYPE_STRUCT
)
/* Adjust cif->bytes to represent a minimum 6 words for the temporary
register argument loading area. */
if
(
cif
->
bytes
<
6
*
SIZEOF_ARG
)
cif
->
bytes
=
6
*
SIZEOF_ARG
;
/* Set the return type flag */
switch
(
cif
->
rtype
->
type
)
{
*
(
void
**
)
argp
=
ecif
->
rvalue
;
argp
+=
sizeof
(
void
*
);
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
cif
->
flags
=
cif
->
rtype
->
type
;
break
;
default:
cif
->
flags
=
FFI_TYPE_INT
;
break
;
}
return
FFI_OK
;
}
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(),
void
*
rvalue
,
void
**
avalue
)
{
unsigned
long
*
stack
,
*
argp
;
long
i
,
avn
;
ffi_type
**
arg_types
;
FFI_ASSERT
(
cif
->
abi
==
FFI_OSF
);
/* If the return value is a struct and we don't have a return
value address then we need to make one. */
if
(
rvalue
==
NULL
&&
cif
->
rtype
->
type
==
FFI_TYPE_STRUCT
)
rvalue
=
alloca
(
cif
->
rtype
->
size
);
/* Allocate the space for the arguments, plus 4 words of temp
space for ffi_call_osf. */
argp
=
stack
=
alloca
(
cif
->
bytes
+
4
*
SIZEOF_ARG
);
if
(
cif
->
flags
==
FFI_TYPE_STRUCT
)
*
(
void
**
)
argp
++
=
rvalue
;
i
=
0
;
avn
=
ecif
->
cif
->
nargs
;
p_arg
=
ecif
->
cif
->
arg_types
;
p_argv
=
ecif
->
avalue
;
avn
=
cif
->
nargs
;
arg_types
=
cif
->
arg_types
;
while
(
i
<
avn
)
{
size_t
z
=
ALIGN
((
*
p_arg
)
->
size
,
SIZEOF_ARG
);
switch
((
*
p_arg
)
->
type
)
switch
((
*
arg_types
)
->
type
)
{
case
FFI_TYPE_SINT8
:
*
(
SINT64
*
)
argp
=
*
(
SINT8
*
)(
*
p_argv
);
*
(
SINT64
*
)
argp
=
*
(
SINT8
*
)(
*
avalue
);
break
;
case
FFI_TYPE_UINT8
:
*
(
UINT64
*
)
argp
=
*
(
UINT8
*
)(
*
p_argv
);
*
(
SINT64
*
)
argp
=
*
(
UINT8
*
)(
*
avalue
);
break
;
case
FFI_TYPE_SINT16
:
*
(
SINT64
*
)
argp
=
*
(
SINT16
*
)(
*
p_argv
);
*
(
SINT64
*
)
argp
=
*
(
SINT16
*
)(
*
avalue
);
break
;
case
FFI_TYPE_UINT16
:
*
(
UINT64
*
)
argp
=
*
(
UINT16
*
)(
*
p_argv
);
*
(
SINT64
*
)
argp
=
*
(
UINT16
*
)(
*
avalue
);
break
;
case
FFI_TYPE_SINT32
:
*
(
SINT64
*
)
argp
=
*
(
SINT32
*
)(
*
p_argv
);
break
;
case
FFI_TYPE_UINT32
:
*
(
UINT64
*
)
argp
=
*
(
UINT32
*
)(
*
p_argv
);
/* Note that unsigned 32-bit quantities are sign extended. */
*
(
SINT64
*
)
argp
=
*
(
SINT32
*
)(
*
avalue
);
break
;
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_POINTER
:
*
(
UINT64
*
)
argp
=
*
(
UINT64
*
)(
*
p_argv
);
*
(
UINT64
*
)
argp
=
*
(
UINT64
*
)(
*
avalue
);
break
;
case
FFI_TYPE_FLOAT
:
if
(
argp
-
stack
<
12
*
SIZEOF_ARG
)
if
(
argp
-
stack
<
6
)
{
/* Note the conversion -- all the fp regs are loaded as
doubles. The in-register format is the same. */
*
(
double
*
)
(
argp
-
6
*
SIZEOF_ARG
)
=
*
(
float
*
)(
*
p_argv
);
*
(
double
*
)
argp
=
*
(
float
*
)(
*
avalue
);
}
else
*
(
float
*
)
argp
=
*
(
float
*
)(
*
p_argv
);
*
(
float
*
)
argp
=
*
(
float
*
)(
*
avalue
);
break
;
case
FFI_TYPE_DOUBLE
:
if
(
argp
-
stack
<
12
*
SIZEOF_ARG
)
*
(
double
*
)
(
argp
-
6
*
SIZEOF_ARG
)
=
*
(
double
*
)(
*
p_argv
);
else
*
(
double
*
)
argp
=
*
(
double
*
)(
*
p_argv
);
*
(
double
*
)
argp
=
*
(
double
*
)(
*
avalue
);
break
;
case
FFI_TYPE_STRUCT
:
memcpy
(
argp
,
*
p_argv
,
(
*
p_arg
)
->
size
);
memcpy
(
argp
,
*
avalue
,
(
*
arg_types
)
->
size
);
break
;
default:
FFI_ASSERT
(
0
);
}
argp
+=
z
;
i
++
,
p_arg
++
,
p_argv
++
;
argp
+=
ALIGN
((
*
arg_types
)
->
size
,
SIZEOF_ARG
)
/
SIZEOF_ARG
;
i
++
,
arg_types
++
,
avalue
++
;
}
ffi_call_osf
(
stack
,
cif
->
bytes
,
cif
->
flags
,
rvalue
,
fn
);
}
/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
)
ffi_prep_closure
(
ffi_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
{
/* Adjust cif->bytes. to include 12 words for the temporary register
argument loading area. This will be removed before the call. */
cif
->
bytes
+=
6
*
SIZEOF_ARG
;
if
(
cif
->
bytes
<
12
*
SIZEOF_ARG
)
cif
->
bytes
=
12
*
SIZEOF_ARG
;
/* The stack must be double word aligned, so round bytes up
appropriately. */
unsigned
int
*
tramp
;
cif
->
bytes
=
ALIGN
(
cif
->
bytes
,
2
*
sizeof
(
void
*
)
);
FFI_ASSERT
(
cif
->
abi
==
FFI_OSF
);
/* Set the return type flag */
switch
(
cif
->
rtype
->
type
)
{
case
FFI_TYPE_VOID
:
case
FFI_TYPE_STRUCT
:
cif
->
flags
=
cif
->
rtype
->
type
;
break
;
tramp
=
(
unsigned
int
*
)
&
closure
->
tramp
[
0
];
tramp
[
0
]
=
0x47fb0401
;
/* mov $27,$1 */
tramp
[
1
]
=
0xa77b0010
;
/* ldq $27,16($27) */
tramp
[
2
]
=
0x6bfb0000
;
/* jmp $31,($27),0 */
tramp
[
3
]
=
0x47ff041f
;
/* nop */
*
(
void
**
)
&
tramp
[
4
]
=
ffi_closure_osf
;
case
FFI_TYPE_FLOAT
:
cif
->
flags
=
FFI_TYPE_FLOAT
;
break
;
closure
->
cif
=
cif
;
closure
->
fun
=
fun
;
closure
->
user_data
=
user_data
;
case
FFI_TYPE_DOUBLE
:
cif
->
flags
=
FFI_TYPE_DOUBLE
;
break
;
/* Flush the Icache. */
asm
volatile
(
"imb"
:
:
:
"memory"
);
default:
cif
->
flags
=
FFI_TYPE_INT
;
break
;
}
return
FFI_OK
;
}
extern
int
ffi_call_osf
(
void
(
*
)(
char
*
,
extended_cif
*
,
int
,
int
),
extended_cif
*
,
unsigned
,
unsigned
,
unsigned
*
,
void
(
*
)());
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(),
void
*
rvalue
,
void
**
avalue
)
int
ffi_closure_osf_inner
(
ffi_closure
*
closure
,
void
*
rvalue
,
unsigned
long
*
argp
)
{
extended_cif
ecif
;
ffi_cif
*
cif
;
void
**
avalue
;
ffi_type
**
arg_types
;
long
i
,
avn
,
argn
;
ecif
.
cif
=
cif
;
ecif
.
avalue
=
avalue
;
/* If the return value is a struct and we don't have a return
value address then we need to make one. */
cif
=
closure
->
cif
;
avalue
=
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
argn
=
0
;
/* Copy the caller's structure return address to that the closure
returns the data directly to the caller. */
if
(
cif
->
flags
==
FFI_TYPE_STRUCT
)
{
rvalue
=
(
void
*
)
argp
[
0
];
argn
=
1
;
}
i
=
0
;
avn
=
cif
->
nargs
;
arg_types
=
cif
->
arg_types
;
if
(
rvalue
==
NULL
&&
cif
->
rtype
->
type
==
FFI_TYPE_STRUCT
)
ecif
.
rvalue
=
alloca
(
cif
->
rtype
->
size
);
else
ecif
.
rvalue
=
rvalue
;
switch
(
cif
->
abi
)
/* Grab the addresses of the arguments from the stack frame. */
while
(
i
<
avn
)
{
case
FFI_OSF
:
ffi_call_osf
(
ffi_prep_args
,
&
ecif
,
cif
->
bytes
,
cif
->
flags
,
rvalue
,
fn
);
break
;
switch
((
*
arg_types
)
->
type
)
{
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_POINTER
:
case
FFI_TYPE_STRUCT
:
*
avalue
=
&
argp
[
argn
];
break
;
default:
FFI_ASSERT
(
0
);
break
;
case
FFI_TYPE_FLOAT
:
if
(
argn
<
6
)
{
/* Floats coming from registers need conversion from double
back to float format. */
*
(
float
*
)
&
argp
[
argn
-
6
]
=
*
(
double
*
)
&
argp
[
argn
-
6
];
*
avalue
=
&
argp
[
argn
-
6
];
}
else
*
avalue
=
&
argp
[
argn
];
break
;
case
FFI_TYPE_DOUBLE
:
*
avalue
=
&
argp
[
argn
-
(
argn
<
6
?
6
:
0
)];
break
;
default:
FFI_ASSERT
(
0
);
}
argn
+=
ALIGN
((
*
arg_types
)
->
size
,
SIZEOF_ARG
)
/
SIZEOF_ARG
;
i
++
,
arg_types
++
,
avalue
++
;
}
/* Invoke the closure. */
(
closure
->
fun
)
(
cif
,
rvalue
,
avalue
,
closure
->
user_data
);
/* Tell ffi_closure_osf what register to put the return value in. */
return
cif
->
flags
;
}
libffi/src/alpha/osf.S
View file @
29fe0479
...
...
@@ -28,91 +28,155 @@
#define LIBFFI_ASM
#include <ffi.h>
#define callback $16
#define ecifp $17
#define bytes $18
#define flags $19
#define raddr $20
#define fn $21
.text
#define flags_ofs 16
#define raddr_ofs 24
#define fn_ofs 32
/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
void *raddr, void (*fnaddr)());
#define SIZEOF_FRAME (6*8)
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
deallocate some of the stack that has been alloca'd. */
.text
.align 4
.align 3
.globl ffi_call_osf
.ent ffi_call_osf
ffi_call_osf:
lda $30, -SIZEOF_FRAME($30)
stq $26, 0($30)
stq $15, 8($30)
stq flags, flags_ofs($30)
stq raddr, raddr_ofs($30)
stq fn, fn_ofs($30)
mov $30, $15
.frame $15, SIZEOF_FRAME, $26, 0
.mask 0x4008000, -SIZEOF_FRAME
.frame $15, 32, $26, 0
.mask 0x4008000, -32
addq $16,$17,$1
mov $16, $30
stq $26, 0($1)
stq $15, 8($1)
stq $18, 16($1)
mov $1, $15
.prologue 0
mov callback, $27 # mov callback into place
subq $30, bytes, $30 # allocate stack space
# Call ffi_prep_args; ecif, bytes and flags are already in place.
mov $30, $16 # push stack arg
jsr $26, ($27), 0
stq $19, 24($1)
mov $20, $27
# Load up all of the (potential) argument registers.
ldq $16, 0($30)
ldt $f16, 0($30)
ldt $f17, 8($30)
ldq $17, 8($30)
ldt $f18, 16($30)
ldq $18, 16($30)
ldt $f19, 24($30)
ldq $19, 24($30)
ldt $f20, 32($30)
ldq $20, 32($30)
ldt $f21, 40($30)
ldq $16, 48($30)
ldq $17, 56($30)
ldq $18, 64($30)
ldq $19, 72($30)
ldq $20, 80($30)
ldq $21, 88($30)
# Get rid of the arg reg temp space and call the function.
ldq $27, fn_ofs($15)
lda $30, 12*8($30)
ldq $21, 40($30)
# Deallocate the register argument area.
lda $30, 48($30)
jsr $26, ($27), 0
ldgp $29, 0($26)
# If the return value pointer is NULL, assume no return value.
ldq raddr, raddr_ofs($15)
beq raddr, $noretval
ldq $19, 24($15)
ldq $18, 16($15)
ldq $26, 0($15)
beq $19, $noretval
ldq flags, flags_ofs($15)
cmpeq
flags
, FFI_TYPE_INT, $1
# Store the return value out in the proper type.
cmpeq
$18
, FFI_TYPE_INT, $1
bne $1, $retint
cmpeq
flags
, FFI_TYPE_FLOAT, $2
cmpeq
$18
, FFI_TYPE_FLOAT, $2
bne $2, $retfloat
cmpeq
flags
, FFI_TYPE_DOUBLE, $3
cmpeq
$18
, FFI_TYPE_DOUBLE, $3
bne $3, $retdouble
br $retstruct
.align 3
$noretval:
ldq $15, 8($15)
ret
$retint:
stq $0, 0(raddr)
br $noretval
stq $0, 0($19)
nop
ldq $15, 8($15)
ret
$retfloat:
sts $f0, 0(
raddr
)
br $noretval
$retdouble:
stt $f0, 0(raddr)
sts $f0, 0(
$19
)
nop
ldq $15, 8($15)
ret
$retstruct:
$noretval:
mov $15, $30
ldq $26, 0($15)
$retdouble:
stt $f0, 0($19)
nop
ldq $15, 8($15)
lda $30, SIZEOF_FRAME($30)
ret
.end ffi_call_osf
/* ffi_closure_osf(...)
Receives the closure argument in $1. */
.align 3
.globl ffi_closure_osf
.ent ffi_closure_osf
ffi_closure_osf:
.frame $30, 16*8, $26, 0
.mask 0x4000000, -14*8
ldgp $29, 0($27)
subq $30, 14*8, $30
stq $26, 0($30)
.prologue 1
# Store all of the potential argument registers in va_list format.
stt $f16, 4*8($30)
stt $f17, 5*8($30)
stt $f18, 6*8($30)
stt $f19, 7*8($30)
stt $f20, 8*8($30)
stt $f21, 9*8($30)
stq $16, 10*8($30)
stq $17, 11*8($30)
stq $18, 12*8($30)
stq $19, 13*8($30)
stq $20, 14*8($30)
stq $21, 15*8($30)
# Call ffi_closure_osf_inner to do the bulk of the work.
mov $1, $16
lda $17, 2*8($30)
lda $18, 10*8($30)
jsr $26, ffi_closure_osf_inner
ldgp $29, 0($26)
ldq $26, 0($30)
# Load up the return value in the proper type.
cmpeq $0, FFI_TYPE_INT, $1
bne $1, $loadint
cmpeq $0, FFI_TYPE_FLOAT, $2
bne $2, $loadfloat
cmpeq $18, FFI_TYPE_DOUBLE, $3
bne $3, $loaddouble
addq $30, 16*8, $30
ret
.align 3
$loadint:
ldq $0, 16($30)
nop
addq $30, 16*8, $30
ret
$loadfloat:
lds $f0, 16($30)
nop
addq $30, 16*8, $30
ret
$loaddouble:
ldt $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.end ffi_closure_osf
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment