@Anders
Here is the suggested PPC template from the AngelScript forum:
Here is how the code *could* look, like a rough draft or so (not yet complete, but)
// Loads all data into the correct places and calls the function.
// intArgSize is the size in bytes for how much data to put in int registers
// floatArgSize is the size in bytes for how much data to put in float registers
// stackArgSize is the size in bytes for how much data to put on the callstack
extern "C" asQWORD ppcFunc(int intArgSize, int floatArgSize, int stackArgSize, asDWORD func)
{
asQWORD result;
asDWORD *args = ppcArgs;
__asm__ (
"\tmr r27,%1\n" // intArgSize
"\tmr r28,%2\n" // floatArgSize
"\tmr r29,%3\n" // stackArgSize
"\tmr r30,%4\n" // args pointer
"\tmr r31,%5\n" // func pointer
#define LOAD_WORD(_reg,_off) "\tcmpwi r27,"#_off"\n" "\tble L"#_reg"\n" "\tlwz "#_reg","#_off"(r30)\n" "L"#_reg":\n"
LOAD_WORD(r3,0)
LOAD_WORD(r4,4)
LOAD_WORD(r5,8)
LOAD_WORD(r6,12)
LOAD_WORD(r7,16)
LOAD_WORD(r8,20)
LOAD_WORD(r9,24)
LOAD_WORD(r10,28)
"\taddi r30,r30,32\n"
#define LOAD_DOUBLE(_reg,_off) "\tcmpwi r28,"#_off"\n" "\tble L"#_reg"\n" "\tlfd "#_reg",0(r30)\n" "L"#_reg":\n"
LOAD_DOUBLE(f0,0)
LOAD_DOUBLE(f1,8)
LOAD_DOUBLE(f2,16)
LOAD_DOUBLE(f3,24)
LOAD_DOUBLE(f4,32)
LOAD_DOUBLE(f5,40)
LOAD_DOUBLE(f6,48)
LOAD_DOUBLE(f7,52)
LOAD_DOUBLE(f8,60)
LOAD_DOUBLE(f9,68)
LOAD_DOUBLE(f10,76)
LOAD_DOUBLE(f11,84)
LOAD_DOUBLE(f12,92)
LOAD_DOUBLE(f13,100)
LOAD_DOUBLE(f14,108)
"\taddi r30,r30,96\n"
// TODO: set up stack frame
// TODO: load r29 bytes from r30
-"\tbl r31\n"
+"\tmtctr r31\n"
+\tbctr\n"
"\tmr %0,r3\n"
// TODO: take down stack frame
/* outputs: */ : "=&r" (result)
/* inputs: */ : "r" (intArgSize), "r" (floatArgSize), "r" (stackArgSize), "r" (args), "r" (func)
/* clobbers: */ : "memory");
return result;
/*
* "=&r" (result) means: 'result' is written on (the '='), it's any GP
* register (the 'r'), and it must not be the same as
* any of the input registers (the '&').
* "r" (func) means: 'func' is any GP reg
*
* "memory" in the 'clobbers' section means that gcc will make
* sure that anything that should be in memory IS there
* before calling this routine.
*/
Could you help me understand how this is going to work.
"According to the Mac OS X ABI Function Call Guide: 32-bit PowerPC Function Calling Conventions" (url below), for each floating point register used, a GPR register is skipped.
For example, if a routine such as "void foo(int parm1, double parm2 , int parm 3)" is called, the parameters would be passed as GPR3=parm1, FPR1=parm2, GPR6=parm3, because for each FPR used, a GPR is skipped. Since parm2 is a double, GPR4 & GPR5 are skipped.
It appears to me that the template above would pass parm3 in GPR4, which would not be understood by the foo routine.
What am I misunderstanding ?
thanks
pecan
http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-SW20
cf., "foo(...)" example almost at bottom of page.