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

« back to all changes in this revision

Viewing changes to callback/vacall_r/vacall-mips.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 mips CPU */
 
2
 
 
3
/*
 
4
 * Copyright 1995-2004 Bruno Haible, <bruno@clisp.org>
 
5
 *
 
6
 * This is free software distributed under the GNU General Public Licence
 
7
 * described in the file COPYING. Contact the author if you don't have this
 
8
 * or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
 
9
 * on this software.
 
10
 */
 
11
 
 
12
#ifndef REENTRANT
 
13
#include "vacall.h.in"
 
14
#else /* REENTRANT */
 
15
#include "vacall_r.h.in"
 
16
#endif
 
17
 
 
18
#ifndef REENTRANT
 
19
typedef void (*func_pointer)(va_alist);
 
20
#else /* REENTRANT */
 
21
#define __vacall __vacall_r
 
22
typedef void (*func_pointer)(void*,va_alist);
 
23
register struct { func_pointer vacall_function; void* arg; }
 
24
         *      env     __asm__("$2");
 
25
#endif
 
26
register func_pointer t9 __asm__("$25");
 
27
register float  farg1   __asm__("$f12");
 
28
register float  farg2   __asm__("$f14");
 
29
register double darg1   __asm__("$f12");
 
30
register double darg2   __asm__("$f14");
 
31
register int    iret    __asm__("$2");
 
32
register int    iret2   __asm__("$3");
 
33
register float  fret    __asm__("$f0");
 
34
register double dret    __asm__("$f0");
 
35
 
 
36
void /* the return type is variable, not void! */
 
37
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
 
38
          __vaword firstword)
 
39
{
 
40
  __va_alist list;
 
41
  /* gcc-2.6.3 source says: When a parameter is passed in a register,
 
42
   * stack space is still allocated for it.
 
43
   */
 
44
  /* Move the arguments passed in registers to their stack locations. */
 
45
  (&firstword)[-4] = word1;
 
46
  (&firstword)[-3] = word2;
 
47
  (&firstword)[-2] = word3;
 
48
  (&firstword)[-1] = word4;
 
49
  list.darg[0] = darg1;
 
50
  list.darg[1] = darg2;
 
51
  list.farg[0] = farg1;
 
52
  list.farg[1] = farg2;
 
53
  /* Prepare the va_alist. */
 
54
  list.flags = 0;
 
55
  list.aptr = (long)(&firstword - 4);
 
56
  list.raddr = (void*)0;
 
57
  list.rtype = __VAvoid;
 
58
  list.memargptr = (long)&firstword;
 
59
  list.anum = 0;
 
60
  /* Call vacall_function. The macros do all the rest. */
 
61
#ifndef REENTRANT
 
62
  (*(t9 = vacall_function)) (&list);
 
63
#else /* REENTRANT */
 
64
  (*(t9 = env->vacall_function)) (env->arg,&list);
 
65
#endif
 
66
  /* Put return value into proper register. */
 
67
  if (list.rtype == __VAvoid) {
 
68
  } else
 
69
  if (list.rtype == __VAchar) {
 
70
    iret = list.tmp._char;
 
71
  } else
 
72
  if (list.rtype == __VAschar) {
 
73
    iret = list.tmp._schar;
 
74
  } else
 
75
  if (list.rtype == __VAuchar) {
 
76
    iret = list.tmp._uchar;
 
77
  } else
 
78
  if (list.rtype == __VAshort) {
 
79
    iret = list.tmp._short;
 
80
  } else
 
81
  if (list.rtype == __VAushort) {
 
82
    iret = list.tmp._ushort;
 
83
  } else
 
84
  if (list.rtype == __VAint) {
 
85
    iret = list.tmp._int;
 
86
  } else
 
87
  if (list.rtype == __VAuint) {
 
88
    iret = list.tmp._uint;
 
89
  } else
 
90
  if (list.rtype == __VAlong) {
 
91
    iret = list.tmp._long;
 
92
  } else
 
93
  if (list.rtype == __VAulong) {
 
94
    iret = list.tmp._ulong;
 
95
  } else
 
96
  if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
 
97
    iret  = ((__vaword *) &list.tmp._longlong)[0];
 
98
    iret2 = ((__vaword *) &list.tmp._longlong)[1];
 
99
  } else
 
100
  if (list.rtype == __VAfloat) {
 
101
    fret = list.tmp._float;
 
102
  } else
 
103
  if (list.rtype == __VAdouble) {
 
104
    dret = list.tmp._double;
 
105
  } else
 
106
  if (list.rtype == __VAvoidp) {
 
107
    iret = (long)list.tmp._ptr;
 
108
  } else
 
109
  if (list.rtype == __VAstruct) {
 
110
    if (list.flags & __VA_PCC_STRUCT_RETURN) {
 
111
      /* pcc struct return convention */
 
112
      iret = (long) list.raddr;
 
113
    } else {
 
114
      /* normal struct return convention */
 
115
      if (list.flags & __VA_SMALL_STRUCT_RETURN) {
 
116
        if (list.rsize == sizeof(char)) {
 
117
          iret = *(unsigned char *) list.raddr;
 
118
        } else
 
119
        if (list.rsize == sizeof(short)) {
 
120
          iret = *(unsigned short *) list.raddr;
 
121
        } else
 
122
        if (list.rsize == sizeof(int)) {
 
123
          iret = *(unsigned int *) list.raddr;
 
124
        }
 
125
      }
 
126
    }
 
127
  }
 
128
}