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

« back to all changes in this revision

Viewing changes to vacall/vacall-powerpc.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
/* vacall function for powerpc CPU */
 
2
 
 
3
/*
 
4
 * Copyright 1995-2006 Bruno Haible, <bruno@clisp.org>
 
5
 * Copyright 2000 Adam Fedor, <fedor@gnu.org>
 
6
 * Copyright 2004 Paul Guyot, <pguyot@kallisys.net>
 
7
 *
 
8
 * This is free software distributed under the GNU General Public Licence
 
9
 * described in the file COPYING. Contact the author if you don't have this
 
10
 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
 
11
 * on this software.
 
12
 */
 
13
 
 
14
#ifndef REENTRANT
 
15
#include "vacall.h.in"
 
16
#else /* REENTRANT */
 
17
#include "vacall_r.h.in"
 
18
#endif
 
19
 
 
20
#ifdef REENTRANT
 
21
#define __vacall __vacall_r
 
22
register struct { void (*vacall_function) (void*,va_alist); void* arg; }
 
23
         *              env     __asm__("r11");
 
24
#endif
 
25
register double         farg1   __asm__("fr1");
 
26
register double         farg2   __asm__("fr2");
 
27
register double         farg3   __asm__("fr3");
 
28
register double         farg4   __asm__("fr4");
 
29
register double         farg5   __asm__("fr5");
 
30
register double         farg6   __asm__("fr6");
 
31
register double         farg7   __asm__("fr7");
 
32
register double         farg8   __asm__("fr8");
 
33
register double         farg9   __asm__("fr9");
 
34
register double         farg10  __asm__("fr10");
 
35
register double         farg11  __asm__("fr11");
 
36
register double         farg12  __asm__("fr12");
 
37
register double         farg13  __asm__("fr13");
 
38
register __vaword       iret    __asm__("r3");
 
39
register __vaword       iret2   __asm__("r4");
 
40
register float          fret    __asm__("fr1");
 
41
register double         dret    __asm__("fr1");
 
42
 
 
43
void /* the return type is variable, not void! */
 
44
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
 
45
          __vaword word5, __vaword word6, __vaword word7, __vaword word8,
 
46
          __vaword firstword)
 
47
{
 
48
  __va_alist list;
 
49
#if defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))
 
50
  /* gcc-2.6.3 source says: When a parameter is passed in a register,
 
51
   * stack space is still allocated for it.
 
52
   */
 
53
  /* Move the arguments passed in registers to their stack locations. */
 
54
  (&firstword)[-8] = word1;
 
55
  (&firstword)[-7] = word2;
 
56
  (&firstword)[-6] = word3;
 
57
  (&firstword)[-5] = word4;
 
58
  (&firstword)[-4] = word5;
 
59
  (&firstword)[-3] = word6;
 
60
  (&firstword)[-2] = word7;
 
61
  (&firstword)[-1] = word8;
 
62
#else
 
63
  /* Move the arguments passed in registers to temp storage, since 
 
64
     moving them to the stack would mess up the stack */
 
65
  list.regarg[0] = word1;
 
66
  list.regarg[1] = word2;
 
67
  list.regarg[2] = word3;
 
68
  list.regarg[3] = word4;
 
69
  list.regarg[4] = word5;
 
70
  list.regarg[5] = word6;
 
71
  list.regarg[6] = word7;
 
72
  list.regarg[7] = word8;
 
73
#endif
 
74
  list.farg[0] = farg1;
 
75
  list.farg[1] = farg2;
 
76
  list.farg[2] = farg3;
 
77
  list.farg[3] = farg4;
 
78
  list.farg[4] = farg5;
 
79
  list.farg[5] = farg6;
 
80
  list.farg[6] = farg7;
 
81
  list.farg[7] = farg8;
 
82
#if defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))
 
83
  list.farg[8] = farg9;
 
84
  list.farg[9] = farg10;
 
85
  list.farg[10] = farg11;
 
86
  list.farg[11] = farg12;
 
87
  list.farg[12] = farg13;
 
88
#endif
 
89
  /* Prepare the va_alist. */
 
90
  list.flags = 0;
 
91
#if defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))
 
92
  list.aptr = (long)(&firstword - 8);
 
93
#else
 
94
  list.aptr = (long)(&list.regarg[0]);
 
95
  list.saptr = (long)(&firstword);
 
96
  list.onstack = 0;
 
97
#endif
 
98
  list.raddr = (void*)0;
 
99
  list.rtype = __VAvoid;
 
100
  list.memfargptr = &list.farg[0];
 
101
  /* Call vacall_function. The macros do all the rest. */
 
102
#ifndef REENTRANT
 
103
  (*vacall_function) (&list);
 
104
#else /* REENTRANT */
 
105
  (*env->vacall_function) (env->arg,&list);
 
106
#endif
 
107
  /* Put return value into proper register. */
 
108
  if (list.rtype == __VAvoid) {
 
109
  } else
 
110
  if (list.rtype == __VAchar) {
 
111
    iret = list.tmp._char;
 
112
  } else
 
113
  if (list.rtype == __VAschar) {
 
114
    iret = list.tmp._schar;
 
115
  } else
 
116
  if (list.rtype == __VAuchar) {
 
117
    iret = list.tmp._uchar;
 
118
  } else
 
119
  if (list.rtype == __VAshort) {
 
120
    iret = list.tmp._short;
 
121
  } else
 
122
  if (list.rtype == __VAushort) {
 
123
    iret = list.tmp._ushort;
 
124
  } else
 
125
  if (list.rtype == __VAint) {
 
126
    iret = list.tmp._int;
 
127
  } else
 
128
  if (list.rtype == __VAuint) {
 
129
    iret = list.tmp._uint;
 
130
  } else
 
131
  if (list.rtype == __VAlong) {
 
132
    iret = list.tmp._long;
 
133
  } else
 
134
  if (list.rtype == __VAulong) {
 
135
    iret = list.tmp._ulong;
 
136
  } else
 
137
  if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
 
138
    iret  = ((__vaword *) &list.tmp._longlong)[0];
 
139
    iret2 = ((__vaword *) &list.tmp._longlong)[1];
 
140
  } else
 
141
  if (list.rtype == __VAfloat) {
 
142
    fret = list.tmp._float;
 
143
  } else
 
144
  if (list.rtype == __VAdouble) {
 
145
    dret = list.tmp._double;
 
146
  } else
 
147
  if (list.rtype == __VAvoidp) {
 
148
    iret = (long)list.tmp._ptr;
 
149
  } else
 
150
  if (list.rtype == __VAstruct) {
 
151
    if (list.flags & __VA_PCC_STRUCT_RETURN) {
 
152
      /* pcc struct return convention */
 
153
      iret = (long) list.raddr;
 
154
    } else {
 
155
      /* normal struct return convention */
 
156
      if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
 
157
        if (list.rsize == sizeof(char)) {
 
158
          iret = *(unsigned char *) list.raddr;
 
159
        } else
 
160
        if (list.rsize == sizeof(short)) {
 
161
          iret = *(unsigned short *) list.raddr;
 
162
        } else
 
163
        if (list.rsize == sizeof(int)) {
 
164
          iret = *(unsigned int *) list.raddr;
 
165
        } else
 
166
        if (list.rsize == 2*sizeof(__vaword)) {
 
167
          iret  = ((__vaword *) list.raddr)[0];
 
168
          iret2 = ((__vaword *) list.raddr)[1];
 
169
        }
 
170
      }
 
171
    }
 
172
  }
 
173
}