~ubuntu-branches/debian/squeeze/ffcall/squeeze

« back to all changes in this revision

Viewing changes to avcall/avcall-convex.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2010-06-26 15:29:30 UTC
  • mfrom: (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100626152930-c09y01gk3szcnykn
Tags: 1.10+cvs20100619-2
Ship to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _avcall_convex_c                                /*-*- C -*-*/
 
2
#define _avcall_convex_c
 
3
/**
 
4
  Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
 
5
  Copyright 1995-1999 Bruno Haible, <bruno@clisp.org>
 
6
 
 
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.
 
11
**/
 
12
/*----------------------------------------------------------------------
 
13
  !!! THIS ROUTINE MUST BE COMPILED gcc -O !!!
 
14
 
 
15
  Foreign function interface for a Convex C2 with gcc.
 
16
 
 
17
  This calls a C function with an argument list built up using macros
 
18
  defined in av_call.h.
 
19
 
 
20
  Convex Argument Passing Conventions:
 
21
 
 
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
 
25
  is used.
 
26
 
 
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"
 
31
 
 
32
#define RETURN(TYPE,VAL)        (*(TYPE*)l->raddr = (TYPE)(VAL))
 
33
 
 
34
int
 
35
__builtin_avcall(av_alist* l)
 
36
{
 
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");
 
41
 
 
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;
 
45
  __avword i;
 
46
 
 
47
  {
 
48
    int i;
 
49
    for (i = 0; i < arglen; i++)        /* push function args onto stack */
 
50
      argframe[i] = l->args[i];
 
51
  }
 
52
 
 
53
  i = (*l->func)();                     /* call function */
 
54
 
 
55
  /* save return value */
 
56
  if (l->rtype == __AVvoid) {
 
57
  } else
 
58
  if (l->rtype == __AVword) {
 
59
    RETURN(__avword, i);
 
60
  } else
 
61
  if (l->rtype == __AVchar) {
 
62
    RETURN(char, i);
 
63
  } else
 
64
  if (l->rtype == __AVschar) {
 
65
    RETURN(signed char, i);
 
66
  } else
 
67
  if (l->rtype == __AVuchar) {
 
68
    RETURN(unsigned char, i);
 
69
  } else
 
70
  if (l->rtype == __AVshort) {
 
71
    RETURN(short, i);
 
72
  } else
 
73
  if (l->rtype == __AVushort) {
 
74
    RETURN(unsigned short, i);
 
75
  } else
 
76
  if (l->rtype == __AVint) {
 
77
    RETURN(int, i);
 
78
  } else
 
79
  if (l->rtype == __AVuint) {
 
80
    RETURN(unsigned int, i);
 
81
  } else
 
82
  if (l->rtype == __AVlong) {
 
83
    RETURN(long, i);
 
84
  } else
 
85
  if (l->rtype == __AVulong) {
 
86
    RETURN(unsigned long, i);
 
87
  } else
 
88
  if (l->rtype == __AVlonglong) {
 
89
    RETURN(long long, llret);
 
90
  } else
 
91
  if (l->rtype == __AVulonglong) {
 
92
    RETURN(unsigned long long, llret);
 
93
  } else
 
94
  if (l->rtype == __AVfloat) {
 
95
    RETURN(float, fret);
 
96
  } else
 
97
  if (l->rtype == __AVdouble) {
 
98
    RETURN(double, dret);
 
99
  } else
 
100
  if (l->rtype == __AVvoidp) {
 
101
    RETURN(void*, i);
 
102
  } else
 
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);
 
108
      } else
 
109
      if (l->rsize == sizeof(short)) {
 
110
        RETURN(short, *(short*)i);
 
111
      } else
 
112
      if (l->rsize == sizeof(int)) {
 
113
        RETURN(int, *(int*)i);
 
114
      } else
 
115
      if (l->rsize == sizeof(double)) {
 
116
        ((int*)l->raddr)[0] = ((int*)i)[0];
 
117
        ((int*)l->raddr)[1] = ((int*)i)[1];
 
118
      } else {
 
119
        int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
 
120
        while (--n >= 0)
 
121
          ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
 
122
      }
 
123
    } else {
 
124
      /* normal struct return convention */
 
125
      if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
 
126
        if (l->rsize == sizeof(char)) {
 
127
          RETURN(char, i);
 
128
        } else
 
129
        if (l->rsize == sizeof(short)) {
 
130
          RETURN(short, i);
 
131
        } else
 
132
        if (l->rsize == sizeof(int)) {
 
133
          RETURN(int, i);
 
134
        } else
 
135
        if (l->rsize == 2*sizeof(__avword)) {
 
136
          RETURN(long long, llret);
 
137
        }
 
138
      }
 
139
    }
 
140
  }
 
141
  return 0;
 
142
}
 
143
 
 
144
#endif /*_avcall_convex_c */