1
#ifndef _avcall_convex_c /*-*- C -*-*/
2
#define _avcall_convex_c
4
Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
5
Copyright 1995-1999 Bruno Haible, <bruno@clisp.org>
7
This is free software distributed under the GNU General Public
8
Licence described in the file COPYING. Contact the author if
9
you don't have this or can't live with it. There is ABSOLUTELY
10
NO WARRANTY, explicit or implied, on this software.
12
/*----------------------------------------------------------------------
13
!!! THIS ROUTINE MUST BE COMPILED gcc -O !!!
15
Foreign function interface for a Convex C2 with gcc.
17
This calls a C function with an argument list built up using macros
20
Convex Argument Passing Conventions:
22
All arguments are passed on the stack with word alignment. Doubles take
23
two words. Structure args are passed as true structures embedded in the
24
argument stack. To return a structure, the -fpcc-struct-return convention
27
Compile this routine with gcc -O (or -O2 or -g -O) to get the right
28
register variables, or use the assembler version.
29
----------------------------------------------------------------------*/
30
#include "avcall.h.in"
32
#define RETURN(TYPE,VAL) (*(TYPE*)l->raddr = (TYPE)(VAL))
35
__builtin_avcall(av_alist* l)
37
register __avword* sp __asm__("sp"); /* C names for registers */
38
register long long llret __asm__("s0");
39
register float fret __asm__("s0");
40
register double dret __asm__("s0");
42
__avword space[__AV_ALIST_WORDS]; /* space for callee's stack frame */
43
__avword* argframe = sp; /* stack offset for argument list */
44
int arglen = l->aptr - l->args;
49
for (i = 0; i < arglen; i++) /* push function args onto stack */
50
argframe[i] = l->args[i];
53
i = (*l->func)(); /* call function */
55
/* save return value */
56
if (l->rtype == __AVvoid) {
58
if (l->rtype == __AVword) {
61
if (l->rtype == __AVchar) {
64
if (l->rtype == __AVschar) {
65
RETURN(signed char, i);
67
if (l->rtype == __AVuchar) {
68
RETURN(unsigned char, i);
70
if (l->rtype == __AVshort) {
73
if (l->rtype == __AVushort) {
74
RETURN(unsigned short, i);
76
if (l->rtype == __AVint) {
79
if (l->rtype == __AVuint) {
80
RETURN(unsigned int, i);
82
if (l->rtype == __AVlong) {
85
if (l->rtype == __AVulong) {
86
RETURN(unsigned long, i);
88
if (l->rtype == __AVlonglong) {
89
RETURN(long long, llret);
91
if (l->rtype == __AVulonglong) {
92
RETURN(unsigned long long, llret);
94
if (l->rtype == __AVfloat) {
97
if (l->rtype == __AVdouble) {
100
if (l->rtype == __AVvoidp) {
103
if (l->rtype == __AVstruct) {
104
if (l->flags & __AV_PCC_STRUCT_RETURN) {
105
/* pcc struct return convention: need a *(TYPE*)l->raddr = *(TYPE*)i; */
106
if (l->rsize == sizeof(char)) {
107
RETURN(char, *(char*)i);
109
if (l->rsize == sizeof(short)) {
110
RETURN(short, *(short*)i);
112
if (l->rsize == sizeof(int)) {
113
RETURN(int, *(int*)i);
115
if (l->rsize == sizeof(double)) {
116
((int*)l->raddr)[0] = ((int*)i)[0];
117
((int*)l->raddr)[1] = ((int*)i)[1];
119
int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
121
((__avword*)l->raddr)[n] = ((__avword*)i)[n];
124
/* normal struct return convention */
125
if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
126
if (l->rsize == sizeof(char)) {
129
if (l->rsize == sizeof(short)) {
132
if (l->rsize == sizeof(int)) {
135
if (l->rsize == 2*sizeof(__avword)) {
136
RETURN(long long, llret);
144
#endif /*_avcall_convex_c */