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

« back to all changes in this revision

Viewing changes to avcall/avcall-m88k.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_m88k_c                          /*-*- C -*-*/
 
2
#define _avcall_m88k_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 -fno-omit-frame-pointer !!!
 
14
 
 
15
  Foreign function interface for a M88000 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
  M88k Argument Passing Conventions:
 
21
 
 
22
  All arguments, except the non-structs among the first 8 words, are passed
 
23
  on the stack with word alignment. Doubles take two words and force double
 
24
  alignment. Scalars among the first 8 words are passed in registers.
 
25
  Structure args are are passed as true structures embedded in the argument
 
26
  stack.
 
27
 
 
28
  To return a structure, the called function copies the return value to the
 
29
  address supplied in register "r12".
 
30
 
 
31
  Compile this routine with gcc -O (or -O2 -fno-omit-frame-pointer or -g -O)
 
32
  to get the right register variables. For other compilers use the
 
33
  pre-compiled assembler version.
 
34
  ----------------------------------------------------------------------*/
 
35
#include "avcall.h.in"
 
36
 
 
37
#define RETURN(TYPE,VAL)        (*(TYPE*)l->raddr = (TYPE)(VAL))
 
38
 
 
39
register __avword*      sret    __asm__("r12");  /* structure return pointer */
 
40
 
 
41
int
 
42
__builtin_avcall(av_alist* l)
 
43
{
 
44
  register __avword*    sp      __asm__("r31"); /* C names for registers */
 
45
/*register __avword     iret    __asm__("r2"); */
 
46
  register __avword     iret2   __asm__("r3");
 
47
  register float        fret    __asm__("r2");
 
48
  register double       dret    __asm__("r2");
 
49
 
 
50
  __avword* argframe = (sp -= __AV_ALIST_WORDS); /* make room for argument list */
 
51
  int arglen = l->aptr - l->args;
 
52
  __avword i;
 
53
 
 
54
  for (i = 0; i < arglen; i++)          /* push function args onto stack */
 
55
    argframe[i] = l->args[i];
 
56
 
 
57
  if (l->rtype == __AVstruct)           /* pass struct return address */
 
58
    sret = l->raddr;
 
59
 
 
60
                                /* call function, pass 8 args in registers */
 
61
  i = (*l->func)(l->args[0], l->args[1], l->args[2], l->args[3],
 
62
                 l->args[4], l->args[5], l->args[6], l->args[7]);
 
63
 
 
64
  /* save return value */
 
65
  if (l->rtype == __AVvoid) {
 
66
  } else
 
67
  if (l->rtype == __AVword) {
 
68
    RETURN(__avword, i);
 
69
  } else
 
70
  if (l->rtype == __AVchar) {
 
71
    RETURN(char, i);
 
72
  } else
 
73
  if (l->rtype == __AVschar) {
 
74
    RETURN(signed char, i);
 
75
  } else
 
76
  if (l->rtype == __AVuchar) {
 
77
    RETURN(unsigned char, i);
 
78
  } else
 
79
  if (l->rtype == __AVshort) {
 
80
    RETURN(short, i);
 
81
  } else
 
82
  if (l->rtype == __AVushort) {
 
83
    RETURN(unsigned short, i);
 
84
  } else
 
85
  if (l->rtype == __AVint) {
 
86
    RETURN(int, i);
 
87
  } else
 
88
  if (l->rtype == __AVuint) {
 
89
    RETURN(unsigned int, i);
 
90
  } else
 
91
  if (l->rtype == __AVlong) {
 
92
    RETURN(long, i);
 
93
  } else
 
94
  if (l->rtype == __AVulong) {
 
95
    RETURN(unsigned long, i);
 
96
  } else
 
97
  if (l->rtype == __AVlonglong || l->rtype == __AVulonglong) {
 
98
    ((__avword*)l->raddr)[0] = i;
 
99
    ((__avword*)l->raddr)[1] = iret2;
 
100
  } else
 
101
  if (l->rtype == __AVfloat) {
 
102
    RETURN(float, fret);
 
103
  } else
 
104
  if (l->rtype == __AVdouble) {
 
105
    RETURN(double, dret);
 
106
  } else
 
107
  if (l->rtype == __AVvoidp) {
 
108
    RETURN(void*, i);
 
109
  } else
 
110
  if (l->rtype == __AVstruct) {
 
111
    if (l->flags & __AV_PCC_STRUCT_RETURN) {
 
112
      /* pcc struct return convention: need a  *(TYPE*)l->raddr = *(TYPE*)i;  */
 
113
      if (l->rsize == sizeof(char)) {
 
114
        RETURN(char, *(char*)i);
 
115
      } else
 
116
      if (l->rsize == sizeof(short)) {
 
117
        RETURN(short, *(short*)i);
 
118
      } else
 
119
      if (l->rsize == sizeof(int)) {
 
120
        RETURN(int, *(int*)i);
 
121
      } else
 
122
      if (l->rsize == sizeof(double)) {
 
123
        ((int*)l->raddr)[0] = ((int*)i)[0];
 
124
        ((int*)l->raddr)[1] = ((int*)i)[1];
 
125
      } else {
 
126
        int n = (l->rsize + sizeof(__avword)-1)/sizeof(__avword);
 
127
        while (--n >= 0)
 
128
          ((__avword*)l->raddr)[n] = ((__avword*)i)[n];
 
129
      }
 
130
    } else {
 
131
      /* normal struct return convention */
 
132
      if (l->flags & __AV_SMALL_STRUCT_RETURN) {
 
133
        if (l->rsize == sizeof(char)) {
 
134
          RETURN(char, i);
 
135
        } else
 
136
        if (l->rsize == sizeof(short)) {
 
137
          RETURN(short, i);
 
138
        } else
 
139
        if (l->rsize == sizeof(int)) {
 
140
          RETURN(int, i);
 
141
        }
 
142
      }
 
143
    }
 
144
  }
 
145
  sp += __AV_ALIST_WORDS;
 
146
  return 0;
 
147
}
 
148
 
 
149
#endif /*_avcall_m88k_c */