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

« back to all changes in this revision

Viewing changes to ffcall/vacall/vacall-sparc.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 sparc CPU */
2
 
 
3
 
/*
4
 
 * Copyright 1995-2005 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__("%g2");
22
 
#endif
23
 
register __vaword* fp   __asm__("%fp"); /* our %fp, caller's %sp */
24
 
register __vaword* ret  __asm__("%i7"); /* %i7+8 = return address */
25
 
register int    iret    __asm__("%i0");
26
 
register int    iret2   __asm__("%i1");
27
 
register float  fret    __asm__("%f0"); /* %f0 */
28
 
register double dret    __asm__("%f0"); /* %f0,%f1 */
29
 
 
30
 
void /* the return type is variable, not void! */
31
 
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
32
 
          __vaword word5, __vaword word6,
33
 
          __vaword firstword)
34
 
{
35
 
  __va_alist list;
36
 
  /* gcc-2.6.3 source says: When a parameter is passed in a register,
37
 
   * stack space is still allocated for it.
38
 
   */
39
 
  /* Move the arguments passed in registers to their stack locations. */
40
 
  (&firstword)[-6] = word1;
41
 
  (&firstword)[-5] = word2;
42
 
  (&firstword)[-4] = word3;
43
 
  (&firstword)[-3] = word4;
44
 
  (&firstword)[-2] = word5;
45
 
  (&firstword)[-1] = word6;
46
 
  /* Prepare the va_alist. */
47
 
  list.flags = 0;
48
 
  list.aptr = (long)(&firstword - 6);
49
 
  list.raddr = (void*)0;
50
 
  list.rtype = __VAvoid;
51
 
  list.structraddr = (void*)((&firstword)[-7]); /* = (void*) fp[16] */
52
 
  /* Call vacall_function. The macros do all the rest. */
53
 
#ifndef REENTRANT
54
 
  (*vacall_function) (&list);
55
 
#else /* REENTRANT */
56
 
  (*env->vacall_function) (env->arg,&list);
57
 
#endif
58
 
  /* Put return value into proper register. */
59
 
  if (list.rtype == __VAvoid) {
60
 
  } else
61
 
  if (list.rtype == __VAchar) {
62
 
    iret = list.tmp._char;
63
 
  } else
64
 
  if (list.rtype == __VAschar) {
65
 
    iret = list.tmp._schar;
66
 
  } else
67
 
  if (list.rtype == __VAuchar) {
68
 
    iret = list.tmp._uchar;
69
 
  } else
70
 
  if (list.rtype == __VAshort) {
71
 
    iret = list.tmp._short;
72
 
  } else
73
 
  if (list.rtype == __VAushort) {
74
 
    iret = list.tmp._ushort;
75
 
  } else
76
 
  if (list.rtype == __VAint) {
77
 
    iret = list.tmp._int;
78
 
  } else
79
 
  if (list.rtype == __VAuint) {
80
 
    iret = list.tmp._uint;
81
 
  } else
82
 
  if (list.rtype == __VAlong) {
83
 
    iret = list.tmp._long;
84
 
  } else
85
 
  if (list.rtype == __VAulong) {
86
 
    iret = list.tmp._ulong;
87
 
  } else
88
 
  if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
89
 
    iret  = ((__vaword *) &list.tmp._longlong)[0];
90
 
    iret2 = ((__vaword *) &list.tmp._longlong)[1];
91
 
  } else
92
 
  if (list.rtype == __VAfloat) {
93
 
    if (list.flags & __VA_SUNCC_FLOAT_RETURN) {
94
 
      dret = (double)list.tmp._float;
95
 
    } else {
96
 
      fret = list.tmp._float;
97
 
    }
98
 
  } else
99
 
  if (list.rtype == __VAdouble) {
100
 
    dret = list.tmp._double;
101
 
  } else
102
 
  if (list.rtype == __VAvoidp) {
103
 
    iret = (long)list.tmp._ptr;
104
 
  } else
105
 
  if (list.rtype == __VAstruct) {
106
 
    if (list.flags & __VA_SUNPROCC_STRUCT_RETURN) {
107
 
      /* Sun cc struct return convention. */
108
 
      /* The desired struct return address was passed in fp[16], later on
109
 
       * list.raddr = list.structraddr = fp[16]. Now the result has
110
 
       * already been copied there. No need to copy the result once more.
111
 
       * The caller expects to receive the struct return address in %o0.
112
 
       */
113
 
      iret = (long) list.raddr;
114
 
      if ((list.rsize & 0xfff) == ret[2])
115
 
        ret++; /* skip the "unimp n" instruction at the return address */
116
 
        /* else the "unimp n" instruction will cause a core dump */
117
 
    } else {
118
 
      if (list.flags & __VA_PCC_STRUCT_RETURN) {
119
 
        /* pcc struct return convention */
120
 
        iret = (long) list.raddr;
121
 
      } else {
122
 
        /* normal struct return convention */
123
 
        if (list.flags & __VA_SMALL_STRUCT_RETURN) {
124
 
          if (list.rsize == sizeof(char)) {
125
 
            iret = *(unsigned char *) list.raddr;
126
 
            goto done;
127
 
          } else
128
 
          if (list.rsize == sizeof(short)) {
129
 
            iret = *(unsigned short *) list.raddr;
130
 
            goto done;
131
 
          } else
132
 
          if (list.rsize == sizeof(int)) {
133
 
            iret = *(unsigned int *) list.raddr;
134
 
            goto done;
135
 
          }
136
 
        }
137
 
        ret++; /* skip the "unimp n" instruction at the return address */
138
 
        done: ;
139
 
      }
140
 
    }
141
 
  }
142
 
}