mirror of
https://github.com/kevinbentley/Descent3.git
synced 2026-04-05 23:00:03 -04:00
clang-format on everything.
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc_mips.cpp
|
||||
//
|
||||
@@ -38,7 +37,6 @@
|
||||
// by Manu Evans in April, 2006
|
||||
//
|
||||
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef MAX_PORTABILITY
|
||||
@@ -77,116 +75,99 @@ extern "C" asQWORD mipsFunc(int intArgSize, int floatArgSize, int stackArgSize,
|
||||
|
||||
// puts the arguments in the correct place in the mipsArgs-array. See comments above.
|
||||
// This could be done better.
|
||||
inline void splitArgs(const asDWORD *args, int argNum, int &numRegIntArgs, int &numRegFloatArgs, int &numRestArgs, int hostFlags)
|
||||
{
|
||||
int i;
|
||||
inline void splitArgs(const asDWORD *args, int argNum, int &numRegIntArgs, int &numRegFloatArgs, int &numRestArgs,
|
||||
int hostFlags) {
|
||||
int i;
|
||||
|
||||
int argBit = 1;
|
||||
for (i = 0; i < argNum; i++)
|
||||
{
|
||||
if (hostFlags & argBit)
|
||||
{
|
||||
if (numRegFloatArgs < AS_NUM_REG_FLOATS)
|
||||
{
|
||||
// put in float register
|
||||
mipsArgs[AS_NUM_REG_INTS + numRegFloatArgs] = args[i];
|
||||
numRegFloatArgs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// put in stack
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
|
||||
numRestArgs++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numRegIntArgs < AS_NUM_REG_INTS)
|
||||
{
|
||||
// put in int register
|
||||
mipsArgs[numRegIntArgs] = args[i];
|
||||
numRegIntArgs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// put in stack
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
|
||||
numRestArgs++;
|
||||
}
|
||||
}
|
||||
argBit <<= 1;
|
||||
}
|
||||
int argBit = 1;
|
||||
for (i = 0; i < argNum; i++) {
|
||||
if (hostFlags & argBit) {
|
||||
if (numRegFloatArgs < AS_NUM_REG_FLOATS) {
|
||||
// put in float register
|
||||
mipsArgs[AS_NUM_REG_INTS + numRegFloatArgs] = args[i];
|
||||
numRegFloatArgs++;
|
||||
} else {
|
||||
// put in stack
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
|
||||
numRestArgs++;
|
||||
}
|
||||
} else {
|
||||
if (numRegIntArgs < AS_NUM_REG_INTS) {
|
||||
// put in int register
|
||||
mipsArgs[numRegIntArgs] = args[i];
|
||||
numRegIntArgs++;
|
||||
} else {
|
||||
// put in stack
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + numRestArgs] = args[i];
|
||||
numRestArgs++;
|
||||
}
|
||||
}
|
||||
argBit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
asQWORD CallCDeclFunction(const asDWORD *args, int argSize, asDWORD func, int flags)
|
||||
{
|
||||
int argNum = argSize >> 2;
|
||||
asQWORD CallCDeclFunction(const asDWORD *args, int argSize, asDWORD func, int flags) {
|
||||
int argNum = argSize >> 2;
|
||||
|
||||
int intArgs = 0;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
int intArgs = 0;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if(argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if (argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
}
|
||||
|
||||
// This function is identical to CallCDeclFunction, with the only difference that
|
||||
// the value in the first parameter is the object
|
||||
asQWORD CallThisCallFunction(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
|
||||
{
|
||||
int argNum = argSize >> 2;
|
||||
asQWORD CallThisCallFunction(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags) {
|
||||
int argNum = argSize >> 2;
|
||||
|
||||
int intArgs = 1;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
int intArgs = 1;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
|
||||
mipsArgs[0] = (asDWORD) obj;
|
||||
mipsArgs[0] = (asDWORD)obj;
|
||||
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if (argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if (argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
}
|
||||
|
||||
// This function is identical to CallCDeclFunction, with the only difference that
|
||||
// the value in the last parameter is the object
|
||||
asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags)
|
||||
{
|
||||
int argNum = argSize >> 2;
|
||||
asQWORD CallThisCallFunction_objLast(const void *obj, const asDWORD *args, int argSize, asDWORD func, int flags) {
|
||||
int argNum = argSize >> 2;
|
||||
|
||||
int intArgs = 0;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
int intArgs = 0;
|
||||
int floatArgs = 0;
|
||||
int restArgs = 0;
|
||||
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if(argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
// put the arguments in the correct places in the mipsArgs array
|
||||
if (argNum > 0)
|
||||
splitArgs(args, argNum, intArgs, floatArgs, restArgs, flags);
|
||||
|
||||
if(intArgs < AS_NUM_REG_INTS)
|
||||
{
|
||||
mipsArgs[intArgs] = (asDWORD) obj;
|
||||
intArgs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + restArgs] = (asDWORD) obj;
|
||||
restArgs++;
|
||||
}
|
||||
if (intArgs < AS_NUM_REG_INTS) {
|
||||
mipsArgs[intArgs] = (asDWORD)obj;
|
||||
intArgs++;
|
||||
} else {
|
||||
mipsArgs[AS_NUM_REG_INTS + AS_NUM_REG_FLOATS + restArgs] = (asDWORD)obj;
|
||||
restArgs++;
|
||||
}
|
||||
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
return mipsFunc(intArgs << 2, floatArgs << 2, restArgs << 2, func);
|
||||
}
|
||||
|
||||
asDWORD GetReturnedFloat()
|
||||
{
|
||||
asDWORD f;
|
||||
asDWORD GetReturnedFloat() {
|
||||
asDWORD f;
|
||||
|
||||
asm("swc1 $f0, %0\n" : "=m"(f));
|
||||
asm("swc1 $f0, %0\n" : "=m"(f));
|
||||
|
||||
return f;
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -205,360 +186,321 @@ asm(
|
||||
" .end Func\n"
|
||||
*/
|
||||
|
||||
|
||||
// sizeof(double) == 4 with sh-elf-gcc (3.4.0) -m4
|
||||
// so this isn't really used...
|
||||
asQWORD GetReturnedDouble()
|
||||
{
|
||||
asQWORD d;
|
||||
asQWORD GetReturnedDouble() {
|
||||
asQWORD d;
|
||||
|
||||
printf("Broken!!!");
|
||||
/*
|
||||
asm("sw $v0, %0\n" : "=m"(d));
|
||||
*/
|
||||
return d;
|
||||
printf("Broken!!!");
|
||||
/*
|
||||
asm("sw $v0, %0\n" : "=m"(d));
|
||||
*/
|
||||
return d;
|
||||
}
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer)
|
||||
{
|
||||
asCScriptEngine *engine = context->engine;
|
||||
asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
int CallSystemFunction(int id, asCContext *context, void *objectPointer) {
|
||||
asCScriptEngine *engine = context->engine;
|
||||
asSSystemFunctionInterface *sysFunc = engine->scriptFunctions[id]->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if (callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD)
|
||||
return context->CallGeneric(id, objectPointer);
|
||||
|
||||
asQWORD retQW = 0;
|
||||
asQWORD retQW = 0;
|
||||
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
|
||||
void *func = (void*)sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asDWORD *args = context->regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
void *obj = 0;
|
||||
asDWORD *vftable;
|
||||
int popSize = paramSize;
|
||||
void *func = (void *)sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asDWORD *args = context->regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
void *obj = 0;
|
||||
asDWORD *vftable;
|
||||
int popSize = paramSize;
|
||||
|
||||
context->regs.objectType = descr->returnType.GetObjectType();
|
||||
if( descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle() )
|
||||
{
|
||||
// Allocate the memory for the object
|
||||
retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
|
||||
mipsArgs[AS_MIPS_MAX_ARGS+1] = (asDWORD) retPointer;
|
||||
context->regs.objectType = descr->returnType.GetObjectType();
|
||||
if (descr->returnType.IsObject() && !descr->returnType.IsReference() && !descr->returnType.IsObjectHandle()) {
|
||||
// Allocate the memory for the object
|
||||
retPointer = engine->CallAlloc(descr->returnType.GetObjectType());
|
||||
mipsArgs[AS_MIPS_MAX_ARGS + 1] = (asDWORD)retPointer;
|
||||
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
}
|
||||
if (sysFunc->hostReturnInMemory) {
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
}
|
||||
|
||||
if( callConv >= ICC_THISCALL )
|
||||
{
|
||||
if( objectPointer )
|
||||
{
|
||||
obj = objectPointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize++;
|
||||
if (callConv >= ICC_THISCALL) {
|
||||
if (objectPointer) {
|
||||
obj = objectPointer;
|
||||
} else {
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize++;
|
||||
|
||||
// Check for null pointer
|
||||
obj = (void*)*(args + paramSize);
|
||||
if( obj == 0 )
|
||||
{
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
if( retPointer )
|
||||
engine->CallFree(retPointer);
|
||||
return 0;
|
||||
}
|
||||
// Check for null pointer
|
||||
obj = (void *)*(args + paramSize);
|
||||
if (obj == 0) {
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
if (retPointer)
|
||||
engine->CallFree(retPointer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
obj = (void*)(int(obj) + sysFunc->baseOffset);
|
||||
}
|
||||
}
|
||||
asASSERT(descr->parameterTypes.GetLength() <= AS_MIPS_MAX_ARGS);
|
||||
// Add the base offset for multiple inheritance
|
||||
obj = (void *)(int(obj) + sysFunc->baseOffset);
|
||||
}
|
||||
}
|
||||
asASSERT(descr->parameterTypes.GetLength() <= AS_MIPS_MAX_ARGS);
|
||||
|
||||
// mark all float arguments
|
||||
int argBit = 1;
|
||||
int hostFlags = 0;
|
||||
int intArgs = 0;
|
||||
for( size_t a = 0; a < descr->parameterTypes.GetLength(); a++ )
|
||||
{
|
||||
if (descr->parameterTypes[a].IsFloatType())
|
||||
hostFlags |= argBit;
|
||||
else
|
||||
intArgs++;
|
||||
argBit <<= 1;
|
||||
}
|
||||
// mark all float arguments
|
||||
int argBit = 1;
|
||||
int hostFlags = 0;
|
||||
int intArgs = 0;
|
||||
for (size_t a = 0; a < descr->parameterTypes.GetLength(); a++) {
|
||||
if (descr->parameterTypes[a].IsFloatType())
|
||||
hostFlags |= argBit;
|
||||
else
|
||||
intArgs++;
|
||||
argBit <<= 1;
|
||||
}
|
||||
|
||||
asDWORD paramBuffer[64];
|
||||
if( sysFunc->takesObjByVal )
|
||||
{
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 1;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
{
|
||||
asDWORD paramBuffer[64];
|
||||
if (sysFunc->takesObjByVal) {
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 1;
|
||||
for (asUINT n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() &&
|
||||
!descr->parameterTypes[n].IsReference()) {
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK )
|
||||
{
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
if (descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) {
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(¶mBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+spos));
|
||||
spos++;
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the value directly
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[1];
|
||||
}
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(¶mBuffer[dpos], *(void **)(args + spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char **)(args + spos));
|
||||
spos++;
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
} else {
|
||||
// Copy the value directly
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
if (descr->parameterTypes[n].GetSizeOnStackDWords() > 1)
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[1];
|
||||
}
|
||||
|
||||
context->isCallingSystemFunction = true;
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_CDECL:
|
||||
case ICC_CDECL_RETURNINMEM:
|
||||
case ICC_STDCALL:
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = CallCDeclFunction(args, paramSize<<2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD**)obj;
|
||||
retQW = CallThisCallFunction(obj, args, paramSize<<2, vftable[asDWORD(func)>>2], hostFlags);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = CallThisCallFunction_objLast(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = CallThisCallFunction(obj, args, paramSize<<2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
context->isCallingSystemFunction = false;
|
||||
context->isCallingSystemFunction = true;
|
||||
switch (callConv) {
|
||||
case ICC_CDECL:
|
||||
case ICC_CDECL_RETURNINMEM:
|
||||
case ICC_STDCALL:
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = CallCDeclFunction(args, paramSize << 2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
retQW = CallThisCallFunction(obj, args, paramSize << 2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asDWORD **)obj;
|
||||
retQW = CallThisCallFunction(obj, args, paramSize << 2, vftable[asDWORD(func) >> 2], hostFlags);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = CallThisCallFunction_objLast(obj, args, paramSize << 2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = CallThisCallFunction(obj, args, paramSize << 2, (asDWORD)func, hostFlags);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
context->isCallingSystemFunction = false;
|
||||
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( sysFunc->takesObjByVal )
|
||||
{
|
||||
// Need to free the complex objects passed by value
|
||||
args = context->regs.stackPointer;
|
||||
if( callConv >= (int)ICC_THISCALL && !objectPointer )
|
||||
args++;
|
||||
if (sysFunc->takesObjByVal) {
|
||||
// Need to free the complex objects passed by value
|
||||
args = context->regs.stackPointer;
|
||||
if (callConv >= (int)ICC_THISCALL && !objectPointer)
|
||||
args++;
|
||||
|
||||
int spos = 0;
|
||||
for( size_t n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( descr->parameterTypes[n].IsObject() &&
|
||||
!descr->parameterTypes[n].IsReference() &&
|
||||
(descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK) )
|
||||
{
|
||||
void *obj = (void*)args[spos++];
|
||||
asSTypeBehaviour *beh = &descr->parameterTypes[n].GetObjectType()->beh;
|
||||
if( beh->destruct )
|
||||
engine->CallObjectMethod(obj, beh->destruct);
|
||||
int spos = 0;
|
||||
for (size_t n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsReference() &&
|
||||
(descr->parameterTypes[n].GetObjectType()->flags & COMPLEX_MASK)) {
|
||||
void *obj = (void *)args[spos++];
|
||||
asSTypeBehaviour *beh = &descr->parameterTypes[n].GetObjectType()->beh;
|
||||
if (beh->destruct)
|
||||
engine->CallObjectMethod(obj, beh->destruct);
|
||||
|
||||
engine->CallFree(obj);
|
||||
}
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
engine->CallFree(obj);
|
||||
} else
|
||||
spos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store the returned value in our stack
|
||||
if( descr->returnType.IsObject() && !descr->returnType.IsReference() )
|
||||
{
|
||||
if( descr->returnType.IsObjectHandle() )
|
||||
{
|
||||
context->regs.objectRegister = (void*)(asDWORD)retQW;
|
||||
// Store the returned value in our stack
|
||||
if (descr->returnType.IsObject() && !descr->returnType.IsReference()) {
|
||||
if (descr->returnType.IsObjectHandle()) {
|
||||
context->regs.objectRegister = (void *)(asDWORD)retQW;
|
||||
|
||||
if( sysFunc->returnAutoHandle && context->regs.objectRegister )
|
||||
engine->CallObjectMethod(context->regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// Copy the returned value to the pointer sent by the script engine
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)retPointer = (asDWORD)retQW;
|
||||
else
|
||||
*(asQWORD*)retPointer = retQW;
|
||||
}
|
||||
if (sysFunc->returnAutoHandle && context->regs.objectRegister)
|
||||
engine->CallObjectMethod(context->regs.objectRegister, descr->returnType.GetObjectType()->beh.addref);
|
||||
} else {
|
||||
if (!sysFunc->hostReturnInMemory) {
|
||||
// Copy the returned value to the pointer sent by the script engine
|
||||
if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)retPointer = (asDWORD)retQW;
|
||||
else
|
||||
*(asQWORD *)retPointer = retQW;
|
||||
}
|
||||
|
||||
// Store the object in the register
|
||||
context->regs.objectRegister = retPointer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store value in valueRegister
|
||||
if( sysFunc->hostReturnFloat )
|
||||
{
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)&context->regs.valueRegister = GetReturnedFloat();
|
||||
else
|
||||
context->regs.valueRegister = GetReturnedDouble();
|
||||
}
|
||||
else if( sysFunc->hostReturnSize == 1 )
|
||||
*(asDWORD*)&context->regs.valueRegister = (asDWORD)retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
}
|
||||
// Store the object in the register
|
||||
context->regs.objectRegister = retPointer;
|
||||
}
|
||||
} else {
|
||||
// Store value in valueRegister
|
||||
if (sysFunc->hostReturnFloat) {
|
||||
if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)&context->regs.valueRegister = GetReturnedFloat();
|
||||
else
|
||||
context->regs.valueRegister = GetReturnedDouble();
|
||||
} else if (sysFunc->hostReturnSize == 1)
|
||||
*(asDWORD *)&context->regs.valueRegister = (asDWORD)retQW;
|
||||
else
|
||||
context->regs.valueRegister = retQW;
|
||||
}
|
||||
|
||||
if( sysFunc->hasAutoHandles )
|
||||
{
|
||||
args = context->regs.stackPointer;
|
||||
if( callConv >= ICC_THISCALL && !objectPointer )
|
||||
args++;
|
||||
if (sysFunc->hasAutoHandles) {
|
||||
args = context->regs.stackPointer;
|
||||
if (callConv >= ICC_THISCALL && !objectPointer)
|
||||
args++;
|
||||
|
||||
int spos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( sysFunc->paramAutoHandles[n] && args[spos] )
|
||||
{
|
||||
// Call the release method on the type
|
||||
engine->CallObjectMethod((void*)args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
|
||||
args[spos] = 0;
|
||||
}
|
||||
int spos = 0;
|
||||
for (asUINT n = 0; n < descr->parameterTypes.GetLength(); n++) {
|
||||
if (sysFunc->paramAutoHandles[n] && args[spos]) {
|
||||
// Call the release method on the type
|
||||
engine->CallObjectMethod((void *)args[spos], descr->parameterTypes[n].GetObjectType()->beh.release);
|
||||
args[spos] = 0;
|
||||
}
|
||||
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
spos++;
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
if (descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() &&
|
||||
!descr->parameterTypes[n].IsReference())
|
||||
spos++;
|
||||
else
|
||||
spos += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
|
||||
return popSize;
|
||||
return popSize;
|
||||
}
|
||||
|
||||
asm(
|
||||
" .text\n"
|
||||
//" .align 2\n"
|
||||
" .global mipsFunc\n"
|
||||
" .ent mipsFunc\n"
|
||||
"mipsFunc:\n"
|
||||
//" .frame $fp,64,$31 # vars= 0, regs= 0/0, args= 0, gp= 0\n"
|
||||
//" .mask 0x00000000,0\n"
|
||||
//" .fmask 0x00000000,0\n"
|
||||
" .set noreorder\n"
|
||||
" .set nomacro\n"
|
||||
// align the stack frame to 8 bytes
|
||||
" addiu $12, $6, 7\n"
|
||||
" li $13, -8\n" // 0xfffffffffffffffc
|
||||
" and $12, $12, $13\n" // t4 holds the size of the argument block
|
||||
// and add 8 bytes for the return pointer and s0 backup
|
||||
" addiu $13, $12, 8\n" // t5 holds the total size of the stack frame (including return pointer)
|
||||
// save the s0 register (so we can use it to remember where our return pointer is lives)
|
||||
" sw $16, -4($sp)\n" // store the s0 register (so we can use it to remember how big our stack frame is)
|
||||
// push the stack
|
||||
" subu $sp, $sp, $13\n"
|
||||
// find the return address, place in s0
|
||||
" addu $16, $sp, $12\n"
|
||||
// store the return pointer
|
||||
" sw $31, 0($16)\n"
|
||||
asm(" .text\n"
|
||||
//" .align 2\n"
|
||||
" .global mipsFunc\n"
|
||||
" .ent mipsFunc\n"
|
||||
"mipsFunc:\n"
|
||||
//" .frame $fp,64,$31 # vars= 0, regs= 0/0, args= 0, gp= 0\n"
|
||||
//" .mask 0x00000000,0\n"
|
||||
//" .fmask 0x00000000,0\n"
|
||||
" .set noreorder\n"
|
||||
" .set nomacro\n"
|
||||
// align the stack frame to 8 bytes
|
||||
" addiu $12, $6, 7\n"
|
||||
" li $13, -8\n" // 0xfffffffffffffffc
|
||||
" and $12, $12, $13\n" // t4 holds the size of the argument block
|
||||
// and add 8 bytes for the return pointer and s0 backup
|
||||
" addiu $13, $12, 8\n" // t5 holds the total size of the stack frame (including return pointer)
|
||||
// save the s0 register (so we can use it to remember where our return pointer is lives)
|
||||
" sw $16, -4($sp)\n" // store the s0 register (so we can use it to remember how big our stack frame
|
||||
// is)
|
||||
// push the stack
|
||||
" subu $sp, $sp, $13\n"
|
||||
// find the return address, place in s0
|
||||
" addu $16, $sp, $12\n"
|
||||
// store the return pointer
|
||||
" sw $31, 0($16)\n"
|
||||
|
||||
// backup our function params
|
||||
" addiu $2, $7, 0\n"
|
||||
" addiu $3, $6, 0\n"
|
||||
// backup our function params
|
||||
" addiu $2, $7, 0\n"
|
||||
" addiu $3, $6, 0\n"
|
||||
|
||||
// get global mipsArgs[] array pointer
|
||||
//" lui $15, %hi(mipsArgs)\n"
|
||||
//" addiu $15, $15, %lo(mipsArgs)\n"
|
||||
// we'll use the macro instead because SN Systems doesnt like %hi/%lo
|
||||
".set macro\n"
|
||||
" la $15, mipsArgs\n"
|
||||
".set nomacro\n"
|
||||
// load register params
|
||||
" lw $4, 0($15)\n"
|
||||
" lw $5, 4($15)\n"
|
||||
" lw $6, 8($15)\n"
|
||||
" lw $7, 12($15)\n"
|
||||
" lw $8, 16($15)\n"
|
||||
" lw $9, 20($15)\n"
|
||||
" lw $10, 24($15)\n"
|
||||
" lw $11, 28($15)\n"
|
||||
// get global mipsArgs[] array pointer
|
||||
//" lui $15, %hi(mipsArgs)\n"
|
||||
//" addiu $15, $15, %lo(mipsArgs)\n"
|
||||
// we'll use the macro instead because SN Systems doesnt like %hi/%lo
|
||||
".set macro\n"
|
||||
" la $15, mipsArgs\n"
|
||||
".set nomacro\n"
|
||||
// load register params
|
||||
" lw $4, 0($15)\n"
|
||||
" lw $5, 4($15)\n"
|
||||
" lw $6, 8($15)\n"
|
||||
" lw $7, 12($15)\n"
|
||||
" lw $8, 16($15)\n"
|
||||
" lw $9, 20($15)\n"
|
||||
" lw $10, 24($15)\n"
|
||||
" lw $11, 28($15)\n"
|
||||
|
||||
// load float params
|
||||
" lwc1 $f12, 32($15)\n"
|
||||
" lwc1 $f13, 36($15)\n"
|
||||
" lwc1 $f14, 40($15)\n"
|
||||
" lwc1 $f15, 44($15)\n"
|
||||
" lwc1 $f16, 48($15)\n"
|
||||
" lwc1 $f17, 52($15)\n"
|
||||
" lwc1 $f18, 56($15)\n"
|
||||
" lwc1 $f19, 60($15)\n"
|
||||
// load float params
|
||||
" lwc1 $f12, 32($15)\n"
|
||||
" lwc1 $f13, 36($15)\n"
|
||||
" lwc1 $f14, 40($15)\n"
|
||||
" lwc1 $f15, 44($15)\n"
|
||||
" lwc1 $f16, 48($15)\n"
|
||||
" lwc1 $f17, 52($15)\n"
|
||||
" lwc1 $f18, 56($15)\n"
|
||||
" lwc1 $f19, 60($15)\n"
|
||||
|
||||
// skip stack paramaters if there are none
|
||||
" beq $3, $0, andCall\n"
|
||||
// skip stack paramaters if there are none
|
||||
" beq $3, $0, andCall\n"
|
||||
|
||||
// push stack paramaters
|
||||
" addiu $15, $15, 64\n"
|
||||
"pushArgs:\n"
|
||||
" addiu $3, -4\n"
|
||||
// load from $15 + stack bytes ($3)
|
||||
" addu $14, $15, $3\n"
|
||||
" lw $14, 0($14)\n"
|
||||
// store to $sp + stack bytes ($3)
|
||||
" addu $13, $sp, $3\n"
|
||||
" sw $14, 0($13)\n"
|
||||
// if there are more, loop...
|
||||
" bne $3, $0, pushArgs\n"
|
||||
" nop\n"
|
||||
// push stack paramaters
|
||||
" addiu $15, $15, 64\n"
|
||||
"pushArgs:\n"
|
||||
" addiu $3, -4\n"
|
||||
// load from $15 + stack bytes ($3)
|
||||
" addu $14, $15, $3\n"
|
||||
" lw $14, 0($14)\n"
|
||||
// store to $sp + stack bytes ($3)
|
||||
" addu $13, $sp, $3\n"
|
||||
" sw $14, 0($13)\n"
|
||||
// if there are more, loop...
|
||||
" bne $3, $0, pushArgs\n"
|
||||
" nop\n"
|
||||
|
||||
// and call the function
|
||||
"andCall:\n"
|
||||
" jal $2\n"
|
||||
" nop\n"
|
||||
// and call the function
|
||||
"andCall:\n"
|
||||
" jal $2\n"
|
||||
" nop\n"
|
||||
|
||||
// restore the return pointer
|
||||
" lw $31, 0($16)\n"
|
||||
// pop the stack pointer (remembering the return pointer was 8 bytes below the top)
|
||||
" addiu $sp, $16, 8\n"
|
||||
// and return from the function
|
||||
" jr $31\n"
|
||||
// restore the s0 register (in the branch delay slot)
|
||||
" lw $16, -4($sp)\n"
|
||||
" .set macro\n"
|
||||
" .set reorder\n"
|
||||
" .end mipsFunc\n"
|
||||
" .size mipsFunc, .-mipsFunc\n"
|
||||
);
|
||||
// restore the return pointer
|
||||
" lw $31, 0($16)\n"
|
||||
// pop the stack pointer (remembering the return pointer was 8 bytes below the top)
|
||||
" addiu $sp, $16, 8\n"
|
||||
// and return from the function
|
||||
" jr $31\n"
|
||||
// restore the s0 register (in the branch delay slot)
|
||||
" lw $16, -4($sp)\n"
|
||||
" .set macro\n"
|
||||
" .set reorder\n"
|
||||
" .end mipsFunc\n"
|
||||
" .size mipsFunc, .-mipsFunc\n");
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_MIPS
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user