🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

AngelScript and Mac OS X

Started by
35 comments, last by afb 18 years, 4 months ago

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 callstackextern "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"            "\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.   */}

Advertisement

Oops, that "bl r31" should be a "mtctr r31\nbctr"

Copy and paste striketh again...
So the PPC ABI is similar to that of the Dreamcast? With floats passed in the float registers and ints in the GP registers, and whatever doesn't fit in the registers is pushed on the stack? You could probably take a few hints from as_callfunc_sh4.cpp on how this could be implemented.

It seems that the AMD64 processors also work in a similar way.

It's both unfortunate and fortunate. Unfortunate, because the overhead for calling functions with the native calling convention will be greater for this kind of ABI. Fortunate because it means that I do not have to change the script stack to use 64bit words for all types, only for the pointers.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I believe this is the x64 fastcall calling convention.
Quote: Original post by WitchLord
So the PPC ABI is similar to that of the Dreamcast? With floats passed in the float registers and ints in the GP registers, and whatever doesn't fit in the registers is pushed on the stack? You could probably take a few hints from as_callfunc_sh4.cpp on how this could be implemented.


Yes, I lifted parts of that for a quick start...

Main difference is that there are both float (4) and double (8) params.
Not sure how you would return a "double" with the current API, but anyway.
BTW:
A great old book about everything PPC is:
"Optimizing PowerPC Code" by Gary Kacmarcik
Quote: Not sure how you would return a "double" with the current API, but anyway.


Hmm, simple enough: write the FP reg to memory, then load the GP regs from it.

This topic is closed to new replies.

Advertisement