File: vacall-mips64.c

package info (click to toggle)
clisp 1%3A2.41-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 49,804 kB
  • ctags: 16,291
  • sloc: lisp: 75,912; ansic: 49,247; xml: 24,289; asm: 21,993; sh: 11,234; fortran: 6,692; cpp: 2,660; objc: 2,481; makefile: 2,355; perl: 164; sed: 55
file content (313 lines) | stat: -rw-r--r-- 13,144 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/* vacall function for mips CPU */

/*
 * Copyright 1995-2004 Bruno Haible, <bruno@clisp.org>
 *
 * This is free software distributed under the GNU General Public Licence
 * described in the file COPYING. Contact the author if you don't have this
 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
 * on this software.
 */

#ifndef REENTRANT
#include "vacall.h.in"
#else /* REENTRANT */
#include "vacall_r.h.in"
#endif

#ifndef REENTRANT
typedef void (*func_pointer)(va_alist);
#else /* REENTRANT */
#define __vacall __vacall_r
typedef void (*func_pointer)(void*,va_alist);
register struct { func_pointer vacall_function; void* arg; }
         *	env	__asm__("$2");
#endif
register func_pointer t9 __asm__("$25");
register void*	sp	__asm__("$sp");
register long	iarg0	__asm__("$4");
register long	iarg1	__asm__("$5");
register long	iarg2	__asm__("$6");
register long	iarg3	__asm__("$7");
register long	iarg4	__asm__("$8");
register long	iarg5	__asm__("$9");
register long	iarg6	__asm__("$10");
register long	iarg7	__asm__("$11");
register float	farg0	__asm__("$f12");
register float	farg1	__asm__("$f13");
register float	farg2	__asm__("$f14");
register float	farg3	__asm__("$f15");
register float	farg4	__asm__("$f16");
register float	farg5	__asm__("$f17");
register float	farg6	__asm__("$f18");
register float	farg7	__asm__("$f19");
register double	darg0	__asm__("$f12");
register double	darg1	__asm__("$f13");
register double	darg2	__asm__("$f14");
register double	darg3	__asm__("$f15");
register double	darg4	__asm__("$f16");
register double	darg5	__asm__("$f17");
register double	darg6	__asm__("$f18");
register double	darg7	__asm__("$f19");
register long	iret	__asm__("$2");
register long	iret2	__asm__("$3");
register float	fret	__asm__("$f0");
register float	fret2	__asm__("$f2");
register double	dret	__asm__("$f0");
register double	dret2	__asm__("$f2");

void /* the return type is variable, not void! */
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
          __vaword word5, __vaword word6, __vaword word7, __vaword word8,
          __vaword firstword)
{
  /* Move the arguments passed in registers to their stack locations. */
  (&firstword)[-8] = iarg0; /* word1 */
  (&firstword)[-7] = iarg1; /* word2 */
  (&firstword)[-6] = iarg2; /* word3 */
  (&firstword)[-5] = iarg3; /* word4 */
  (&firstword)[-4] = iarg4; /* word5 */
  (&firstword)[-3] = iarg5; /* word6 */
  (&firstword)[-2] = iarg6; /* word7 */
  (&firstword)[-1] = iarg7; /* word8 */
 {__va_alist list;
  list.darg[0] = darg0;
  list.darg[1] = darg1;
  list.darg[2] = darg2;
  list.darg[3] = darg3;
  list.darg[4] = darg4;
  list.darg[5] = darg5;
  list.darg[6] = darg6;
  list.darg[7] = darg7;
  list.farg[0] = farg0;
  list.farg[1] = farg1;
  list.farg[2] = farg2;
  list.farg[3] = farg3;
  list.farg[4] = farg4;
  list.farg[5] = farg5;
  list.farg[6] = farg6;
  list.farg[7] = farg7;
  /* Prepare the va_alist. */
  list.flags = 0;
  list.aptr = (long)(&firstword - 8);
  list.raddr = (void*)0;
  list.rtype = __VAvoid;
  list.memargptr = (long)&firstword;
  list.anum = 0;
  /* Call vacall_function. The macros do all the rest. */
#ifndef REENTRANT
  (*(t9 = vacall_function)) (&list);
#else /* REENTRANT */
  (*(t9 = env->vacall_function)) (env->arg,&list);
#endif
  /* Put return value into proper register. */
  if (list.rtype == __VAvoid) {
  } else
  if (list.rtype == __VAchar) {
    iret = list.tmp._char;
  } else
  if (list.rtype == __VAschar) {
    iret = list.tmp._schar;
  } else
  if (list.rtype == __VAuchar) {
    iret = list.tmp._uchar;
  } else
  if (list.rtype == __VAshort) {
    iret = list.tmp._short;
  } else
  if (list.rtype == __VAushort) {
    iret = list.tmp._ushort;
  } else
  if (list.rtype == __VAint) {
    iret = list.tmp._int;
  } else
  if (list.rtype == __VAuint) {
    iret = list.tmp._uint;
  } else
  if (list.rtype == __VAlong) {
    iret = list.tmp._long;
  } else
  if (list.rtype == __VAulong) {
    iret = list.tmp._ulong;
  } else
  if (list.rtype == __VAlonglong) {
    iret = list.tmp._long;
  } else
  if (list.rtype == __VAulonglong) {
    iret = list.tmp._ulong;
  } else
  if (list.rtype == __VAfloat) {
    fret = list.tmp._float;
  } else
  if (list.rtype == __VAdouble) {
    dret = list.tmp._double;
  } else
  if (list.rtype == __VAvoidp) {
    iret = (long)list.tmp._ptr;
  } else
  if (list.rtype == __VAstruct) {
    if (list.flags & __VA_PCC_STRUCT_RETURN) {
      /* pcc struct return convention */
      iret = (long) list.raddr;
    } else {
      /* normal struct return convention */
      if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
        if (list.flags & __VA_GCC_STRUCT_RETURN) {
          /* gcc returns structs of size 1,2,4,8 in registers. */
          if (list.rsize == sizeof(char)) {
            iret = *(unsigned char *) list.raddr;
          } else
          if (list.rsize == sizeof(short)) {
            iret = *(unsigned short *) list.raddr;
          } else
          if (list.rsize == sizeof(int)) {
            iret = *(unsigned int *) list.raddr;
          } else
          if (list.rsize == sizeof(long)) {
            iret = *(unsigned long *) list.raddr;
          }
        } else {
          /* cc returns structs of size <= 16 in registers. */
          /* Maybe this big if cascade could be replaced with
           * if (list.rsize > 0 && list.rsize <= 16)
           *   __asm__ ("ldl $2,%0 ; ldr $2,%1"
           *            : : "m" (((unsigned char *) list.raddr)[0]),
           *                "m" (((unsigned char *) list.raddr)[7]));
           */
          if (list.rsize > 0 && list.rsize <= 16) {
            if (list.rsize == 1) {
              iret =   (__vaword)((unsigned char *) list.raddr)[0] << 56;
            } else
            if (list.rsize == 2) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48);
            } else
            if (list.rsize == 3) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40);
            } else
            if (list.rsize == 4) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40)
                    | ((__vaword)((unsigned char *) list.raddr)[3] << 32);
            } else
            if (list.rsize == 5) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40)
                    | ((__vaword)((unsigned char *) list.raddr)[3] << 32)
                    | ((__vaword)((unsigned char *) list.raddr)[4] << 24);
            } else
            if (list.rsize == 6) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40)
                    | ((__vaword)((unsigned char *) list.raddr)[3] << 32)
                    | ((__vaword)((unsigned char *) list.raddr)[4] << 24)
                    | ((__vaword)((unsigned char *) list.raddr)[5] << 16);
            } else
            if (list.rsize == 7) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40)
                    | ((__vaword)((unsigned char *) list.raddr)[3] << 32)
                    | ((__vaword)((unsigned char *) list.raddr)[4] << 24)
                    | ((__vaword)((unsigned char *) list.raddr)[5] << 16)
                    | ((__vaword)((unsigned char *) list.raddr)[6] << 8);
            } else
            if (list.rsize >= 8 && list.rsize <= 16) {
              iret =  ((__vaword)((unsigned char *) list.raddr)[0] << 56)
                    | ((__vaword)((unsigned char *) list.raddr)[1] << 48)
                    | ((__vaword)((unsigned char *) list.raddr)[2] << 40)
                    | ((__vaword)((unsigned char *) list.raddr)[3] << 32)
                    | ((__vaword)((unsigned char *) list.raddr)[4] << 24)
                    | ((__vaword)((unsigned char *) list.raddr)[5] << 16)
                    | ((__vaword)((unsigned char *) list.raddr)[6] << 8)
                    |  (__vaword)((unsigned char *) list.raddr)[7];
              /* Maybe this big if cascade could be replaced with
               * if (list.rsize > 8 && list.rsize <= 16)
               *   __asm__ ("ldl $3,%0 ; ldr $3,%1"
               *            : : "m" (((unsigned char *) list.raddr)[8]),
               *                "m" (((unsigned char *) list.raddr)[15]));
               */
              if (list.rsize == 8) {
              } else
              if (list.rsize == 9) {
                iret2 =   (__vaword)((unsigned char *) list.raddr)[8] << 56;
              } else
              if (list.rsize == 10) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48);
              } else
              if (list.rsize == 11) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40);
              } else
              if (list.rsize == 12) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40)
                       | ((__vaword)((unsigned char *) list.raddr)[11] << 32);
              } else
              if (list.rsize == 13) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40)
                       | ((__vaword)((unsigned char *) list.raddr)[11] << 32)
                       | ((__vaword)((unsigned char *) list.raddr)[12] << 24);
              } else
              if (list.rsize == 14) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40)
                       | ((__vaword)((unsigned char *) list.raddr)[11] << 32)
                       | ((__vaword)((unsigned char *) list.raddr)[12] << 24)
                       | ((__vaword)((unsigned char *) list.raddr)[13] << 16);
              } else
              if (list.rsize == 15) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40)
                       | ((__vaword)((unsigned char *) list.raddr)[11] << 32)
                       | ((__vaword)((unsigned char *) list.raddr)[12] << 24)
                       | ((__vaword)((unsigned char *) list.raddr)[13] << 16)
                       | ((__vaword)((unsigned char *) list.raddr)[14] << 8);
              } else
              if (list.rsize == 16) {
                iret2 =  ((__vaword)((unsigned char *) list.raddr)[8] << 56)
                       | ((__vaword)((unsigned char *) list.raddr)[9] << 48)
                       | ((__vaword)((unsigned char *) list.raddr)[10] << 40)
                       | ((__vaword)((unsigned char *) list.raddr)[11] << 32)
                       | ((__vaword)((unsigned char *) list.raddr)[12] << 24)
                       | ((__vaword)((unsigned char *) list.raddr)[13] << 16)
                       | ((__vaword)((unsigned char *) list.raddr)[14] << 8)
                       |  (__vaword)((unsigned char *) list.raddr)[15];
              }
            }
          }
          if (list.flags & __VA_REGISTER_FLOATSTRUCT_RETURN) {
            if (list.rsize == sizeof(float)) {
              fret = *(float*)list.raddr;
            } else
            if (list.rsize == 2*sizeof(float)) {
              fret = *(float*)list.raddr;
              fret2 = *(float*)((char*)list.raddr + 4);
            }
          }
          if (list.flags & __VA_REGISTER_DOUBLESTRUCT_RETURN) {
            if (list.rsize == sizeof(double)) {
              dret = *(double*)list.raddr;
            } else
            if (list.rsize == 2*sizeof(double)) {
              dret = *(double*)list.raddr;
              dret2 = *(double*)((char*)list.raddr + 8);
            }
          }
        }
      }
    }
  }
}}