1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/* vacall function for powerpc64 CPU */
/*
* Copyright 1995-2006 Bruno Haible, <bruno@clisp.org>
* Copyright 2000 Adam Fedor, <fedor@gnu.org>
* Copyright 2004 Paul Guyot, <pguyot@kallisys.net>
*
* This is free software distributed under the GNU General Public Licence
* described in the file COPYING. Contact the author if you don't have this
* or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
* on this software.
*/
#ifndef REENTRANT
#include "vacall.h.in"
#else /* REENTRANT */
#include "vacall_r.h.in"
#endif
#ifdef REENTRANT
#define __vacall __vacall_r
register struct { void (*vacall_function) (void*,va_alist); void* arg; }
* env __asm__("r11");
#endif
register double farg1 __asm__("fr1");
register double farg2 __asm__("fr2");
register double farg3 __asm__("fr3");
register double farg4 __asm__("fr4");
register double farg5 __asm__("fr5");
register double farg6 __asm__("fr6");
register double farg7 __asm__("fr7");
register double farg8 __asm__("fr8");
register double farg9 __asm__("fr9");
register double farg10 __asm__("fr10");
register double farg11 __asm__("fr11");
register double farg12 __asm__("fr12");
register double farg13 __asm__("fr13");
register __vaword iret __asm__("r3");
register float fret __asm__("fr1");
register double dret __asm__("fr1");
void /* the return type is variable, not void! */
__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
__vaword word5, __vaword word6, __vaword word7, __vaword word8,
__vaword firstword)
{
__va_alist list;
/* When a parameter is passed in a register,
* stack space is still allocated for it.
*/
/* Move the arguments passed in registers to their stack locations. */
(&firstword)[-8] = word1;
(&firstword)[-7] = word2;
(&firstword)[-6] = word3;
(&firstword)[-5] = word4;
(&firstword)[-4] = word5;
(&firstword)[-3] = word6;
(&firstword)[-2] = word7;
(&firstword)[-1] = word8;
list.farg[0] = farg1;
list.farg[1] = farg2;
list.farg[2] = farg3;
list.farg[3] = farg4;
list.farg[4] = farg5;
list.farg[5] = farg6;
list.farg[6] = farg7;
list.farg[7] = farg8;
list.farg[8] = farg9;
list.farg[9] = farg10;
list.farg[10] = farg11;
list.farg[11] = farg12;
list.farg[12] = farg13;
/* Prepare the va_alist. */
list.flags = 0;
list.aptr = (long)(&firstword - 8);
list.raddr = (void*)0;
list.rtype = __VAvoid;
list.memfargptr = &list.farg[0];
/* Call vacall_function. The macros do all the rest. */
#ifndef REENTRANT
(*vacall_function) (&list);
#else /* REENTRANT */
(*env->vacall_function) (env->arg,&list);
#endif
/* Put return value into proper register. */
if (list.rtype == __VAvoid) {
} else
if (list.rtype == __VAchar) {
iret = list.tmp._char;
} else
if (list.rtype == __VAschar) {
iret = list.tmp._schar;
} else
if (list.rtype == __VAuchar) {
iret = list.tmp._uchar;
} else
if (list.rtype == __VAshort) {
iret = list.tmp._short;
} else
if (list.rtype == __VAushort) {
iret = list.tmp._ushort;
} else
if (list.rtype == __VAint) {
iret = list.tmp._int;
} else
if (list.rtype == __VAuint) {
iret = list.tmp._uint;
} else
if (list.rtype == __VAlong) {
iret = list.tmp._long;
} else
if (list.rtype == __VAulong) {
iret = list.tmp._ulong;
} else
if (list.rtype == __VAlonglong) {
iret = list.tmp._long;
} else
if (list.rtype == __VAulonglong) {
iret = list.tmp._ulong;
} else
if (list.rtype == __VAfloat) {
fret = list.tmp._float;
} else
if (list.rtype == __VAdouble) {
dret = list.tmp._double;
} else
if (list.rtype == __VAvoidp) {
iret = (long)list.tmp._ptr;
} else
if (list.rtype == __VAstruct) {
/* __VA_PCC_STRUCT_RETURN and __VA_REGISTER_STRUCT_RETURN are ignored */
}
}
|