1
/* vacall function for alpha CPU */
4
* Copyright 1995-2004 Bruno Haible, <bruno@clisp.org>
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,
13
#include "vacall.h.in"
15
#include "vacall_r.h.in"
19
#define __vacall __vacall_r
20
register struct { void (*vacall_function) (void*,va_alist); void* arg; }
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");
40
void /* the return type is variable, not void! */
41
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
42
__vaword word5, __vaword word6,
46
struct { double farg1, farg2, farg3, farg4, farg5, farg6;
47
long arg1, arg2, arg3, arg4, arg5, arg6;
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.
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;
66
/* Prepare the va_alist. */
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. */
74
(*vacall_function) (&list);
76
(*env->vacall_function) (env->arg,&list);
78
/* Put return value into proper register. */
79
if (list.rtype == __VAvoid) {
81
if (list.rtype == __VAchar) {
82
iret = list.tmp._char;
84
if (list.rtype == __VAschar) {
85
iret = list.tmp._schar;
87
if (list.rtype == __VAuchar) {
88
iret = list.tmp._uchar;
90
if (list.rtype == __VAshort) {
91
iret = list.tmp._short;
93
if (list.rtype == __VAushort) {
94
iret = list.tmp._ushort;
96
if (list.rtype == __VAint) {
99
if (list.rtype == __VAuint) {
100
iret = list.tmp._uint;
102
if (list.rtype == __VAlong) {
103
iret = list.tmp._long;
105
if (list.rtype == __VAulong) {
106
iret = list.tmp._ulong;
108
if (list.rtype == __VAlonglong) {
109
iret = list.tmp._long;
111
if (list.rtype == __VAulonglong) {
112
iret = list.tmp._ulong;
114
if (list.rtype == __VAfloat) {
115
fret = list.tmp._float;
117
if (list.rtype == __VAdouble) {
118
dret = list.tmp._double;
120
if (list.rtype == __VAvoidp) {
121
iret = (long)list.tmp._ptr;
123
if (list.rtype == __VAstruct) {
124
if (list.flags & __VA_PCC_STRUCT_RETURN) {
125
/* pcc struct return convention */
126
iret = (long) list.raddr;
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;
133
if (list.rsize == sizeof(short)) {
134
iret = *(unsigned short *) list.raddr;
136
if (list.rsize == sizeof(int)) {
137
iret = *(unsigned int *) list.raddr;
139
if (list.rsize == sizeof(long)) {
140
iret = *(unsigned long *) list.raddr;
142
if (list.rsize == 2*sizeof(__vaword)) {
143
iret = ((__vaword *) list.raddr)[0];
144
iret2 = ((__vaword *) list.raddr)[1];