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

« back to all changes in this revision

Viewing changes to vacall/vacall-alpha.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 alpha 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
#ifdef REENTRANT
 
19
#define __vacall __vacall_r
 
20
register struct { void (*vacall_function) (void*,va_alist); void* arg; }
 
21
         *              env     __asm__("$1");
 
22
#endif
 
23
register long           arg1    __asm__("$16");
 
24
register long           arg2    __asm__("$17");
 
25
register long           arg3    __asm__("$18");
 
26
register long           arg4    __asm__("$19");
 
27
register long           arg5    __asm__("$20");
 
28
register long           arg6    __asm__("$21");
 
29
register double         farg1   __asm__("$f16");
 
30
register double         farg2   __asm__("$f17");
 
31
register double         farg3   __asm__("$f18");
 
32
register double         farg4   __asm__("$f19");
 
33
register double         farg5   __asm__("$f20");
 
34
register double         farg6   __asm__("$f21");
 
35
register __vaword       iret    __asm__("$0");
 
36
register __vaword       iret2   __asm__("$1");
 
37
register float          fret    __asm__("$f0");
 
38
register double         dret    __asm__("$f0");
 
39
 
 
40
void /* the return type is variable, not void! */
 
41
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
 
42
          __vaword word5, __vaword word6,
 
43
          __vaword firstword)
 
44
{
 
45
  __va_alist list;
 
46
  struct { double farg1, farg2, farg3, farg4, farg5, farg6;
 
47
           long arg1, arg2, arg3, arg4, arg5, arg6;
 
48
         }
 
49
    args;
 
50
  /* MAGIC ALERT! This is the last struct on the stack, so that
 
51
   * &args + 1 == &firstword. Look at the assembly code to convince yourself.
 
52
   */
 
53
  /* Move the arguments passed in registers to their stack locations. */
 
54
  /* args.arg1 = */ (&firstword)[-6] = word1;
 
55
  /* args.arg2 = */ (&firstword)[-5] = word2;
 
56
  /* args.arg3 = */ (&firstword)[-4] = word3;
 
57
  /* args.arg4 = */ (&firstword)[-3] = word4;
 
58
  /* args.arg5 = */ (&firstword)[-2] = word5;
 
59
  /* args.arg6 = */ (&firstword)[-1] = word6;
 
60
  args.farg1 = farg1;
 
61
  args.farg2 = farg2;
 
62
  args.farg3 = farg3;
 
63
  args.farg4 = farg4;
 
64
  args.farg5 = farg5;
 
65
  args.farg6 = farg6;
 
66
  /* Prepare the va_alist. */
 
67
  list.flags = 0;
 
68
  list.aptr = (long)(&firstword - 6);
 
69
  list.raddr = (void*)0;
 
70
  list.rtype = __VAvoid;
 
71
  list.memargptr = (long)&firstword;
 
72
  /* Call vacall_function. The macros do all the rest. */
 
73
#ifndef REENTRANT
 
74
  (*vacall_function) (&list);
 
75
#else /* REENTRANT */
 
76
  (*env->vacall_function) (env->arg,&list);
 
77
#endif
 
78
  /* Put return value into proper register. */
 
79
  if (list.rtype == __VAvoid) {
 
80
  } else
 
81
  if (list.rtype == __VAchar) {
 
82
    iret = list.tmp._char;
 
83
  } else
 
84
  if (list.rtype == __VAschar) {
 
85
    iret = list.tmp._schar;
 
86
  } else
 
87
  if (list.rtype == __VAuchar) {
 
88
    iret = list.tmp._uchar;
 
89
  } else
 
90
  if (list.rtype == __VAshort) {
 
91
    iret = list.tmp._short;
 
92
  } else
 
93
  if (list.rtype == __VAushort) {
 
94
    iret = list.tmp._ushort;
 
95
  } else
 
96
  if (list.rtype == __VAint) {
 
97
    iret = list.tmp._int;
 
98
  } else
 
99
  if (list.rtype == __VAuint) {
 
100
    iret = list.tmp._uint;
 
101
  } else
 
102
  if (list.rtype == __VAlong) {
 
103
    iret = list.tmp._long;
 
104
  } else
 
105
  if (list.rtype == __VAulong) {
 
106
    iret = list.tmp._ulong;
 
107
  } else
 
108
  if (list.rtype == __VAlonglong) {
 
109
    iret = list.tmp._long;
 
110
  } else
 
111
  if (list.rtype == __VAulonglong) {
 
112
    iret = list.tmp._ulong;
 
113
  } else
 
114
  if (list.rtype == __VAfloat) {
 
115
    fret = list.tmp._float;
 
116
  } else
 
117
  if (list.rtype == __VAdouble) {
 
118
    dret = list.tmp._double;
 
119
  } else
 
120
  if (list.rtype == __VAvoidp) {
 
121
    iret = (long)list.tmp._ptr;
 
122
  } else
 
123
  if (list.rtype == __VAstruct) {
 
124
    if (list.flags & __VA_PCC_STRUCT_RETURN) {
 
125
      /* pcc struct return convention */
 
126
      iret = (long) list.raddr;
 
127
    } else {
 
128
      /* normal struct return convention */
 
129
      if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
 
130
        if (list.rsize == sizeof(char)) {
 
131
          iret = *(unsigned char *) list.raddr;
 
132
        } else
 
133
        if (list.rsize == sizeof(short)) {
 
134
          iret = *(unsigned short *) list.raddr;
 
135
        } else
 
136
        if (list.rsize == sizeof(int)) {
 
137
          iret = *(unsigned int *) list.raddr;
 
138
        } else
 
139
        if (list.rsize == sizeof(long)) {
 
140
          iret = *(unsigned long *) list.raddr;
 
141
        } else
 
142
        if (list.rsize == 2*sizeof(__vaword)) {
 
143
          iret  = ((__vaword *) list.raddr)[0];
 
144
          iret2 = ((__vaword *) list.raddr)[1];
 
145
        }
 
146
      }
 
147
    }
 
148
  }
 
149
}