Advertisement

Angelscript on Raspberry Pi

Started by November 10, 2012 01:31 AM
130 comments, last by WitchLord 11 years, 10 months ago
The if( sysFunc->takesObjByVal ) condition is an optimization. On iOS and Windows Phone, the argument list doesn't need any modifications, unless one or more of the arguments are of an object type. In your case, just as for ANDROID, the argument list needs to be prepared properly in almost all cases, so you shouldn't check this condition.

No, you'll want to add the verifications for floats within the loop that starts on line 113 in as_callfunc_arm.cpp, i.e.


for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
{
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
{
// leave this as is. Just make sure the code that is there for ANDROID is also included for Raspberry Pi
}
else if( descr->parameterTypes[n].IsFloatType() && (countFloats < 15 || freeSingleFloat != -1) )
{
// add the treatment for floats here
}
else if( descr->parameterTypes[n].IsDoubleType() && countFloats < 14 )
{
// add the treatment for doubles here
}
else
{
// leave this as is. This is where the integers are treated, and the existing code should work. Just make sure the code that is there for ANDROID is also included for Raspberry Pi
}
}


In my pseudo code I included the genericArgs array by mistake. The paramBuffer that is already existing in the as_callfunc_arm.cpp is the one that will hold the integer arguments. You don't need to change it.

Once you have the code to separate the float and double args working, the floatArgs array needs to be passed to the assembler routines where the assembler routines should load the "d" registers with contents of the floatArgs.

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

Ok, it´s clear now. So just for ease of development, I could define AS_ANDROID at the beginning, right?
Advertisement
Yes, I believe you can take that approach. Or, you can simply remove the checks for AS_ANDROID.

When I merge the final solution I'll need to keep conditions specific for Raspberry Pi, but as I said before you don't need to concern yourself with this at the moment. Let's just make it work for RPi first, then I'll figure out how to unify the code for all platforms.

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

The float argument handling part is kind of done. I think it is not reordering the args the way the disassemblies showed, but for now I´m just trying to pass 1 float arg so the lack of reordering doesn´t matter. I´m stuck with this: which opcode should I use to pass the values from the array to the "s" registers? (Assuming that the array is being assigned to r5 at the beginning of the asm code.)
Just for the record, ARM CPUs do have different registers for integer operations and floating point calculations. I think float registers are also used for the NEON sse-like instruction set.

You can find that kind of information in ARM's site (with nice colors n' all :D ) I did a presentation about those a few months ago.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

Yes, we found that info the hard way...disassembly after disassembly after disassembly,,, wacko.png
Right now I have an asm function that is passed 4 args, the fourth being the pointer to the float array args of the actual system function. I need to know how to store (in asm) the values of the array in the different float registers ("s" registers).

The problem is... I know about 0.000001e-19 % of ASM, so I´m kind of doing this "using the force"...laugh.png
Advertisement
This is another use for disassembly. See how the compiler does it, and then copy that.

For example:


void TargetFunc(double d0, double d1, double d2, double d3, double d4, double d5, double d6, double, d7) { printf("",d0,d1,d2,d3,d4,d5,d6,d7); }

void DisassembleMe(asDWORD *floatArgs)
{
TargetFunc(*(double*)&floatArgs[0],
*(double*)&floatArgs[2],
*(double*)&floatArgs[4],
*(double*)&floatArgs[6],
*(double*)&floatArgs[8],
*(double*)&floatArgs[10],
*(double*)&floatArgs[12],
*(double*)&floatArgs[14]);
}


I don't know much about assembly either. I wouldn't dream about attempting to write an assembly function from scratch. All the assembler routines I've written so far is from piecing together sequences I've gathered from disassemblies.

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

Nice! I can´t believe I didn´t think of using the disassemblies... Now the correct float values are reaching the system function correctly, but I´m getting a seg fault afterwards. Should be simple to fix thou since I know exactly where to look.
I´ve got the code for passing floats/doubles to their corresponding registers in place in working (only for CDECL, but once I´ve got this working the other calling conventions should be easier to implement). Now there seems to be a problem with the way args that don´t fit in the basic registers (s0-s15, d0-d7, r0-r3) are pushed into the stack. I have some questions about your code:

You have avariable named paramSize, which is created like this:

int paramSize = sysFunc->paramSize;

But just before the first big loop (and without having used it) you set paramSize = 0; Is that on purpose?

Also, what´s the reason for this:

// Keep a free location at the beginning
args = &paramBuffer[2];

(Just after the first big loop).

EDIT: Now I see where the stack related problem is. When a float (or double) value can´t find a free "s" or "d" register, it gets pushed into the stack. But if it is in the first three "places" of the stack, the ASM routine tries to push it´s value into one of the "r" registers. Time for more disassembling to find out how the compiler handles this cases!
The paramSize gives the number of dwords present in the paramBuffer. As such, the float args that are placed in the registers shouldn't increase the paramSize.

args = &paramBuffer[2], is because in some situations a pair of hidden arguments are passed before the explicit args, e.g. when an object is returned by value, then a pointer to the memory where that object should be initialized is passed before all other args, and when calling an object method, then the object pointer is also passed as a hidden argument before the rest.

Sounds like you're making good progress. I look forward to adding Raspberry Pi as yet another supported platform :)

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

This topic is closed to new replies.

Advertisement