2
* Copyright 2008 Cadence Design Systems, Inc.
4
* Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
9
* Written by Eliot Miranda 11/07.
10
* Changes by John M McIntosh 12/1/08 to support powerpc
12
* Body of the various callIA32XXXReturn functions.
13
* Call a foreign function according to IA32-ish ABI rules.
16
double floatStorageArea[13];
17
sqInt funcAlien, resultMaybeAlien;
24
for (i = numArgs, size = 0; --i >= 0;) {
25
sqInt arg = argVector[i];
26
if (objIsAlien(arg) && sizeField(arg))
27
size += moduloPOT(sizeof(long),abs(sizeField(arg)));
28
else if (interpreterProxy->isFloatObject(arg)) {
30
size += figureOutFloatSize(typeSignatureArray,i);
32
size += sizeof(double);
34
else /* assume an integebr or pointer. check below. */
39
/* At point of call stack must be aligned to STACK_ALIGN_BYTES. So alloca
40
* at least enough for this plus the argvector, and start writing argvector
41
* at aligned point. Then just prior to call cut-back stack to aligned.
43
argvec = alloca(STACK_ALIGN_BYTES + moduloPOT(STACK_ALIGN_BYTES,size));
44
argvec = alignModuloPOT(STACK_ALIGN_BYTES, argvec);
50
for (i = 0; i < numArgs; i++) {
51
sqInt arg = argVector[i];
52
if (isSmallInt(arg)) {
53
*(long *)argvec = intVal(arg);
54
if (gpRegCount < 8) gpRegCount++;
55
argvec += sizeof(long);
57
else if (objIsAlien(arg)) {
60
if (!(size = sizeField(arg)))
61
size = argByteSize = sizeof(void *);
63
argByteSize = abs(size);
64
switch (argByteSize) {
66
memcpy(argvec+3, startOfDataWithSize(arg,size), argByteSize);
69
memcpy(argvec+2, startOfDataWithSize(arg,size), argByteSize);
72
memcpy(argvec+1, startOfDataWithSize(arg,size), argByteSize);
75
memcpy(argvec, startOfDataWithSize(arg,size), argByteSize);
77
long internalSructureSize = moduloPOT(sizeof(long), argByteSize);
78
if (gpRegCount < 8) gpRegCount += (internalSructureSize+3)/4;
79
if (gpRegCount > 8) gpRegCount = 8;
83
int sizeOfFloat = figureOutFloatSize(typeSignatureArray,i);
84
if (sizeOfFloat > 0) {
85
if (sizeOfFloat == sizeof(float)) {
86
float fv = *(float*)argvec;
91
if (fpRegCount < 13) { /* 13 registers for floating point numbers */
92
floatStorageArea[fpRegCount++] = v;
96
argvec += internalSructureSize;
98
else if (interpreterProxy->isFloatObject(arg)) {
99
double v = interpreterProxy->floatValueOf(arg);
100
if (interpreterProxy->failed())
101
return PrimErrBadArgument;
102
if (hasTypeArray && figureOutFloatSize(typeSignatureArray,i) == sizeof(float)) {
104
*(float *)argvec = floatv;
105
argvec += sizeof(float);
106
if (gpRegCount < 8) gpRegCount += 1;
108
*(double *)argvec = v;
109
argvec += sizeof(double);
110
if (gpRegCount < 8) gpRegCount += 2;
113
if (fpRegCount < 13) { /* 13 registers for floating point numbers */
114
floatStorageArea[fpRegCount++] = v;
117
if (gpRegCount > 8) gpRegCount = 8;
118
} else if (objIsUnsafeAlien(arg)) {
119
sqInt bitsObj = interpreterProxy->fetchPointerofObject(0,arg);
120
void *v = interpreterProxy->firstIndexableField(bitsObj);
121
*(void **)argvec = v;
122
if (gpRegCount < 8) gpRegCount++;
123
argvec += sizeof(long);
125
long v = interpreterProxy->signed32BitValueOf(arg);
126
if (interpreterProxy->failed())
127
return PrimErrBadArgument;
130
if (gpRegCount < 8) gpRegCount++;
131
argvec += sizeof(long);
135
funcAlien = interpreterProxy->stackValue(funcOffset);
136
ffiStackIndex = (argvec-argstart)/4;
137
GPRegsLocation = ffiStackLocation = (long *) argstart;
138
FPRegsLocation = &floatStorageArea[0];
139
f = *(void **)startOfParameterData(funcAlien);
140
#if STACK_ALIGN_BYTES
141
/* cut stack back to start of aligned args */