Sign in to follow this  
Tzarls

Angelscript on Raspberry Pi

Recommended Posts

Tzarls    1411
Yes, we found that info the hard way...disassembly after disassembly after disassembly,,, [img]http://public.gamedev.net//public/style_emoticons/default/wacko.png[/img]
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"...[img]http://public.gamedev.net//public/style_emoticons/default/laugh.png[/img]

Share this post


Link to post
Share on other sites
WitchLord    4677
This is another use for disassembly. See how the compiler does it, and then copy that.

For example:

[code]
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]);
}
[/code]

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.

Share this post


Link to post
Share on other sites
Tzarls    1411
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.

Share this post


Link to post
Share on other sites
Tzarls    1411
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! Edited by Tzarls

Share this post


Link to post
Share on other sites
WitchLord    4677
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 :)

Share this post


Link to post
Share on other sites
Tzarls    1411
CDECL at 90%. I need to make some adjustments for when objects are passed by value, but passing all other args work fine, be it using "r", "s" or "d" registers or the stack. I´ve had to make some important changes to the existing code, so instead or trying to make it fit with the original file, I´d suggest giving it its own... in fact, I´m really curious about how the current implementation is working with Android (or iOS). Has anyone reported native calling conventions really working for those cases? Edited by Tzarls

Share this post


Link to post
Share on other sites
WitchLord    4677
Unfortunately I do not have any development environment to certify that the code is actually working 100% on Android and iOS, but there are plenty of developers that use AngelScript on these platforms and so far I haven't heard of any problems.

If the code for Raspberry Pi becomes sufficiently different I'll probably do as you suggested and keep it separate from the rest.

Share this post


Link to post
Share on other sites
Tzarls    1411
Andreas:

In the code section that copies the passed object to the paramBuffer, you have this:

[CODE]// Copy the object's memory to the buffer
memcpy(&paramBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());[/CODE]

Since you aren´t performing any kind of bounds checking, this could cause problems if the object to be copied exceeds the capacity of the array... or maybe I´m missing something? In this kind of situations maybe the lib could raise an internal exception when something like this happens.

Share this post


Link to post
Share on other sites
Tzarls    1411
More questions:

How do I "trigger" the usage of the different calling conventions? I mean:

[CODE]switch( callConv )
{
case ICC_CDECL_RETURNINMEM: // fall through
case ICC_STDCALL_RETURNINMEM:
std::cout << "armFuncR0.\n";
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)retPointer);
break;
case ICC_CDECL: // fall through
case ICC_STDCALL:
std::cout << "armFunc.\n";
retQW = armFunc(args, paramSize<<2, func);
break;
case ICC_THISCALL: // fall through
case ICC_CDECL_OBJFIRST:
std::cout << "armFuncR0.\n";
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
break;
case ICC_THISCALL_RETURNINMEM:
std::cout << "armFuncR0R1.\n";
....[/CODE]

What kind of functions should i register in order to be able to test every possible case in the above switch? I know the "THISCALL" ones should be called by object methods, but what´s the difference between the "RETURNINMEM" and the other ones? I´ve finished porting the armFuncR0 and I´d like to test it before going on.

Also, is there any "standard" test that the code has to pass in order to safely say that the lib supports a certain platform?

Last night I had dreams with "r" registers....[img]http://public.gamedev.net//public/style_emoticons/default/wacko.png[/img] [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

Share this post


Link to post
Share on other sites
WitchLord    4677
When RETURNINMEM is used depends on the ABI. Some classes will always be returned in memory regardless of their size, others will only be returned in memory if their size is bigger than some minimum. Normally the existance of explicitly declared constructors, destructors, and or assignment operator in the class declaration will determine whether the size if of importance or not. Usually these same properties also determine how the objects are passed by value, i.e. whether they are pushed on the stack or if just a reference to the object is pushed on the stack.

In the tests/test_feature project (from the SVN) you'll find the regression test suite that I use to make sure everything works ok with each release. The tests for testing the native calling convention starts on line 325 in main.cpp. I suggest you start with those tests by commenting out all other tests before that. The tests for the native calling convention are designed to test all the aspects of the ABI and will provide you with the tests you need.

[code]
// The following tests are designed specifically to test the native calling conventions.
// These are grouped by calling convention and ordered in increasing complexity.
{
// cdecl
if( TestExecute() ) goto failed; else printf("-- TestExecute passed\n");
if( TestCDeclReturn::Test() ) goto failed; else printf("-- TestCDeclReturn passed\n");
if( TestExecute1Arg() ) goto failed; else printf("-- TestExecute1Arg passed\n");
if( TestExecute2Args() ) goto failed; else printf("-- TestExecute2Args passed\n");
if( TestExecute4Args() ) goto failed; else printf("-- TestExecute4Args passed\n");
if( TestExecute4Argsf() ) goto failed; else printf("-- TestExecute4Argsf passed\n");
if( TestExecuteMixedArgs() ) goto failed; else printf("-- TestExecuteMixedArgs passed\n");
if( TestExecute32Args() ) goto failed; else printf("-- TestExecute32Args passed\n");
if( TestExecute32MixedArgs() ) goto failed; else printf("-- TestExecute32MixedArgs passed\n");
if( TestCDecl_Class() ) goto failed; else printf("-- TestCDecl_Class passed\n");
if( TestCDecl_ClassA() ) goto failed; else printf("-- TestCDecl_ClassA passed\n");
if( TestCDecl_ClassC() ) goto failed; else printf("-- TestCDecl_ClassC passed\n");
if( TestCDecl_ClassD() ) goto failed; else printf("-- TestCDecl_ClassD passed\n");
if( TestCDecl_ClassK() ) goto failed; else printf("-- TestCDecl_ClassK passed\n");

// cdecl_objlast and cdecl_objfirst
if( TestCDeclObjLast::Test() ) goto failed; else printf("-- TestCDeclObjLast passed\n");
if( TestReturnWithCDeclObjFirst() ) goto failed; else printf("-- TestReturnWithCDeclObjFirst passed\n");

// thiscall
if( TestExecuteThis32MixedArgs() ) goto failed; else printf("-- TestExecuteThis32MixedArgs passed\n");
if( TestThiscallClass() ) goto failed; else printf("-- TestThiscallClass passed\n");
if( TestNotComplexThisCall() ) goto failed; else printf("-- TestNotComplexThisCall passed\n");
if( TestVirtualMethod() ) goto failed; else printf("-- TestVirtualMethod passed\n");
if( TestMultipleInheritance() ) goto failed; else printf("-- TestMultipleInheritance passed\n");
if( TestVirtualInheritance() ) goto failed; else printf("-- TestVirtualInheritance passed\n");

// stdcall
if( TestStdcall4Args() ) goto failed; else printf("-- TestStdcall4Args passed\n");
if( TestNotComplexStdcall() ) goto failed; else printf("-- TestNotComplexStdcall passed\n");
}
[/code] Edited by Andreas Jonsson

Share this post


Link to post
Share on other sites
Tzarls    1411
Ok, I´ll run the tests to check how I´m progressing.

Now, one more question.

[CODE]retQW = armFunc(args, paramSize<<2, func);[/CODE]

I´m having trouble with return values. When the system function returns an int, everything is fine. The problem arises when the function returns a float or a double. From the dissasemblies I´ve found that in those cases the return values are being passed back stored at registers s0 or d0 (float / double) - as opposed to when returning an int, which is stored in r0. I was wondering how do we get that value into retQW. Is it stored there automaitcally by some kind of compiler wizardry? (as a result of the "retQW = " assignment maybe?) If so, then how should we interpret the returning value? Maybe it´s some kind of alignment problem or something..... any ideas would be appreciated.

In other words..... heeeeelp! [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]

Share this post


Link to post
Share on other sites
WitchLord    4677
As I mentioned earlier. My suggestion is to do something similar to what is done in as_callfunc_x86.cpp. Simply create a separate assembler routine that copies the d0 register to r0,r1. Let's call it GetReturnedDouble(). Then call this function from CallSystemFunctionNative() after the armFunc() has returned with the following condition:

[code]
// If the return is a float value we need to get the value from the d0 register (or just s0 in case of single float)
if( sysFunc->hostReturnFloat )
retQW = GetReturnedDouble();
[/code]

You can probably get the assembler instructions for doing this by disassemblying the following C function:

[code]
asQWORD GetReturnedDouble(double dbl)
{
// Return the binary representation of the double in the qword
return *(asQWORD*)&dbl;
}
[/code]

Regards,
Andreas

Share this post


Link to post
Share on other sites
Tzarls    1411
Oh, yes, i had forgotten about your previous post regarding the x86 implementation. I have an idea which might also work - its similar but involves less conditionals and function calling. I just wanted to know if maybe there was some "hidden" compiler feature I didn´t know about... So, I guess I have all I need to get this working.... until the next problem arises! ;)

Share this post


Link to post
Share on other sites
Tzarls    1411
Andreas:

I got the returning of floats/doubles in armFunc working. Now I´ve got a problem with returning objects from armFuncR0 (it fails the TestReturnStruct () test in the test bench).

What I´ve found so far:

The system registered object is created (type point) and it is getting the correct values. The problem appears when the engine receives the created object.

CallSytemFunctionNative() reports that sysFunc->hostReturnInMemory = true and sysFunc->hostReturnSize = 1. If I just let the function exit with the usual "return retQW;", the returned struct has all its members with a value of 0. (The same happens for the rect structure).

If bejore returning I do this:

[CODE]*(asDWORD*)retPointer = (asDWORD)retQW;[/CODE]

Then the returned structure has its first member with the correct value. If I do it this way:

[CODE]*(asQWORD*)retPointer = retQW;[/CODE]

The the returned structure has its first and second members with the correct values.
Now, in the original asm file, you´ve got:

[CODE]mov r0, r3 // r0 explicitly set[/CODE]

As I understand it, this copies r3 (which holds retPointer) to r0. But then you never use r3 again, and I guess r0 is going to be overwritten with the pointer to the return struct... shouldn´t I end the asm function copying r0 back to where r3 is pointing at? Any ideas?

Share this post


Link to post
Share on other sites
WitchLord    4677
First of all. Disassembly the TestPoint() and TestRect() functions so we can see how the ABI expects these structures to be returned.

For both iOS and Android these functions return the value in memory, which is why armFuncR0. However, this may not be the case for Raspberry Pi, which is why we need to see the disassembly.

From what you say that retQW appears to hold the value, then it would seem the structure is returned in the registers rather than in memory. At least with the Point type. In this case the configuration in as_config.h needs to be changed according to the ABI for RPi.

I need to know how the RPi is being identified, i.e. what defines are given by default by gcc when compiling for RPi. Can you run the command "g++ -dM -E as_config.h" and show me the result? It should print the defines that are set after going through the as_config.h macros.

Most likely you'll find the following two in the output:

CDECL_RETURN_SIMPLE_IN_MEMORY
CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2

My guess is that the second needs to be changed to at least 3 for RPi, i.e. simple structs smaller than 3 DWORDs will be returned in registers, others will be returned in memory.

As for the question on the use of R0 in armFuncR0. This is for functions that return a value in memory. In this case the caller must pass a pointer to the memory where the return value should be placed. This pointer is passed as an implicit first argument to the function, i.e. in R0. The called function will take the pointer it receives in R0, and store the return value in that memory spot. As the memory is already populated by the called function, there is nothing to do by the caller once the function returns.

Share this post


Link to post
Share on other sites
Tzarls    1411
Disassemblies!

For this code:

[CODE]#include <iostream>
typedef unsigned long asDWORD;
struct asPoint
{
float x,y;
};
struct asRect
{
asPoint tl, br;
};
asPoint TestPoint(void)
{
asPoint p={1,2};
return p;
}
asRect TestRect(void)
{
asRect r={{3,4}, {5,6}};
return r;
}
int main()
{
asPoint t = TestPoint();
asRect t2 = TestRect();
std::cout << "X: " << t.x << ".\n";
std::cout << "Y: " << t.y << ".\n";
std::cout << "Rect X1: " << t2.br.x << ".\n";
std::cout << "Rect Y1: " << t2.br.y << ".\n";
}[/CODE]<p>
main:

[CODE]0x86e0 push {r11, lr}
0x86e4 add r11, sp, #4
0x86e8 sub sp, sp, #48 ; 0x30
0x86ec bl 0x8620 <TestPoint()>
0x86f0 vmov.f32 s14, s0
0x86f4 vmov.f32 s15, s1
0x86f8 vstr s14, [r11, #-36] ; 0xffffffdc
0x86fc vstr s15, [r11, #-32] ; 0xffffffe0
0x8700 sub r3, r11, #12
0x8704 sub r2, r11, #36 ; 0x24
0x8708 ldm r2, {r0, r1}
0x870c stm r3, {r0, r1}
0x8710 bl 0x8674 <TestRect()>
0x8714 vmov.f32 s12, s0
0x8718 vmov.f32 s13, s1
0x871c vmov.f32 s14, s2
0x8720 vmov.f32 s15, s3
0x8724 vstr s12, [r11, #-52] ; 0xffffffcc
0x8728 vstr s13, [r11, #-48] ; 0xffffffd0
0x872c vstr s14, [r11, #-44] ; 0xffffffd4
0x8730 vstr s15, [r11, #-40] ; 0xffffffd8
0x8734 sub r12, r11, #28
0x8738 sub r3, r11, #52 ; 0x34
0x873c ldm r3, {r0, r1, r2, r3}
0x8740 stm r12, {r0, r1, r2, r3}
0x8744 ldr r0, [pc, #200] ; 0x8814 <main()+308>
0x8748 ldr r1, [pc, #200] ; 0x8818 <main()+312>
0x874c bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8750 mov r3, r0
0x8754 vldr s15, [r11, #-12]
0x8758 mov r0, r3
0x875c vmov.f32 s0, s15
0x8760 bl 0x8568 <std::ostream::operator<<(float)>
0x8764 mov r3, r0
0x8768 mov r0, r3
0x876c ldr r1, [pc, #168] ; 0x881c <main()+316>
0x8770 bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8774 ldr r0, [pc, #152] ; 0x8814 <main()+308>
0x8778 ldr r1, [pc, #160] ; 0x8820 <main()+320>
0x877c bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8780 mov r3, r0
0x8784 vldr s15, [r11, #-8]
0x8788 mov r0, r3
0x878c vmov.f32 s0, s15
0x8790 bl 0x8568 <std::ostream::operator<<(float)>
0x8794 mov r3, r0
0x8798 mov r0, r3
0x879c ldr r1, [pc, #120] ; 0x881c <main()+316>
0x87a0 bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87a4 ldr r0, [pc, #104] ; 0x8814 <main()+308>
0x87a8 ldr r1, [pc, #116] ; 0x8824 <main()+324>
0x87ac bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87b0 mov r3, r0
0x87b4 vldr s15, [r11, #-20] ; 0xffffffec
0x87b8 mov r0, r3
0x87bc vmov.f32 s0, s15
0x87c0 bl 0x8568 <std::ostream::operator<<(float)>
0x87c4 mov r3, r0
0x87c8 mov r0, r3
0x87cc ldr r1, [pc, #72] ; 0x881c <main()+316>
0x87d0 bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87d4 ldr r0, [pc, #56] ; 0x8814 <main()+308>
0x87d8 ldr r1, [pc, #72] ; 0x8828 <main()+328>
0x87dc bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87e0 mov r3, r0
0x87e4 vldr s15, [r11, #-16]
0x87e8 mov r0, r3
0x87ec vmov.f32 s0, s15
0x87f0 bl 0x8568 <std::ostream::operator<<(float)>
0x87f4 mov r3, r0
0x87f8 mov r0, r3
0x87fc ldr r1, [pc, #24] ; 0x881c <main()+316>
0x8800 bl 0x8550 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8804 mov r3, #0
0x8808 mov r0, r3
0x880c sub sp, r11, #4
0x8810 pop {r11, pc}
0x8814 ldrdeq r0, [r1], -r0 ; <UNPREDICTABLE>
0x8818 andeq r8, r0, r4, lsr r9
0x881c andeq r8, r0, r8, lsr r9
0x8820 andeq r8, r0, r12, lsr r9
0x8824 andeq r8, r0, r0, asr #18
0x8828 andeq r8, r0, r12, asr #18[/CODE]

TestPoint:

[CODE]0x8620 push {r11} ; (str r11, [sp, #-4]!)
0x8624 add r11, sp, #0
0x8628 sub sp, sp, #28
0x862c ldr r2, [pc, #60] ; 0x8670 <TestPoint()+80>
0x8630 sub r3, r11, #20
0x8634 ldm r2, {r0, r1}
0x8638 stm r3, {r0, r1}
0x863c sub r3, r11, #12
0x8640 sub r2, r11, #20
0x8644 ldm r2, {r0, r1}
0x8648 stm r3, {r0, r1}
0x864c ldr r2, [r11, #-12]
0x8650 ldr r3, [r11, #-8]
0x8654 vmov s14, r2
0x8658 vmov s15, r3
0x865c vmov.f32 s0, s14
0x8660 vmov.f32 s1, s15
0x8664 add sp, r11, #0
0x8668 pop {r11}
0x866c bx lr
0x8670 andeq r8, r0, r12, lsl r9[/CODE]

TestRect:

[CODE]0x8674 push {r11} ; (str r11, [sp, #-4]!)
0x8678 add r11, sp, #0
0x867c sub sp, sp, #52 ; 0x34
0x8680 ldr r3, [pc, #84] ; 0x86dc <TestRect()+104>
0x8684 sub r12, r11, #36 ; 0x24
0x8688 ldm r3, {r0, r1, r2, r3}
0x868c stm r12, {r0, r1, r2, r3}
0x8690 sub r12, r11, #20
0x8694 sub r3, r11, #36 ; 0x24
0x8698 ldm r3, {r0, r1, r2, r3}
0x869c stm r12, {r0, r1, r2, r3}
0x86a0 ldr r0, [r11, #-20]
0x86a4 ldr r1, [r11, #-16]
0x86a8 ldr r2, [r11, #-12]
0x86ac ldr r3, [r11, #-8]
0x86b0 vmov s12, r0
0x86b4 vmov s13, r1
0x86b8 vmov s14, r2
0x86bc vmov s15, r3
0x86c0 vmov.f32 s0, s12
0x86c4 vmov.f32 s1, s13
0x86c8 vmov.f32 s2, s14
0x86cc vmov.f32 s3, s15
0x86d0 add sp, r11, #0
0x86d4 pop {r11}
0x86d8 bx lr
0x86dc andeq r8, r0, r4, lsr #18[/CODE]

As you said - it appears that values are being returned in registers. Edited by Tzarls

Share this post


Link to post
Share on other sites
Tzarls    1411
Here are the defines:
[CODE]#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)
#define __DBL_MIN_EXP__ (-1021)
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define __UINT_LEAST16_MAX__ 65535
#define _GLIBCXX_HAVE_ENOLINK 1
#define __FLT_MIN__ 1.1754943508222875e-38F
#define _GLIBCXX_WEAK_DEFINITION
#define __bswap_16(x) (__extension__ ({ unsigned short int __bsx = (x); __bswap_constant_16 (__bsx); }))
#define __UINT_LEAST8_TYPE__ unsigned char
#define _T_WCHAR_
#define __flexarr []
#define _SCHED_H 1
#define __S64_TYPE __quad_t
#define __stub_fchflags
#define __SQUAD_TYPE __quad_t
#define __INTMAX_C(c) c ## LL
#define _BSD_SIZE_T_DEFINED_
#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
#define PTHREAD_CANCELED ((void *) -1)
#define _BITS_TIME_H 1
#define CLOCK_THREAD_CPUTIME_ID 3
#define __TIME_T_TYPE __SLONGWORD_TYPE
#define __CHAR_BIT__ 8
#define _GLIBCXX_HAVE_ETIME 1
#define _GLIBCXX_USE_RANDOM_TR1 1
#define __CPU_ZERO_S(setsize,cpusetp) do __builtin_memset (cpusetp, '\0', setsize); while (0)
#define __UINT8_MAX__ 255
#define __bswap_64(x) (__extension__ ({ union { __extension__ unsigned long long int __ll; unsigned int __l[2]; } __w, __r; if (__builtin_constant_p (x)) __r.__ll = __bswap_constant_64 (x); else { __w.__ll = (x); __r.__l[0] = __bswap_32 (__w.__l[1]); __r.__l[1] = __bswap_32 (__w.__l[0]); } __r.__ll; }))
#define __WINT_MAX__ 4294967295U
#define __SIZEOF_PTHREAD_ATTR_T 36
#define _GLIBCXX_HAVE_WRITEV 1
#define _GLIBCXX_END_NAMESPACE_LDBL
#define __GLIBC_PREREQ(maj,min) ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
#define _XOPEN_SOURCE 700
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __SIZE_MAX__ 4294967295U
#define __stub_putmsg
#define __WCHAR_MAX__ 4294967295U
#define STDCALL __attribute__((stdcall))
#define pthread_cleanup_push_defer_np(routine,arg) do { __pthread_cleanup_class __clframe (routine, arg); __clframe.__defer ()
#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
#define AS_LINUX
#define SCHED_IDLE 5
#define _GLIBCXX_USE_LONG_LONG 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __DBL_DENORM_MIN__ double(4.9406564584124654e-324L)
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define __USE_BSD 1
#define __FLT_EVAL_METHOD__ 0
#define _GLIBCXX_HAVE_FMODF 1
#define _GLIBCXX_PSEUDO_VISIBILITY(V)
#define _GLIBCXX_HAVE_FMODL 1
#define __ASMNAME2(prefix,cname) __STRING (prefix) cname
#define __unix__ 1
#define _GLIBCXX_HAVE_SYS_STAT_H 1
#define _GLIBCXX_HAVE_ENOTSUP 1
#define asBC_WORDARG0(x) (*(((asWORD*)x)+1))
#define asBC_WORDARG1(x) (*(((asWORD*)x)+2))
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A)
#define SCHED_RR 2
#define __stub_setlogin
#define _GLIBCXX_PACKAGE_NAME "package-unused"
#define __FLOAT_WORD_ORDER __BYTE_ORDER
#define __ASSERT_VOID_CAST static_cast<void>
#define CLONE_NEWNET 0x40000000
#define __CPU_COUNT_S(setsize,cpusetp) __sched_cpucount (setsize, cpusetp)
#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
#define _GLIBCXX_USE_C99_COMPLEX_TR1 1
#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
#define __UINT_FAST64_MAX__ 18446744073709551615ULL
#define __SIG_ATOMIC_TYPE__ int
#define __GID_T_TYPE __U32_TYPE
#define __DBL_MIN_10_EXP__ (-307)
#define CLONE_NEWUTS 0x04000000
#define __FINITE_MATH_ONLY__ 0
#define __ARMEL__ 1
#define _GLIBCXX_USE_WCHAR_T 1
#define __STDDEF_H__
#define __pid_t_defined
#define __GNUC_PATCHLEVEL__ 3
#define _GLIBCXX_STD_C std
#define _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __UINT_FAST8_MAX__ 255
#define __LDBL_REDIR1(name,proto,alias) name proto
#define __size_t
#define _GLIBCXX_HAVE_FREXPF 1
#define _GLIBCXX_HAVE_FREXPL 1
#define __DEC64_MAX_EXP__ 385
#define _WCHAR_T_DEFINED
#define _GLIBCXX_PURE __attribute__ ((__pure__))
#define __SIZEOF_PTHREAD_CONDATTR_T 4
#define __INT8_C(c) c
#define asNEW(x) new(userAlloc(sizeof(x))) x
#define _GLIBCXX_HAVE_COSHF 1
#define _GLIBCXX_HAVE_COSHL 1
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define __stub_putpmsg
#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
#define htobe16(x) __bswap_16 (x)
#define _GLIBCXX_HAVE_ENDIAN_H 1
#define __always_inline __inline __attribute__ ((__always_inline__))
#define __SHRT_MAX__ 32767
#define __LDBL_MAX__ 1.7976931348623157e+308L
#define _GLIBCXX_USE_C99_COMPLEX 1
#define __stub_get_kernel_syms
#define _GLIBCXX_CPU_DEFINES 1
#define htobe32(x) __bswap_32 (x)
#define _GLIBCXX_HAVE_FLOAT_H 1
#define __UINT_LEAST8_MAX__ 255
#define __GXX_TYPEINFO_EQUALITY_INLINE 0
#define _GLIBCXX_HAVE_EOWNERDEAD 1
#define __ptr_t void *
#define _GLIBCXX_HAVE_MODF 1
#define _GLIBCXX_HAVE_ATANF 1
#define _GLIBCXX_HAVE_ATANL 1
#define __UINTMAX_TYPE__ long long unsigned int
#define _GLIBCXX_OS_DEFINES 1
#define __linux 1
#define __DEC32_EPSILON__ 1E-6DF
#define CPU_OR_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, |)
#define __stub_sigreturn
#define _BITS_TYPES_H 1
#define _GLIBCXX_HAVE_SYS_TIME_H 1
#define _GLIBCXX_HAVE_LIBINTL_H 1
#define __CHAR_UNSIGNED__ 1
#define __UINT32_MAX__ 4294967295U
#define __UID_T_TYPE __U32_TYPE
#define LEAVECRITICALSECTION(x) x.Leave()
#define CLONE_SIGHAND 0x00000800
#define _GLIBCXX_SYMVER 1
#define __SIZE_T
#define __LDBL_MAX_EXP__ 1024
#define _GLIBCXX_HAVE_STRTOLD 1
#define END_AS_NAMESPACE
#define _ATFILE_SOURCE 1
#define CPU_ISSET(cpu,cpusetp) __CPU_ISSET_S (cpu, sizeof (cpu_set_t), cpusetp)
#define _GLIBCXX_HAVE_LC_MESSAGES 1
#define __WINT_MIN__ 0U
#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
#define __linux__ 1
#define ALIGN(b) (((b)+3)&(~3))
#define CLONE_SETTLS 0x00080000
#define _SIZE_T_DEFINED_
#define __LDBL_REDIR_NTH(name,proto) name proto __THROW
#define __SCHAR_MAX__ 127
#define _GLIBCXX_HAVE_LIMIT_RSS 1
#define __USING_NAMESPACE_STD(name)
#define CLONE_THREAD 0x00010000
#define __WCHAR_MIN__ 0U
#define be32toh(x) __bswap_32 (x)
#define __KERNEL_STRICT_NAMES
#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }
#define __INT64_C(c) c ## LL
#define __NTH(fct) fct throw ()
#define __DBL_DIG__ 15
#define AS_NO_MEMORY_H
#define _GLIBCXX_HAVE_LIMIT_FSIZE 1
#define _POSIX_SOURCE 1
#define __SIZEOF_INT__ 4
#define __SIZEOF_POINTER__ 4
#define __attribute_used__ __attribute__ ((__used__))
#define CLOCK_REALTIME 0
#define _GLIBCXX_HAVE_POWL 1
#define __USER_LABEL_PREFIX__
#define SCHED_OTHER 0
#define _GLIBCXX_HAVE_TANL 1
#define _GLIBCXX_USE_C99_FENV_TR1 1
#define __GLIBC__ 2
#define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
#define __END_DECLS }
#define __CONCAT(x,y) x ## y
#define __bswap_constant_16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
#define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused"
#define __STDC_HOSTED__ 1
#define _LARGEFILE64_SOURCE 1
#define __LDBL_HAS_INFINITY__ 1
#define __SLONG32_TYPE long int
#define _BITS_TYPESIZES_H 1
#define _GLIBCXX_CONST __attribute__ ((__const__))
#define __EXCEPTION__
#define __GNU_LIBRARY__ 6
#define THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
#define __stub_query_module
#define __FLT_EPSILON__ 1.1920928955078125e-7F
#define __CPUELT(cpu) ((cpu) / __NCPUBITS)
#define __APCS_32__ 1
#define __GXX_WEAK__ 1
#define _GLIBCXX_HAVE_ISNANF 1
#define PTHREAD_BARRIER_SERIAL_THREAD -1
#define _GLIBCXX_HAVE_ISNANL 1
#define asBC_QWORDARG(x) (*(asQWORD*)(x+1))
#define PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
#define __SSIZE_T_TYPE __SWORD_TYPE
#define __DEV_T_TYPE __UQUAD_TYPE
#define _GLIBCXX_BEGIN_NAMESPACE_ALGO
#define __LDBL_MIN__ 2.2250738585072014e-308L
#define le32toh(x) (x)
#define __DEC32_MAX__ 9.999999E96DF
#define _GLIBCXX_HAVE_POLL 1
#define CPU_SETSIZE __CPU_SETSIZE
#define _ANSI_STDDEF_H
#define _ASSERT_H_DECLS
#define _WCHAR_T_
#define _STDDEF_H
#define __INT32_MAX__ 2147483647
#define _GLIBCXX_BEGIN_EXTERN_C extern "C" {
#define __SIZEOF_PTHREAD_COND_T 48
#define __SIZEOF_LONG__ 4
#define __STDC_IEC_559__ 1
#define __STDC_ISO_10646__ 200009L
#define __UINT16_C(c) c
#define _PREDEFS_H
#define __SIZEOF_PTHREAD_BARRIER_T 20
#define _GLIBCXX_HAVE_MODFF 1
#define _GLIBCXX_HAVE_MODFL 1
#define __DECIMAL_DIG__ 17
#define UNUSED_VAR(x) (x)=(x)
#define __USE_FORTIFY_LEVEL 0
#define CPU_EQUAL(cpusetp1,cpusetp2) __CPU_EQUAL_S (sizeof (cpu_set_t), cpusetp1, cpusetp2)
#define _GLIBCXX_HAVE_HYPOTF 1
#define _GLIBCXX_HAVE_HYPOTL 1
#define _GLIBCXX_HAVE_SYS_UIO_H 1
#define __gnu_linux__ 1
#define _LARGEFILE_SOURCE 1
#define _ENDIAN_H 1
#define __attribute_warn_unused_result__ __attribute__ ((__warn_unused_result__))
#define _GLIBCXX_USE_LFS 1
#define _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1
#define __ARM_PCS_VFP 1
#define __UQUAD_TYPE __u_quad_t
#define _GLIBCXX_HAVE_LOCALE_H 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define _GLIBCXX_HAVE_FABSF 1
#define _GLIBCXX_HAVE_FABSL 1
#define __THROW throw ()
#define _GLIBCXX_HAVE_POWF 1
#define __GLIBC_HAVE_LONG_LONG 1
#define ___int_wchar_t_h
#define _T_PTRDIFF
#define __GNUC__ 4
#define __GXX_RTTI 1
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define CLONE_FILES 0x00000400
#define __timespec_defined 1
#define PTHREAD_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
#define __OFF64_T_TYPE __SQUAD_TYPE
#define ANGELSCRIPT_H
#define _GLIBCXX_HAVE_STRERROR_L 1
#define VALUE_OF_BOOLEAN_TRUE 1
#define _GLIBCXX_HAVE_STRERROR_R 1
#define __FLT_HAS_DENORM__ 1
#define __SIZEOF_LONG_DOUBLE__ 8
#define AS_METHOD_AMBIGUITY_CAST(t) static_cast<t >
#define assert_perror(errnum) (!(errnum) ? __ASSERT_VOID_CAST (0) : __assert_perror_fail ((errnum), __FILE__, __LINE__, __ASSERT_FUNCTION))
#define __USE_SVID 1
#define _GLIBCXX_RES_LIMITS 1
#define __LDBL_REDIR1_NTH(name,proto,alias) name proto __THROW
#define __BIGGEST_ALIGNMENT__ 8
#define __defined_schedparam 1
#define _GLIBCXX_NAMESPACE_LDBL
#define __USE_ISOC95 1
#define _TIME_H 1
#define __USE_ISOC99 1
#define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
#define _GLIBCXX_HAVE_WCHAR_H 1
#define _GLIBCXX_HAVE_S_ISREG 1
#define _GLIBCXX_HAVE_ICONV 1
#define __DBL_MAX__ double(1.7976931348623157e+308L)
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
#define asMETHODPR(c,m,p,r) asSMethodPtr<sizeof(void (c::*)())>::Convert(AS_METHOD_AMBIGUITY_CAST(r (c::*)p)(&c::m))
#define sched_priority __sched_priority
#define _GLIBCXX_STDIO_SEEK_CUR 1
#define __INT_FAST32_MAX__ 2147483647
#define __DBL_HAS_INFINITY__ 1
#define _GLIBCXX_STDIO_EOF -1
#define __SIZEOF_PTHREAD_MUTEX_T 24
#define __USE_LARGEFILE 1
#define _GLIBCXX_HAVE_ETXTBSY 1
#define __INT64_MAX__ 9223372036854775807LL
#define _GLIBCXX_END_NAMESPACE_ALGO
#define __USE_XOPEN 1
#define __SIZEOF_PTHREAD_RWLOCK_T 32
#define CLONE_NEWNS 0x00020000
#define __USE_XOPEN2K 1
#define __DEC32_MIN_EXP__ (-94)
#define SCHED_FIFO 1
#define __DADDR_T_TYPE __S32_TYPE
#define __THUMB_INTERWORK__ 1
#define __END_NAMESPACE_C99
#define _GLIBCXX_HAVE_EPROTO 1
#define _GLIBCXX_HAVE_LINUX_FUTEX 1
#define __CPU_ISSET_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu < 8 * (setsize) ? ((((__const __cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] & __CPUMASK (__cpu))) != 0 : 0; }))
#define _GLIBCXX_HAVE_SINCOSF 1
#define CPU_COUNT_S(setsize,cpusetp) __CPU_COUNT_S (setsize, cpusetp)
#define _GLIBCXX_HAVE_SINCOSL 1
#define __FD_SETSIZE 1024
#define __attribute_format_strfmon__(a,b) __attribute__ ((__format__ (__strfmon__, a, b)))
#define __INT_FAST16_TYPE__ int
#define _SIZE_T_DEFINED
#define _GLIBCXX_HAVE_GETIPINFO 1
#define _WCHAR_T_DEFINED_
#define _GLIBCXX_PTRDIFF_T_IS_INT 1
#define __USE_POSIX199506 1
#define _FEATURES_H 1
#define __LDBL_HAS_DENORM__ 1
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#define CLONE_PARENT 0x00008000
#define asBC_DWORDARG(x) (asDWORD(*(x+1)))
#define __stub_getmsg
#define __stub_fattach
#define __cplusplus 1
#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
#define __INT_LEAST32_MAX__ 2147483647
#define _GCC_WRAP_STDINT_H
#define __DEC32_MIN__ 1E-95DF
#define _GLIBCXX_HAVE_SYS_IPC_H 1
#define __DEPRECATED 1
#define __S32_TYPE int
#define __cleanup_fct_attribute
#define __glibc_unlikely(cond) __builtin_expect((cond), 0)
#define CPU_ALLOC(count) __CPU_ALLOC (count)
#define __DBL_MAX_EXP__ 1024
#define _GLIBCXX_EXTERN_TEMPLATE 1
#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0 } } }
#define _BITS_WCHAR_H 1
#define __DEC128_EPSILON__ 1E-33DL
#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
#define _GLIBCXX_HAVE_ECANCELED 1
#define PDP_ENDIAN __PDP_ENDIAN
#define _GLIBCXX_HAVE_ATAN2F 1
#define __PTRDIFF_MAX__ 2147483647
#define asFUNCTION(f) asFunctionPtr(f)
#define asDELETE(ptr,x) {void *tmp = ptr; (ptr)->~x(); userFree(tmp);}
#define asBC_PTRARG(x) (*(asPWORD*)(x+1))
#define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1
#define _GLIBCXX_HAVE_ATAN2L 1
#define TRYENTERCRITICALSECTION(x) x.TryEnter()
#define __bounded
#define __USECONDS_T_TYPE __U32_TYPE
#define __BEGIN_NAMESPACE_STD
#define BCARG_W(b) ((asWORD*)&(b)[1])
#define __OFF_T_TYPE __SLONGWORD_TYPE
#define PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
#define ACQUIREEXCLUSIVE(x) x.AcquireExclusive()
#define __GNUG__ 4
#define _T_WCHAR
#define __INO_T_TYPE __ULONGWORD_TYPE
#define __LONG_LONG_MAX__ 9223372036854775807LL
#define __SIZEOF_SIZE_T__ 4
#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
#define __GLIBCXX__ 20121011
#define _WCHAR_T
#define PTHREAD_MUTEX_INITIALIZER { { 0, 0, 0, 0, 0, { 0 } } }
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
#define __SIZEOF_WINT_T__ 4
#define __NO_CTYPE 1
#define __CORRECT_ISO_CPP_STRING_H_PROTO
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
#define __U16_TYPE unsigned short int
#define _GLIBCXX_HAVE_SYS_PARAM_H 1
#define _GCC_WCHAR_T
#define BCARG_PTR(b) ((asPWORD*)&(b)[1])
#define pthread_cleanup_push(routine,arg) do { __pthread_cleanup_class __clframe (routine, arg)
#define _PTRDIFF_T
#define __ptrvalue
#define _GLIBCXX_HOSTED 1
#define __GXX_ABI_VERSION 1002
#define _GLIBCXX_HAS_GTHREADS 1
#define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#define __USE_GNU 1
#define __FLT_MIN_EXP__ (-125)
#define _GLIBCXX_HAVE_ENODATA 1
#define PTHREAD_RWLOCK_INITIALIZER { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
#define __CPU_EQUAL_S(setsize,cpusetp1,cpusetp2) (__builtin_memcmp (cpusetp1, cpusetp2, setsize) == 0)
#define _GLIBCXX_USE_SCHED_YIELD 1
#define __stub_create_module
#define __extern_always_inline extern __always_inline __attribute__ ((__gnu_inline__, __artificial__))
#define __PTRDIFF_T
#define _GLIBCXX_HAVE_FINITEF 1
#define _GLIBCXX_HAVE_FINITEL 1
#define _GLIBCXX_HAVE_SINHF 1
#define _GLIBCXX_HAVE_SINHL 1
#define __INT_FAST64_TYPE__ long long int
#define _GLIBCXX_HAVE_SQRTF 1
#define _GLIBCXX_HAVE_SQRTL 1
#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
#define asBCTYPE_rW_PTR_ARG asBCTYPE_rW_DW_ARG
#define __DBL_MIN__ double(2.2250738585072014e-308L)
#define _GLIBCXX_HAVE_SYS_SEM_H 1
#define __CPU_CLR_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu < 8 * (setsize) ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] &= ~__CPUMASK (__cpu)) : 0; }))
#define __cpu_set_t_defined
#define _GLIBCXX_HAVE_ENOTRECOVERABLE 1
#define __LITTLE_ENDIAN 1234
#define CLOCK_REALTIME_COARSE 5
#define __USE_XOPEN2KXSI 1
#define __REDIRECT(name,proto,alias) name proto __asm__ (__ASMNAME (#alias))
#define __FLT_MIN_10_EXP__ (-37)
#define AS_MEMORY_H
#define __time_t_defined 1
#define __USE_UNIX98 1
#define __MODE_T_TYPE __U32_TYPE
#define _GLIBCXX_HAVE_STRINGS_H 1
#define __nonnull(params) __attribute__ ((__nonnull__ params))
#define CPU_ZERO(cpusetp) __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp)
#define __RLIM64_T_TYPE __UQUAD_TYPE
#define _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 1
#define BEGIN_AS_NAMESPACE
#define _GLIBCXX_USE_DEPRECATED 1
#define _GLIBCXX_HAVE_SETENV 1
#define CPU_XOR_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, ^)
#define _BITS_SETJMP_H 1
#define _GLIBCXX_PACKAGE_URL ""
#define CPU_CLR(cpu,cpusetp) __CPU_CLR_S (cpu, sizeof (cpu_set_t), cpusetp)
#define ASM_AT_N_T
#define CLONE_PARENT_SETTID 0x00100000
#define ANGELSCRIPT_VERSION 22501
#define __DEC128_MIN__ 1E-6143DL
#define __REGISTER_PREFIX__
#define __UINT16_MAX__ 65535
#define __DBL_HAS_DENORM__ 1
#define asBCINFO_DUMMY(b) {asBC_MAXBYTECODE, asBCTYPE_INFO, 0, "BC_" #b}
#define __attribute_pure__ __attribute__ ((__pure__))
#define CLONE_CHILD_SETTID 0x01000000
#define _GLIBCXX_HAVE_SINCOS 1
#define __USE_POSIX2 1
#define __UINT8_TYPE__ unsigned char
#define __SLONGWORD_TYPE long int
#define __bswap_32(x) (__extension__ ({ register unsigned int __bsx = (x); __bswap_constant_32 (__bsx); }))
#define _GLIBCXX_HAVE_ISWBLANK 1
#define __REDIRECT_LDBL(name,proto,alias) __REDIRECT (name, proto, alias)
#define __NO_INLINE__ 1
#define __warndecl(name,msg) extern void name (void) __attribute__((__warning__ (msg)))
#define CPU_SET(cpu,cpusetp) __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp)
#define __FLT_MANT_DIG__ 24
#define _GLIBCXX_HAVE_COMPLEX_H 1
#define __VERSION__ "4.6.3"
#define _GLIBCXX_HAVE_INT64_T 1
#define _GLIBCXX_USE_CONSTEXPR const
#define asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())(static_cast<r (*)p>(f)))
#define __UINT64_C(c) c ## ULL
#define _PTRDIFF_T_
#define _GLIBCXX_HAVE_TANHF 1
#define _SYS_CDEFS_H 1
#define _GLIBCXX_HAVE_TANHL 1
#define pthread_cleanup_pop_restore_np(execute) __clframe.__restore (); __clframe.__setdoit (execute); } while (0)
#define ARG_DW(b) ((asDWORD*)&b)
#define __CPU_OP_S(setsize,destset,srcset1,srcset2,op) (__extension__ ({ cpu_set_t *__dest = (destset); __const __cpu_mask *__arr1 = (srcset1)->__bits; __const __cpu_mask *__arr2 = (srcset2)->__bits; size_t __imax = (setsize) / sizeof (__cpu_mask); size_t __i; for (__i = 0; __i < __imax; ++__i) ((__cpu_mask *) __dest->__bits)[__i] = __arr1[__i] op __arr2[__i]; __dest; }))
#define AS_ALIGN
#define _GLIBCXX_PACKAGE_BUGREPORT ""
#define __INT_WCHAR_T_H
#define __USE_XOPEN2K8 1
#define asVSNPRINTF(a,b,c,d) vsnprintf(a, b, c, d)
#define _BSD_SOURCE 1
#define AS_PTR_SIZE 1
#define __STRING(x) #x
#define _T_PTRDIFF_
#define __unbounded
#define be16toh(x) __bswap_16 (x)
#define _GLIBCXX_HAVE_ENOSTR 1
#define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#define _GLIBCXX_HAVE_HYPOT 1
#define __GNUC_PREREQ(maj,min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#define _SYS_SIZE_T_H
#define _GLIBCXX_CXX_CONFIG_H 1
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __SIZE_T__
#define UNREACHABLE_RETURN
#define __glibcxx_assert(_Condition)
#define __stub_gtty
#define __NLINK_T_TYPE __UWORD_TYPE
#define __uint32_t_defined
#define _GLIBCXX_HAVE_TGMATH_H 1
#define __stub_sstk
#define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0, 0, 0, 0 } }
#define __wur
#define __STDC_IEC_559_COMPLEX__ 1
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0 } } }
#define asASSERT(x) assert(x)
#define ARG_QW(b) ((asQWORD*)&b)
#define _GLIBCXX_USE_C99_INTTYPES_TR1 1
#define __INT32_C(c) c
#define __DEC64_EPSILON__ 1E-15DD
#define __ORDER_PDP_ENDIAN__ 3412
#define __DEC128_MIN_EXP__ (-6142)
#define __PDP_ENDIAN 3412
#define _ISOC95_SOURCE 1
#define _GLIBCXX_HAVE_ENOSR 1
#define BYTE_ORDER __BYTE_ORDER
#define CLOCK_MONOTONIC_COARSE 6
#define __INT_FAST32_TYPE__ int
#define _GLIBCXX_HAVE_LIMIT_DATA 1
#define _GLIBCXX_HAVE_EBADMSG 1
#define htole32(x) (x)
#define BCARG_DW(b) ((asDWORD*)&(b)[1])
#define _GLIBCXX_USE_C99_MATH 1
#define __UINT_LEAST16_TYPE__ short unsigned int
#define _GLIBCXX_HAVE_GTHR_DEFAULT 1
#define STDC_HEADERS 1
#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define unix 1
#define __USE_POSIX 1
#define __bswap_constant_64(x) ((((x) & 0xff00000000000000ull) >> 56) | (((x) & 0x00ff000000000000ull) >> 40) | (((x) & 0x0000ff0000000000ull) >> 24) | (((x) & 0x000000ff00000000ull) >> 8) | (((x) & 0x00000000ff000000ull) << 8) | (((x) & 0x0000000000ff0000ull) << 24) | (((x) & 0x000000000000ff00ull) << 40) | (((x) & 0x00000000000000ffull) << 56))
#define AS_ARRAY_H
#define _GLIBCXX_HAVE_STRING_H 1
#define __INT16_MAX__ 32767
#define _BSD_SIZE_T_
#define __SIZE_TYPE__ unsigned int
#define __UINT64_MAX__ 18446744073709551615ULL
#define __va_arg_pack_len() __builtin_va_arg_pack_len ()
#define __ULONGWORD_TYPE unsigned long int
#define _SIZE_T_DECLARED
#define _GLIBCXX_HAVE_LIMIT_AS 1
#define __INT8_TYPE__ signed char
#define __ELF__ 1
#define DECLARECRITICALSECTION(x) asCThreadCriticalSection x;
#define _GLIBCXX_ATOMIC_BUILTINS_1 1
#define _GLIBCXX_ATOMIC_BUILTINS_2 1
#define _GLIBCXX_ATOMIC_BUILTINS_4 1
#define __ID_T_TYPE __U32_TYPE
#define CPU_AND(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, &)
#define _GLIBCXX_HAVE_MBSTATE_T 1
#define __warnattr(msg) __attribute__((__warning__ (msg)))
#define ANGELSCRIPT_VERSION_STRING "2.25.1"
#define __FLT_RADIX__ 2
#define __INT_LEAST16_TYPE__ short int
#define __LDBL_EPSILON__ 2.2204460492503131e-16L
#define __UINTMAX_C(c) c ## ULL
#define _POSIX_C_SOURCE 200809L
#define __long_double_t long double
#define _GLIBCXX_HAVE_ISINF 1
#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
#define __LDBL_REDIR(name,proto) name proto
#define CLOCK_MONOTONIC_RAW 4
#define __SIG_ATOMIC_MAX__ 2147483647
#define BCARG_QW(b) ((asQWORD*)&(b)[1])
#define __VFP_FP__ 1
#define __WCHAR_MAX ( (wchar_t) - 1 )
#define __SIZEOF_PTRDIFF_T__ 4
#define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))
#define _GLIBCXX_HAVE_COSF 1
#define _GLIBCXX_HAVE_COSL 1
#define __bswap_constant_32(x) ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
#define __errordecl(name,msg) extern void name (void) __attribute__((__error__ (msg)))
#define _XOPEN_SOURCE_EXTENDED 1
#define _GLIBCXX_END_NAMESPACE_VERSION
#define __restrict_arr
#define __USE_MISC 1
#define __UWORD_TYPE unsigned int
#define _SIZE_T_
#define asBCTYPE_PTR_DW_ARG asBCTYPE_DW_DW_ARG
#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
#define CLONE_NEWPID 0x20000000
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A)
#define _GLIBCXX_HAVE_DLFCN_H 1
#define strdupa(s) (__extension__ ({ __const char *__old = (s); size_t __len = strlen (__old) + 1; char *__new = (char *) __builtin_alloca (__len); (char *) memcpy (__new, __old, __len); }))
#define _WCHAR_T_H
#define SCHED_BATCH 3
#define CPU_ZERO_S(setsize,cpusetp) __CPU_ZERO_S (setsize, cpusetp)
#define _GLIBCXX_END_EXTERN_C }
#define __INT_FAST16_MAX__ 2147483647
#define __stub_revoke
#define __timer_t_defined 1
#define _GLIBCXX_HAVE_VSWSCANF 1
#define __ARM_ARCH_6__ 1
#define _GLIBCXX_ICONV_CONST
#define __WCHAR_MIN ( 0 )
#define __UINT_FAST32_MAX__ 4294967295U
#define __CPU_ALLOC_SIZE(count) ((((count) + __NCPUBITS - 1) / __NCPUBITS) * sizeof (__cpu_mask))
#define __UINT_LEAST64_TYPE__ long long unsigned int
#define __U64_TYPE __u_quad_t
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_MAX_10_EXP__ 38
#define _GLIBCXX_HAVE_FLOORF 1
#define _GLIBCXX_HAVE_FLOORL 1
#define __LONG_MAX__ 2147483647L
#define __WCHAR_T__
#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
#define asBCTYPE_wW_PTR_ARG asBCTYPE_wW_DW_ARG
#define RELEASEEXCLUSIVE(x) x.ReleaseExclusive()
#define _GLIBCXX_NORETURN __attribute__ ((__noreturn__))
#define __FLT_HAS_INFINITY__ 1
#define asBCINFO(b,t,s) {asBC_ ##b, asBCTYPE_ ##t, s, #b}
#define __unix 1
#define _BSD_PTRDIFF_T_
#define _GLIBCXX_USE_C99_MATH_TR1 1
#define __LONG_LONG_PAIR(HI,LO) LO, HI
#define __UINT_FAST16_TYPE__ unsigned int
#define __bos0(ptr) __builtin_object_size (ptr, 0)
#define __DEC64_MAX__ 9.999999999999999E384DD
#define NULL __null
#define __CHAR16_TYPE__ short unsigned int
#define LT_OBJDIR ".libs/"
#define __PRAGMA_REDEFINE_EXTNAME 1
#define __USING_NAMESPACE_C99(name)
#define BIG_ENDIAN __BIG_ENDIAN
#define _GLIBCXX_HAVE_SINF 1
#define _GLIBCXX_HAVE_SINL 1
#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE
#define COMPLEX_OBJS_PASSED_BY_REF
#define __INT_LEAST16_MAX__ 32767
#define __stub_lchmod
#define CLONE_NEWUSER 0x10000000
#define pthread_cleanup_pop(execute) __clframe.__setdoit (execute); } while (0)
#define __DEC64_MANT_DIG__ 16
#define __UINT_LEAST32_MAX__ 4294967295U
#define __INT_LEAST64_TYPE__ long long int
#define htole16(x) (x)
#define _GLIBCXX_SYMVER_GNU 1
#define __INT16_TYPE__ short int
#define __INT_LEAST8_TYPE__ signed char
#define __DEC32_MAX_EXP__ 97
#define TIMER_ABSTIME 1
#define __INT_FAST8_MAX__ 127
#define __PMT(args) args
#define __INTPTR_MAX__ 2147483647
#define CSIGNAL 0x000000ff
#define linux 1
#define _GLIBCXX_HAVE_ISNAN 1
#define CLOCK_MONOTONIC 1
#define __int8_t_defined
#define __CPU_SET_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu < 8 * (setsize) ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] |= __CPUMASK (__cpu)) : 0; }))
#define htole64(x) (x)
#define asBC_SWORDARG1(x) (*(((short*)x)+2))
#define _GLIBCXX_HAVE_LDEXPF 1
#define _XLOCALE_H 1
#define __KEY_T_TYPE __S32_TYPE
#define __EXCEPTIONS 1
#define __WORDSIZE 32
#define __BEGIN_DECLS extern "C" {
#define __LDBL_MANT_DIG__ 53
#define __USE_ANSI 1
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
#define _GLIBCXX_HAVE_INTTYPES_H 1
#define __DBL_HAS_QUIET_NAN__ 1
#define _BITS_BYTESWAP_H 1
#define _STRING_H 1
#define _BITS_PTHREADTYPES_H 1
#define CALLEE_POPS_HIDDEN_RETURN_POINTER
#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0 } } }
#define assert(expr) ((expr) ? __ASSERT_VOID_CAST (0) : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
#define __RLIM_T_TYPE __ULONGWORD_TYPE
#define le64toh(x) (x)
#define CLONE_FS 0x00000200
#define __INTPTR_TYPE__ int
#define __UINT16_TYPE__ short unsigned int
#define __WCHAR_TYPE__ unsigned int
#define __CLOCKID_T_TYPE __S32_TYPE
#define __SIZEOF_FLOAT__ 4
#define _GLIBCXX_PACKAGE_TARNAME "libstdc++"
#define DECLAREREADWRITELOCK(x) asCThreadReadWriteLock x;
#define __stub_fdetach
#define __UINTPTR_MAX__ 4294967295U
#define __DEC64_MIN_EXP__ (-382)
#define __stub_chflags
#define CLONE_IO 0x80000000
#define __BYTE_ORDER __LITTLE_ENDIAN
#define _GLIBCXX_USE_C99 1
#define _GLIBCXX_HAVE_WCSTOF 1
#define CPU_COUNT(cpusetp) __CPU_COUNT_S (sizeof (cpu_set_t), cpusetp)
#define __INT_FAST64_MAX__ 9223372036854775807LL
#define CLONE_NEWIPC 0x08000000
#define __FLT_DIG__ 6
#define __FSID_T_TYPE struct { int __val[2]; }
#define _GLIBCXX_HAVE_EIDRM 1
#define _GLIBCXX_CONSTEXPR
#define _WCHAR_T_DECLARED
#define __UINT_FAST64_TYPE__ long long unsigned int
#define _GLIBCXX_HAVE_WCTYPE_H 1
#define CLONE_UNTRACED 0x00800000
#define __LDBL_REDIR_DECL(name)
#define _GLIBCXX_HAVE_STRTOF 1
#define _GLIBCXX_HAVE_MEMORY_H 1
#define __INT_MAX__ 2147483647
#define _GLIBCXX_HAVE_STDINT_H 1
#define _GLIBCXX_HAVE_INT64_T_LONG_LONG 1
#define __S16_TYPE short int
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
#define _T_SIZE_
#define __CPU_SETSIZE 1024
#define __USE_LARGEFILE64 1
#define CLONE_PTRACE 0x00002000
#define __INT64_TYPE__ long long int
#define __FLT_MAX_EXP__ 128
#define CLOCK_PROCESS_CPUTIME_ID 2
#define _GLIBCXX_HAVE_STRXFRM_L 1
#define __DBL_MANT_DIG__ 53
#define ___int_size_t_h
#define __TIMER_T_TYPE void *
#define asNEWARRAY(x,cnt) (x*)userAlloc(sizeof(x)*cnt)
#define _GLIBCXX_HAVE_FENV_H 1
#define _GLIBCXX_HAVE_STDBOOL_H 1
#define __INT_LEAST64_MAX__ 9223372036854775807LL
#define AS_CONFIG_H
#define __clock_t_defined 1
#define __GLIBC_MINOR__ 13
#define CLONE_DETACHED 0x00400000
#define __DEC64_MIN__ 1E-383DD
#define __WINT_TYPE__ unsigned int
#define __UINT_LEAST32_TYPE__ unsigned int
#define __SIZEOF_SHORT__ 2
#define __intptr_t_defined
#define __LDBL_MIN_EXP__ (-1021)
#define _GLIBCXX_HAVE_LOGF 1
#define _GLIBCXX_HAVE_LOGL 1
#define _GLIBCXX_HAVE_EXPF 1
#define __arm__ 1
#define _GLIBCXX_HAVE_EXPL 1
#define _NEW
#define CLONE_VM 0x00000100
#define __INT_LEAST8_MAX__ 127
#define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
#define __USE_POSIX199309 1
#define CPU_SET_S(cpu,setsize,cpusetp) __CPU_SET_S (cpu, setsize, cpusetp)
#define _GLIBCXX_HAVE_LOG10F 1
#define _GLIBCXX_HAVE_LOG10L 1
#define __BLKCNT64_T_TYPE __SQUAD_TYPE
#define CPU_ISSET_S(cpu,setsize,cpusetp) __CPU_ISSET_S (cpu, setsize, cpusetp)
#define __WCHAR_UNSIGNED__ 1
#define __LDBL_MAX_10_EXP__ 308
#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
#define __DBL_EPSILON__ double(2.2204460492503131e-16L)
#define asBC_FLOATARG(x) (*(float*)(x+1))
#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
#define __stub_stty
#define le16toh(x) (x)
#define _SIZET_
#define _SVID_SOURCE 1
#define __REDIRECT_NTH_LDBL(name,proto,alias) __REDIRECT_NTH (name, proto, alias)
#define __UINT8_C(c) c
#define ACQUIRESHARED(x) x.AcquireShared()
#define _GLIBCXX_HAVE_CEILF 1
#define _GLIBCXX_HAVE_CEILL 1
#define __INT_LEAST32_TYPE__ int
#define CPU_FREE(cpuset) __CPU_FREE (cpuset)
#define __wchar_t__
#define __SIZEOF_WCHAR_T__ 4
#define __UINT64_TYPE__ long long unsigned int
#define _PTHREAD_H 1
#define _ISOC99_SOURCE 1
#define AS_API
#define _GLIBCXX_STD_A std
#define __REDIRECT_NTH(name,proto,alias) name proto __THROW __asm__ (__ASMNAME (#alias))
#define __END_NAMESPACE_STD
#define _GLIBCXX_USE_C99_STDINT_TR1 1
#define _STDDEF_H_
#define be64toh(x) __bswap_64 (x)
#define asBCTYPE_PTR_ARG asBCTYPE_DW_ARG
#define AS_ARM
#define _GLIBCXX_STDIO_SEEK_END 2
#define __INT_FAST8_TYPE__ signed char
#define __PID_T_TYPE __S32_TYPE
#define _GLIBCXX_HAVE_TANF 1
#define _GLIBCXX_USE_NLS 1
#define _GLIBCXX_HAVE_STDLIB_H 1
#define __stub_getpmsg
#define AS_NAMESPACE_QUALIFIER
#define asDELETEARRAY(ptr) userFree(ptr)
#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
#define __ASSERT_FUNCTION __PRETTY_FUNCTION__
#define asBC_INTARG(x) (int(*(x+1)))
#define _GLIBCXX_DEPRECATED
#define _GLIBCXX_SIZE_T_IS_UINT 1
#define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1
#define PTHREAD_ONCE_INIT 0
#define __DBL_DECIMAL_DIG__ 17
#define ARG_W(b) ((asWORD*)&b)
#define CLOCKS_PER_SEC 1000000l
#define __DEC_EVAL_METHOD__ 2
#define _SIZE_T
#define _GLIBCXX_USE_GETTIMEOFDAY 1
#define __ULONG32_TYPE unsigned long int
#define _GLIBCXX_FAST_MATH 0
#define CLONE_CHILD_CLEARTID 0x00200000
#define __BIG_ENDIAN 4321
#define strndupa(s,n) (__extension__ ({ __const char *__old = (s); size_t __len = strnlen (__old, (n)); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len); }))
#define _GLIBCXX_HAVE_LDEXPL 1
#define _GLIBCXX_NOTHROW throw()
#define __CPU_ALLOC(count) __sched_cpualloc (count)
#define _GCC_SIZE_T
#define __ORDER_BIG_ENDIAN__ 4321
#define __INO64_T_TYPE __UQUAD_TYPE
#define RELEASESHARED(x) x.ReleaseShared()
#define __USE_XOPEN2K8XSI 1
#define __UINT32_C(c) c ## U
#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
#define SCHED_RESET_ON_FORK 0x40000000
#define __INTMAX_MAX__ 9223372036854775807LL
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __size_t__
#define htobe64(x) __bswap_64 (x)
#define __FLT_DENORM_MIN__ 1.4012984643248171e-45F
#define CPU_ALLOC_SIZE(count) __CPU_ALLOC_SIZE (count)
#define CPU_OR(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, |)
#define __BEGIN_NAMESPACE_C99
#define _GLIBCXX_HAVE_FINITE 1
#define AS_SIZEOF_BOOL 1
#define __INT8_MAX__ 127
#define CPU_EQUAL_S(setsize,cpusetp1,cpusetp2) __CPU_EQUAL_S (setsize, cpusetp1, cpusetp2)
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define _GLIBCXX_HAVE_EOVERFLOW 1
#define __UINT_FAST32_TYPE__ unsigned int
#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
#define __CHAR32_TYPE__ unsigned int
#define AS_CRITICALSECTION_H
#define __FLT_MAX__ 3.4028234663852886e+38F
#define _GLIBCXX_HAVE_VFWSCANF 1
#define ENTERCRITICALSECTION(x) x.Enter()
#define CPU_XOR(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, ^)
#define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
#define AS_POSIX_THREADS
#define asMETHOD(c,m) asSMethodPtr<sizeof(void (c::*)())>::Convert((void (c::*)())(&c::m))
#define _GLIBCXX_HAVE_SYS_TYPES_H 1
#define __INT32_TYPE__ int
#define _ASSERT_H 1
#define __SIZEOF_DOUBLE__ 8
#define __SWORD_TYPE int
#define __INTMAX_TYPE__ long long int
#define __DEC128_MAX_EXP__ 6145
#define __CPU_FREE(cpuset) __sched_cpufree (cpuset)
#define _T_SIZE
#define __va_arg_pack() __builtin_va_arg_pack ()
#define _GLIBCXX_HAVE_TLS 1
#define _GLIBCXX_HAVE_ACOSF 1
#define _GLIBCXX_HAVE_ACOSL 1
#define CLONE_VFORK 0x00004000
#define __GNUC_MINOR__ 6
#define __UINTMAX_MAX__ 18446744073709551615ULL
#define CPU_CLR_S(cpu,setsize,cpusetp) __CPU_CLR_S (cpu, setsize, cpusetp)
#define __DEC32_MANT_DIG__ 7
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#define _STDINT_H 1
#define __DBL_MAX_10_EXP__ 308
#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
#define __USE_XOPEN_EXTENDED 1
#define _GLIBCXX_HAVE_SYS_RESOURCE_H 1
#define __INT16_C(c) c
#define _GLIBCXX_HAVE_SYS_IOCTL_H 1
#define __STDC__ 1
#define _GLIBCXX_HAVE_VWSCANF 1
#define __attribute_malloc__ __attribute__ ((__malloc__))
#define CLONE_SYSVSEM 0x00040000
#define _GLIBCXX_USE_C99_CTYPE_TR1 1
#define __PTRDIFF_TYPE__ int
#define _GLIBCXX_END_NAMESPACE_CONTAINER
#define __clockid_t_defined 1
#define __attribute_noinline__ __attribute__ ((__noinline__))
#define _GLIBCXX_BEGIN_NAMESPACE_LDBL
#define CPU_AND_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, &)
#define __NCPUBITS (8 * sizeof (__cpu_mask))
#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __UINT32_TYPE__ unsigned int
#define __UINTPTR_TYPE__ unsigned int
#define _GLIBCXX_INLINE_VERSION 0
#define AS_NO_ATOMIC
#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
#define __ARM_EABI__ 1
#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
#define __DEC128_MANT_DIG__ 34
#define __LDBL_MIN_10_EXP__ (-307)
#define __attribute_deprecated__ __attribute__ ((__deprecated__))
#define ARG_PTR(b) ((asPWORD*)&b)
#define __SIZEOF_LONG_LONG__ 8
#define _GLIBCXX_HAVE_ISINFF 1
#define _GLIBCXX_HAVE_ASINF 1
#define _GLIBCXX_HAVE_ISINFL 1
#define _GLIBCXX_HAVE_ASINL 1
#define __USE_ATFILE 1
#define _GCC_PTRDIFF_T
#define __LDBL_DIG__ 15
#define __FLT_DECIMAL_DIG__ 9
#define __UINT_FAST16_MAX__ 4294967295U
#define _GLIBCXX_HAVE_LIMIT_VMEM 0
#define _GLIBCXX_PACKAGE_STRING "package-unused version-unused"
#define asBC_SWORDARG0(x) (*(((short*)x)+1))
#define __GNUC_GNU_INLINE__ 1
#define asBC_SWORDARG2(x) (*(((short*)x)+3))
#define ___int_ptrdiff_t_h
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
#define GNU_STYLE_VIRTUAL_METHOD
#define _GLIBCXX_USE_NANOSLEEP 1
#define _GLIBCXX_HAVE_UNISTD_H 1
#define __UINT_FAST8_TYPE__ unsigned char
#define _GNU_SOURCE 1
#define __N(msgid) (msgid)
#define __P(args) args
#define __ARM_FEATURE_DSP 1
#define __WCHAR_T
#define __U32_TYPE unsigned int
#define _GLIBCXX_HAVE_EXECINFO_H 1[/CODE]
And I found this information in a doc called "Procedure Call Standard for the ARM® Architecture":
5.4
Result Return
The manner in which a result is returned from a function is determined by the type of that result.
For the base standard:
A Half-precision Floating Point Type is converted to single precision and returned in r0.
A Fundamental Data Type that is smaller than 4 bytes is zero- or sign-extended to a word and returned in r0.
A word-sized Fundamental Data Type (e.g., int, float) is returned in r0.
A double-word sized Fundamental Data Type (e.g., long long, double and 64-bit containerized vectors) is returned in r0 and r1.
A 128-bit containerized vector is returned in r0-r3.
A Composite Type not larger than 4 bytes is returned in r0. The format is as if the result had been stored in memory at a word-aligned address and then loaded into r0 with an LDR instruction. Any bits in r0 that lie outside the bounds of the result have unspecified values.
A Composite Type larger than 4 bytes, or whose size cannot be determined statically by both caller and callee, is stored in memory at an address passed as an extra argument when the function was called (§5.5, rule A.4).
The last paragraph has a reference to the following:
Stage A – Initialization
This stage is performed exactly once, before processing of the arguments commences.
A.1 The Next Core Register Number (NCRN) is set to r0.
A.2.cp Co-processor argument register initialization is performed.
A.3 The next stacked argument address (NSAA) is set to the current stack-pointer value (SP).
A.4 If the subroutine is a function that returns a result in memory, then the address for the result is placed in r0 and the NCRN is set to r1.
And in the chapter related to the VFP processor (in charge of floating point operations) it says:
6.1.2.2
Result return
Any result whose type would satisfy the conditions for a VFP CPRC is returned in the appropriate number of consecutive VFP registers starting with the lowest numbered register (s0, d0, q0).
All other types are returned as for the base standard.
Hope this helps.

Share this post


Link to post
Share on other sites
WitchLord    4677
Yes, both types are returned in registers. The Point type is returned in s0 and s1, and the Rect type is returned in s0, s1, s2, and s3.

This is not according to the Standard ARM ABI that you quoted, which is not surprising. I have yet to see any platform that follows the standard to the letter.

Anyway. This requires a bit of special handling in the AngelScript code. Both types have been registered with the following flags:

asOBJ_VALUE|asOBJ_POD|asOBJ_APP_CLASS|asOBJ_APP_CLASS_ALLFLOATS

The last flag, i.e. asOBJ_APP_CLASS_ALLFLOATS, is what needs to be used to identify this scenario.

I imagine something like this:

[code]
if( descr->returnType.IsObject() &&
!descr->returnType.IsObjectHandle() &&
!descr->returnType.IsReference() &&
!(descr->returnType.GetObjectType()->flags & COMPLEX_RETURN_MASK) &&
(descr->returnType.GetObjectType()->flags & asOBJ_APP_CLASS_ALLFLOATS) )
{
CopyReturnedObjectFromSRegisters(retPointer, descr->returnType.GetSizeInMemoryDWords());
}
[/code]

Where CopyReturnedObjectFromSRegisters() would be a function written in assembler to copy the s0, s1, s2, and s3 to the memory referred to by retPointer, based on the size.

With this complexity in how returned values are treated in the ABI you'll probably have to ignore sysFunc->hostReturnInMemory that is determined by PrepareSystemFunction(). Or, you need to change the PrepareSystemFunction() too to properly detect when a type is returned in memory or not.

Before making decisions though, you'll need to understand how other types are returned.

For example how would the following types be returned:

[code]
struct Int4 { int a; }; // Part of testcdecl_class.cpp
struct Int8 { int a, b; }; // Part of testcdecl_class.cpp
struct Int12 { int a, b, c; }; // Part of testcdecl_class.cpp
struct Float20 { float a, b, c, d, e; }; // not covered in any test. Register with same flags as Point and Rect
[/code]

I imagine the types will be returned as following:

[code]
Int4 -> r0
Int8 -> r0 and r1
Int12 -> memory (though could possibly be r0, r1, and r2)
Float20 -> memory (though could possibly be s0, s1, s2, s3, and s4)
[/code]

Share this post


Link to post
Share on other sites
WitchLord    4677
Based on the #defines that the compiler provides by default, it appears that the Raspberry Pi platform is treated just like Linux with ARM. I can't see anything that specifically identifies Raspberry Pi.

These are the defines of interest:

[code]
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __unix__ 1
#define __ARMEL__ 1
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define __GNUC__ 4
#define __GNUC_PATCHLEVEL__ 3
#define __GNUG__ 4
#define unix 1
#define __unix 1
#define linux 1
#define __arm__ 1
#define __GNUC_MINOR__ 6
#define __ARM_EABI__ 1
[/code]

This means that as_config.h will go into the section for the GNUC compiler with Linux operating system and ARM cpu. The specifics for this target platform are defined on the lines 738 to 753, which gives the following:

[code]
// Platform
#define AS_LINUX
#define AS_ARM

// Method pointer structure
#define GNU_STYLE_VIRTUAL_METHOD
#define MULTI_BASE_OFFSET(x) (*((asDWORD*)(&x)+1))

// Parameter treatment
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
#define COMPLEX_OBJS_PASSED_BY_REF
#define AS_CALLEE_DESTROY_OBJ_BY_VAL


// Return value treatment
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR)
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define CALLEE_POPS_HIDDEN_RETURN_POINTER
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define THISCALL_CALLEE_POPS_HIDDEN_RETURN_POINTER
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2

// Miscellaneous
#define STDCALL __attribute__((stdcall))
#define AS_POSIX_THREADS
#define AS_NO_ATOMIC
#define AS_SIZEOF_BOOL 1
#define ASM_AT_N_T
#define AS_ALIGN
[/code]

With the current information that I have, I believe the configuration in as_config.h is correct for the RPi. Except that we probably need to increment something to specifically identify that structures containing only floats are handled differently than others.

Share this post


Link to post
Share on other sites
Tzarls    1411
Disassemblies!
For this code:

[CODE]#include <iostream>
typedef unsigned long asDWORD;
struct Int4
{
int a;
};
struct Int8
{
int a,b;
};
struct Int12
{
int a,b,c;
};
struct Float20
{
float a,b,c,d,e;
};

Int4 test4(void)
{
Int4 p={1};
return p;
}
Int8 test8(void)
{
Int8 p={1,2};
return p;
}
Int12 test12(void)
{
Int12 p={1,2,3};
return p;
}
Float20 test20(void)
{
Float20 p={1.1f, 2.2f, 3.3f, 4.4f, 5.5f};
return p;
}
int main()
{
Int4 i4 = test4();
Int8 i8 = test8();
Int12 i12 = test12();
Float20 f20= test20();
std::cout << "Valor: " << i4.a << ".\n";
std::cout << "Valor: " << i8.a << ".\n";
std::cout << "Valor: " << i8.b << ".\n";
std::cout << "Valor: " << i12.a << ".\n";
std::cout << "Valor: " << i12.b << ".\n";
std::cout << "Valor: " << i12.c << ".\n";
std::cout << "Valor: " << f20.a << ".\n";
std::cout << "Valor: " << f20.b << ".\n";
std::cout << "Valor: " << f20.c << ".\n";
std::cout << "Valor: " << f20.d << ".\n";
std::cout << "Valor: " << f20.e << ".\n";
}
[/CODE]


main:

[CODE]0x872c push {r11, lr}
0x8730 add r11, sp, #4
0x8734 sub sp, sp, #48 ; 0x30
0x8738 bl 0x8658 <test4()>
0x873c mov r3, r0
0x8740 str r3, [r11, #-8]
0x8744 sub r3, r11, #16
0x8748 mov r0, r3
0x874c bl 0x8680 <test8()>
0x8750 sub r3, r11, #28
0x8754 mov r0, r3
0x8758 bl 0x86b4 <test12()>
0x875c sub r3, r11, #48 ; 0x30
0x8760 mov r0, r3
0x8764 bl 0x86e8 <test20()>
0x8768 ldr r0, [pc, #560] ; 0x89a0 <main()+628>
0x876c ldr r1, [pc, #560] ; 0x89a4 <main()+632>
0x8770 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8774 mov r3, r0
0x8778 mov r2, r3
0x877c ldr r3, [r11, #-8]
0x8780 mov r0, r2
0x8784 mov r1, r3
0x8788 bl 0x8540 <std::ostream::operator<<(int)>
0x878c mov r3, r0
0x8790 mov r0, r3
0x8794 ldr r1, [pc, #524] ; 0x89a8 <main()+636>
0x8798 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x879c ldr r0, [pc, #508] ; 0x89a0 <main()+628>
0x87a0 ldr r1, [pc, #508] ; 0x89a4 <main()+632>
0x87a4 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87a8 mov r3, r0
0x87ac mov r2, r3
0x87b0 ldr r3, [r11, #-16]
0x87b4 mov r0, r2
0x87b8 mov r1, r3
0x87bc bl 0x8540 <std::ostream::operator<<(int)>
0x87c0 mov r3, r0
0x87c4 mov r0, r3
0x87c8 ldr r1, [pc, #472] ; 0x89a8 <main()+636>
0x87cc bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87d0 ldr r0, [pc, #456] ; 0x89a0 <main()+628>
0x87d4 ldr r1, [pc, #456] ; 0x89a4 <main()+632>
0x87d8 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87dc mov r3, r0
0x87e0 mov r2, r3
0x87e4 ldr r3, [r11, #-12]
0x87e8 mov r0, r2
0x87ec mov r1, r3
0x87f0 bl 0x8540 <std::ostream::operator<<(int)>
0x87f4 mov r3, r0
0x87f8 mov r0, r3
0x87fc ldr r1, [pc, #420] ; 0x89a8 <main()+636>
0x8800 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8804 ldr r0, [pc, #404] ; 0x89a0 <main()+628>
0x8808 ldr r1, [pc, #404] ; 0x89a4 <main()+632>
0x880c bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8810 mov r3, r0
0x8814 mov r2, r3
0x8818 ldr r3, [r11, #-28]
0x881c mov r0, r2
0x8820 mov r1, r3
0x8824 bl 0x8540 <std::ostream::operator<<(int)>
0x8828 mov r3, r0
0x882c mov r0, r3
0x8830 ldr r1, [pc, #368] ; 0x89a8 <main()+636>
0x8834 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8838 ldr r0, [pc, #352] ; 0x89a0 <main()+628>
0x883c ldr r1, [pc, #352] ; 0x89a4 <main()+632>
0x8840 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8844 mov r3, r0
0x8848 mov r2, r3
0x884c ldr r3, [r11, #-24]
0x8850 mov r0, r2
0x8854 mov r1, r3
0x8858 bl 0x8540 <std::ostream::operator<<(int)>
0x885c mov r3, r0
0x8860 mov r0, r3
0x8864 ldr r1, [pc, #316] ; 0x89a8 <main()+636>
0x8868 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x886c ldr r0, [pc, #300] ; 0x89a0 <main()+628>
0x8870 ldr r1, [pc, #300] ; 0x89a4 <main()+632>
0x8874 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8878 mov r3, r0
0x887c mov r2, r3
0x8880 ldr r3, [r11, #-20]
0x8884 mov r0, r2
0x8888 mov r1, r3
0x888c bl 0x8540 <std::ostream::operator<<(int)>
0x8890 mov r3, r0
0x8894 mov r0, r3
0x8898 ldr r1, [pc, #264] ; 0x89a8 <main()+636>
0x889c bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88a0 ldr r0, [pc, #248] ; 0x89a0 <main()+628>
0x88a4 ldr r1, [pc, #248] ; 0x89a4 <main()+632>
0x88a8 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88ac mov r3, r0
0x88b0 vldr s15, [r11, #-48] ; 0xffffffd0
0x88b4 mov r0, r3
0x88b8 vmov.f32 s0, s15
0x88bc bl 0x85a0 <std::ostream::operator<<(float)>
0x88c0 mov r3, r0
0x88c4 mov r0, r3
0x88c8 ldr r1, [pc, #216] ; 0x89a8 <main()+636>
0x88cc bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88d0 ldr r0, [pc, #200] ; 0x89a0 <main()+628>
0x88d4 ldr r1, [pc, #200] ; 0x89a4 <main()+632>
0x88d8 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88dc mov r3, r0
0x88e0 vldr s15, [r11, #-44] ; 0xffffffd4
0x88e4 mov r0, r3
0x88e8 vmov.f32 s0, s15
0x88ec bl 0x85a0 <std::ostream::operator<<(float)>
0x88f0 mov r3, r0
0x88f4 mov r0, r3
0x88f8 ldr r1, [pc, #168] ; 0x89a8 <main()+636>
0x88fc bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8900 ldr r0, [pc, #152] ; 0x89a0 <main()+628>
0x8904 ldr r1, [pc, #152] ; 0x89a4 <main()+632>
0x8908 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x890c mov r3, r0
0x8910 vldr s15, [r11, #-40] ; 0xffffffd8
0x8914 mov r0, r3
0x8918 vmov.f32 s0, s15
0x891c bl 0x85a0 <std::ostream::operator<<(float)>
0x8920 mov r3, r0
0x8924 mov r0, r3
0x8928 ldr r1, [pc, #120] ; 0x89a8 <main()+636>
0x892c bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8930 ldr r0, [pc, #104] ; 0x89a0 <main()+628>
0x8934 ldr r1, [pc, #104] ; 0x89a4 <main()+632>
0x8938 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x893c mov r3, r0
0x8940 vldr s15, [r11, #-36] ; 0xffffffdc
0x8944 mov r0, r3
0x8948 vmov.f32 s0, s15
0x894c bl 0x85a0 <std::ostream::operator<<(float)>
0x8950 mov r3, r0
0x8954 mov r0, r3
0x8958 ldr r1, [pc, #72] ; 0x89a8 <main()+636>
0x895c bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8960 ldr r0, [pc, #56] ; 0x89a0 <main()+628>
0x8964 ldr r1, [pc, #56] ; 0x89a4 <main()+632>
0x8968 bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x896c mov r3, r0
0x8970 vldr s15, [r11, #-32] ; 0xffffffe0
0x8974 mov r0, r3
0x8978 vmov.f32 s0, s15
0x897c bl 0x85a0 <std::ostream::operator<<(float)>
0x8980 mov r3, r0
0x8984 mov r0, r3
0x8988 ldr r1, [pc, #24] ; 0x89a8 <main()+636>
0x898c bl 0x8588 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8990 mov r3, #0
0x8994 mov r0, r3
0x8998 sub sp, r11, #4
0x899c pop {r11, pc}
0x89a0 andeq r0, r1, r0, asr r12
0x89a4 andeq r8, r0, r4, asr #21
0x89a8 andeq r8, r0, r12, asr #21[/CODE]
Int4:
[CODE]0x8658 push {r11} ; (str r11, [sp, #-4]!)
0x865c add r11, sp, #0
0x8660 sub sp, sp, #12
0x8664 mov r3, #1
0x8668 str r3, [r11, #-8]
0x866c ldr r3, [r11, #-8]
0x8670 mov r0, r3
0x8674 add sp, r11, #0
0x8678 pop {r11}
0x867c bx lr[/CODE]
Int8:
[CODE]0x8680 push {r11} ; (str r11, [sp, #-4]!)
0x8684 add r11, sp, #0
0x8688 sub sp, sp, #12
0x868c str r0, [r11, #-8]
0x8690 ldr r3, [r11, #-8]
0x8694 ldr r2, [pc, #20] ; 0x86b0 <test8()+48>
0x8698 ldm r2, {r0, r1}
0x869c stm r3, {r0, r1}
0x86a0 ldr r0, [r11, #-8]
0x86a4 add sp, r11, #0
0x86a8 pop {r11}
0x86ac bx lr
0x86b0 muleq r0, r12, r10[/CODE]
Int12:
[CODE]0x86b4 push {r11} ; (str r11, [sp, #-4]!)
0x86b8 add r11, sp, #0
0x86bc sub sp, sp, #12
0x86c0 str r0, [r11, #-8]
0x86c4 ldr r3, [r11, #-8]
0x86c8 ldr r2, [pc, #20] ; 0x86e4 <test12()+48>
0x86cc ldm r2, {r0, r1, r2}
0x86d0 stm r3, {r0, r1, r2}
0x86d4 ldr r0, [r11, #-8]
0x86d8 add sp, r11, #0
0x86dc pop {r11}
0x86e0 bx lr
0x86e4 andeq r8, r0, r4, lsr #21[/CODE]
Float20:
[CODE]0x86e8 push {r4, r11}
0x86ec add r11, sp, #4
0x86f0 sub sp, sp, #8
0x86f4 str r0, [r11, #-8]
0x86f8 ldr r2, [r11, #-8]
0x86fc ldr r3, [pc, #36] ; 0x8728 <test20()+64>
0x8700 mov r12, r2
0x8704 mov r4, r3
0x8708 ldm r4!, {r0, r1, r2, r3}
0x870c stmia r12!, {r0, r1, r2, r3}
0x8710 ldr r3, [r4]
0x8714 str r3, [r12]
0x8718 ldr r0, [r11, #-8]
0x871c sub sp, r11, #4
0x8720 pop {r4, r11}
0x8724 bx lr
0x8728 ; <UNDEFINED> instruction: 0x00008ab0[/CODE]

Share this post


Link to post
Share on other sites
WitchLord    4677
All except Int4 are returned in memory. Int4 is returned in R0.

This is good, because it means that the configuration in as_config.h is correct, i.e. it should be:

#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2

You just need to add the exception when the object type is registered with asOBJ_CLASS_ALLFLOATS, where structs at most 32 bytes in size are returned in the registers.

Share this post


Link to post
Share on other sites
Tzarls    1411
Ok. So if, and only if, the type has been registered with asOBJ_CLASS_ALLFLOATS I have to do the "copy from registers to retPointer", and the rest of cases are supposedly being handled by the default behaviour, right?

Edit: Success!!! Now onto the next error....[img]http://public.gamedev.net//public/style_emoticons/default/dry.png[/img] [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img] Edited by Tzarls

Share this post


Link to post
Share on other sites
Tzarls    1411
Andreas:

Now I´m having trouble with the TestCDecl_ClassK test. It fails on line 114, with a "Failed to assign object returned from function. c1.a = ....". All tests before and after this one pass until the assertion at line 62 (function static void class1ByVal(ClassK1 c) ) which fails.

I can see that the class that fails is the one with just 1 member - does this have to do with the disassemblies we had before, when we found that classes with 1 member are returned in r0, and all of the others are returned in memory? Where do I look now?

Share this post


Link to post
Share on other sites
WitchLord    4677
This one is simpler. It has to do with what the compiler considers when determining if a class/struct is 'simple' or 'complex'. If all other tests pass before that, then it would seem the compiler looks for the existance of the destructor and or the copy constructor to determine that the class is 'complex'.

Change as_config.h to include the following defines on line 742:

[code]
#undef COMPLEX_MASK
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
#undef COMPLEX_RETURN_MASK
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR)
[/code]

Regards,
Andreas

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this