1
/* vacall function for m68k CPU */
4
* Copyright 1995-2006 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; }
28
register void* sret __asm__("a1");
29
register int iret __asm__("d0");
30
register int iret2 __asm__("d1");
31
register int pret __asm__("a0"); /* some compilers return pointers in a0 */
32
register float fret __asm__("d0"); /* d0 */
33
register double dret __asm__("d0"); /* d0,d1 */
34
register float fp_fret __asm__("fp0");
35
register double fp_dret __asm__("fp0");
37
void /* the return type is variable, not void! */
38
__vacall (__vaword firstword)
41
/* Prepare the va_alist. */
43
list.aptr = (long)&firstword;
44
list.raddr = (void*)0;
45
list.rtype = __VAvoid;
46
list.structraddr = sret;
47
/* Call vacall_function. The macros do all the rest. */
49
(*vacall_function) (&list);
51
(*env->vacall_function) (env->arg,&list);
53
/* Put return value into proper register. */
54
if (list.rtype == __VAvoid) {
56
if (list.rtype == __VAchar) {
57
iret = list.tmp._char;
59
if (list.rtype == __VAschar) {
60
iret = list.tmp._schar;
62
if (list.rtype == __VAuchar) {
63
iret = list.tmp._uchar;
65
if (list.rtype == __VAshort) {
66
iret = list.tmp._short;
68
if (list.rtype == __VAushort) {
69
iret = list.tmp._ushort;
71
if (list.rtype == __VAint) {
74
if (list.rtype == __VAuint) {
75
iret = list.tmp._uint;
77
if (list.rtype == __VAlong) {
78
iret = list.tmp._long;
80
if (list.rtype == __VAulong) {
81
iret = list.tmp._ulong;
83
if (list.rtype == __VAlonglong || list.rtype == __VAulonglong) {
84
iret = ((__vaword *) &list.tmp._longlong)[0];
85
iret2 = ((__vaword *) &list.tmp._longlong)[1];
87
if (list.rtype == __VAfloat) {
88
if (list.flags & __VA_FREG_FLOAT_RETURN) {
89
fp_fret = list.tmp._float;
91
if (list.flags & __VA_SUNCC_FLOAT_RETURN) {
92
dret = (double)list.tmp._float;
94
fret = list.tmp._float;
98
if (list.rtype == __VAdouble) {
99
if (list.flags & __VA_FREG_FLOAT_RETURN) {
100
fp_dret = list.tmp._double;
102
dret = list.tmp._double;
105
if (list.rtype == __VAvoidp) {
106
pret = iret = (long)list.tmp._ptr;
108
if (list.rtype == __VAstruct) {
109
/* NB: On m68k, all structure sizes are divisible by 2. */
110
if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
111
if (list.rsize == sizeof(char)) { /* can't occur */
112
iret = *(unsigned char *) list.raddr;
115
if (list.rsize == sizeof(short)) {
116
iret = *(unsigned short *) list.raddr;
119
if (list.rsize == sizeof(int)) {
120
iret = *(unsigned int *) list.raddr;
123
if (list.rsize == 2*sizeof(__vaword)) {
124
iret = ((__vaword *) list.raddr)[0];
125
iret2 = ((__vaword *) list.raddr)[1];
129
if (list.flags & __VA_PCC_STRUCT_RETURN) {
130
/* pcc struct return convention */
131
pret = iret = (long) list.raddr;
133
/* normal struct return convention */