Angelscript on Raspberry Pi
Yes, there are 8 "d" registers for use by double arguments.
It probably means that there are 16 "s" registers too, but that needs to be confirmed. It may be that the ABI only uses 8 "s" registers.
The same for the "r" registers. How many are used?
I saw something interesting with the receivesMixed2(float a,double b,float c). The order of the arguments was changed, probably to use the s1 register which would otherwise be empty could be used. With this the arguments was passed as: a -> s0, c -> s1, b -> d1.
I wonder if the same happens when the function is receiving 32bit integers and 64bit integers too, i.e. receivesMixed3(int a, long long b, int c).
It probably means that there are 16 "s" registers too, but that needs to be confirmed. It may be that the ABI only uses 8 "s" registers.
The same for the "r" registers. How many are used?
I saw something interesting with the receivesMixed2(float a,double b,float c). The order of the arguments was changed, probably to use the s1 register which would otherwise be empty could be used. With this the arguments was passed as: a -> s0, c -> s1, b -> d1.
I wonder if the same happens when the function is receiving 32bit integers and 64bit integers too, i.e. receivesMixed3(int a, long long b, int c).
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Yes, I noticed the reordering of parameters. Ok, so next is: test if reordering happens with 32bit int and 64bit ints, and check the real limits for "r" and "s" registers. Funnily, the docs i´ve got state that the floating point unit in this processor has 16 "d" registers (which can be seen as 32 "s" registers).
I´ll be back with some more disassemblies.
I´ll be back with some more disassemblies.
#include <iostream>
void receivesMixedInts(int a, long long b, int c)
{
std::cout << "Received " << a << ".\n";
std::cout << "Received " << b << ".\n";
std::cout << "Received " << c << ".\n";
}
void receivesLots(double a0, double a1, double a2, double a3, double a4, double a5,
float f0, float f1, float f2, float f3, float f4, float f5, float f6, float f7)
{
std::cout << "Received " << a0 << ".\n";
std::cout << "Received " << a1 << ".\n";
std::cout << "Received " << a2 << ".\n";
std::cout << "Received " << a3 << ".\n";
std::cout << "Received " << a4 << ".\n";
std::cout << "Received " << a5 << ".\n";
std::cout << "Received " << f0 << ".\n";
std::cout << "Received " << f1 << ".\n";
std::cout << "Received " << f2 << ".\n";
std::cout << "Received " << f3 << ".\n";
std::cout << "Received " << f4 << ".\n";
std::cout << "Received " << f5 << ".\n";
std::cout << "Received " << f6 << ".\n";
std::cout << "Received " << f7 << ".\n";
}
void receivesLotsInts(long long a0, long long a1, long long a2,
int f0, int f1, int f2, int f3, int f4, int f5, int f6, int f7)
{
std::cout << "Received " << a0 << ".\n";
std::cout << "Received " << a1 << ".\n";
std::cout << "Received " << a2 << ".\n";
std::cout << "Received " << f0 << ".\n";
std::cout << "Received " << f1 << ".\n";
std::cout << "Received " << f2 << ".\n";
std::cout << "Received " << f3 << ".\n";
std::cout << "Received " << f4 << ".\n";
std::cout << "Received " << f5 << ".\n";
std::cout << "Received " << f6 << ".\n";
std::cout << "Received " << f7 << ".\n";
}
int main()
{
receivesMixedInts(1, 100, 3);
receivesLots(0.12345, 1.12345, 2.34567, 3.456789, 4.5678901, 5.6789012,
0.7f, 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f);
receivesLotsInts(1000000,2000000, 3000000,
1, 2, 3, 4, 5, 6, 7, 8);
return 0;
}
main:
0x8c38 push {r11, lr}
0x8c3c add r11, sp, #4
0x8c40 sub sp, sp, #40 ; 0x28
0x8c44 mov r3, #3
0x8c48 str r3, [sp]
0x8c4c mov r0, #1
0x8c50 mov r2, #100 ; 0x64
0x8c54 mov r3, #0
0x8c58 bl 0x86d0 <receivesMixedInts(int, long long, int)>
0x8c5c ldr r3, [pc, #268] ; 0x8d70 <main()+312>
0x8c60 str r3, [sp]
0x8c64 ldr r3, [pc, #264] ; 0x8d74 <main()+316>
0x8c68 str r3, [sp, #4]
0x8c6c ldr r3, [pc, #260] ; 0x8d78 <main()+320>
0x8c70 str r3, [sp, #8]
0x8c74 ldr r3, [pc, #256] ; 0x8d7c <main()+324>
0x8c78 str r3, [sp, #12]
0x8c7c vldr d0, [pc, #148] ; 0x8d18 <main()+224>
0x8c80 vldr d1, [pc, #152] ; 0x8d20 <main()+232>
0x8c84 vldr d2, [pc, #156] ; 0x8d28 <main()+240>
0x8c88 vldr d3, [pc, #160] ; 0x8d30 <main()+248>
0x8c8c vldr d4, [pc, #164] ; 0x8d38 <main()+256>
0x8c90 vldr d5, [pc, #168] ; 0x8d40 <main()+264>
0x8c94 vldr s12, [pc, #196] ; 0x8d60 <main()+296>
0x8c98 vldr s13, [pc, #196] ; 0x8d64 <main()+300>
0x8c9c vldr s14, [pc, #196] ; 0x8d68 <main()+304>
0x8ca0 vldr s15, [pc, #196] ; 0x8d6c <main()+308>
0x8ca4 bl 0x877c <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)>
0x8ca8 add r3, pc, #152 ; 0x98
0x8cac ldrd r2, [r3]
0x8cb0 strd r2, [sp]
0x8cb4 mov r3, #1
0x8cb8 str r3, [sp, #8]
0x8cbc mov r3, #2
0x8cc0 str r3, [sp, #12]
0x8cc4 mov r3, #3
0x8cc8 str r3, [sp, #16]
0x8ccc mov r3, #4
0x8cd0 str r3, [sp, #20]
0x8cd4 mov r3, #5
0x8cd8 str r3, [sp, #24]
0x8cdc mov r3, #6
0x8ce0 str r3, [sp, #28]
0x8ce4 mov r3, #7
0x8ce8 str r3, [sp, #32]
0x8cec mov r3, #8
0x8cf0 str r3, [sp, #36] ; 0x24
0x8cf4 add r1, pc, #84 ; 0x54
0x8cf8 ldrd r0, [r1]
0x8cfc add r3, pc, #84 ; 0x54
0x8d00 ldrd r2, [r3]
0x8d04 bl 0x8a2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)>
0x8d08 mov r3, #0
0x8d0c mov r0, r3
0x8d10 sub sp, r11, #4
0x8d14 pop {r11, pc}
0x8d18 adcspl pc, r0, r12, ror r2 ; <UNPREDICTABLE>
0x8d1c svccc 0x00bf9a6b
0x8d20 strlt r0, [r11, #-3880] ; 0xf28
0x8d24 svccc 0x00f1f9a6
0x8d28 andge r10, r9, #164, 20 ; 0xa4000
0x8d2c andmi r12, r2, lr, ror #7
0x8d30 stc2l 1, cr6, [r1, #380] ; 0x17c
0x8d34 andmi r10, r11, r0, lsl #15
0x8d38 blx 0x1f41b42
0x8d3c andsmi r4, r2, r4, lsl #11
0x8d40 sub sp, r12, r2, asr r12
0x8d44 andsmi r11, r6, r1, lsr r7
0x8d48 eoreq r12, sp, r0, asr #13
0x8d4c andeq r0, r0, r0
0x8d50 andeq r4, pc, r0, asr #4
0x8d54 andeq r0, r0, r0
0x8d58 andseq r8, lr, r0, lsl #9
0x8d5c andeq r0, r0, r0
0x8d60 svccc 0x00333333
0x8d64 svccc 0x008ccccd
0x8d68 andmi r12, r12, sp, asr #25
0x8d6c subsmi r3, r3, r3, lsr r3
0x8d70 addmi r12, r12, sp, asr #25
0x8d74 adcsmi r0, r0, r0
0x8d78 sbcsmi r3, r3, r3, lsr r3
0x8d7c rscsmi r6, r6, r6, ror #12
receiveMixedInts:
0x86d0 push {r11, lr}
0x86d4 add r11, sp, #4
0x86d8 sub sp, sp, #16
0x86dc str r0, [r11, #-8]
0x86e0 strd r2, [r11, #-20] ; 0xffffffec
0x86e4 ldr r0, [pc, #132] ; 0x8770 <receivesMixedInts(int, long long, int)+160>
0x86e8 ldr r1, [pc, #132] ; 0x8774 <receivesMixedInts(int, long long, int)+164>
0x86ec bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x86f0 mov r3, r0
0x86f4 mov r0, r3
0x86f8 ldr r1, [r11, #-8]
0x86fc bl 0x85a4 <std::ostream::operator<<(int)>
0x8700 mov r3, r0
0x8704 mov r0, r3
0x8708 ldr r1, [pc, #104] ; 0x8778 <receivesMixedInts(int, long long, int)+168>
0x870c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8710 ldr r0, [pc, #88] ; 0x8770 <receivesMixedInts(int, long long, int)+160>
0x8714 ldr r1, [pc, #88] ; 0x8774 <receivesMixedInts(int, long long, int)+164>
0x8718 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x871c mov r3, r0
0x8720 mov r0, r3
0x8724 ldrd r2, [r11, #-20] ; 0xffffffec
0x8728 bl 0x8610 <std::ostream::operator<<(long long)>
0x872c mov r3, r0
0x8730 mov r0, r3
0x8734 ldr r1, [pc, #60] ; 0x8778 <receivesMixedInts(int, long long, int)+168>
0x8738 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x873c ldr r0, [pc, #44] ; 0x8770 <receivesMixedInts(int, long long, int)+160>
0x8740 ldr r1, [pc, #44] ; 0x8774 <receivesMixedInts(int, long long, int)+164>
0x8744 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8748 mov r3, r0
0x874c mov r0, r3
0x8750 ldr r1, [r11, #4]
0x8754 bl 0x85a4 <std::ostream::operator<<(int)>
0x8758 mov r3, r0
0x875c mov r0, r3
0x8760 ldr r1, [pc, #16] ; 0x8778 <receivesMixedInts(int, long long, int)+168>
0x8764 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8768 sub sp, r11, #4
0x876c pop {r11, pc}
0x8770 andeq r1, r1, r0, ror #2
0x8774 andeq r8, r0, r0, ror lr
0x8778 andeq r8, r0, r12, ror lr
receivesLots:
0x877c push {r11, lr}
0x8780 add r11, sp, #4
0x8784 sub sp, sp, #64 ; 0x40
0x8788 vstr d0, [r11, #-12]
0x878c vstr d1, [r11, #-20] ; 0xffffffec
0x8790 vstr d2, [r11, #-28] ; 0xffffffe4
0x8794 vstr d3, [r11, #-36] ; 0xffffffdc
0x8798 vstr d4, [r11, #-44] ; 0xffffffd4
0x879c vstr d5, [r11, #-52] ; 0xffffffcc
0x87a0 vstr s12, [r11, #-56] ; 0xffffffc8
0x87a4 vstr s13, [r11, #-60] ; 0xffffffc4
0x87a8 vstr s14, [r11, #-64] ; 0xffffffc0
0x87ac vstr s15, [r11, #-68] ; 0xffffffbc
0x87b0 ldr r0, [pc, #616] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x87b4 ldr r1, [pc, #616] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x87b8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87bc mov r3, r0
0x87c0 mov r0, r3
0x87c4 vldr d0, [r11, #-12]
0x87c8 bl 0x8598 <std::ostream::operator<<(double)>
0x87cc mov r3, r0
0x87d0 mov r0, r3
0x87d4 ldr r1, [pc, #588] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x87d8 bl 0x85ec <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 ldr r0, [pc, #572] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x87e0 ldr r1, [pc, #572] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x87e4 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87e8 mov r3, r0
0x87ec mov r0, r3
0x87f0 vldr d0, [r11, #-20] ; 0xffffffec
0x87f4 bl 0x8598 <std::ostream::operator<<(double)>
0x87f8 mov r3, r0
0x87fc mov r0, r3
0x8800 ldr r1, [pc, #544] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8804 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8808 ldr r0, [pc, #528] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x880c ldr r1, [pc, #528] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8810 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8814 mov r3, r0
0x8818 mov r0, r3
0x881c vldr d0, [r11, #-28] ; 0xffffffe4
0x8820 bl 0x8598 <std::ostream::operator<<(double)>
0x8824 mov r3, r0
0x8828 mov r0, r3
0x882c ldr r1, [pc, #500] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8830 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8834 ldr r0, [pc, #484] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8838 ldr r1, [pc, #484] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x883c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8840 mov r3, r0
0x8844 mov r0, r3
0x8848 vldr d0, [r11, #-36] ; 0xffffffdc
0x884c bl 0x8598 <std::ostream::operator<<(double)>
0x8850 mov r3, r0
0x8854 mov r0, r3
0x8858 ldr r1, [pc, #456] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x885c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8860 ldr r0, [pc, #440] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8864 ldr r1, [pc, #440] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8868 bl 0x85ec <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 mov r3, r0
0x8870 mov r0, r3
0x8874 vldr d0, [r11, #-44] ; 0xffffffd4
0x8878 bl 0x8598 <std::ostream::operator<<(double)>
0x887c mov r3, r0
0x8880 mov r0, r3
0x8884 ldr r1, [pc, #412] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8888 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x888c ldr r0, [pc, #396] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8890 ldr r1, [pc, #396] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8894 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8898 mov r3, r0
0x889c mov r0, r3
0x88a0 vldr d0, [r11, #-52] ; 0xffffffcc
0x88a4 bl 0x8598 <std::ostream::operator<<(double)>
0x88a8 mov r3, r0
0x88ac mov r0, r3
0x88b0 ldr r1, [pc, #368] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x88b4 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88b8 ldr r0, [pc, #352] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x88bc ldr r1, [pc, #352] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x88c0 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88c4 mov r3, r0
0x88c8 mov r0, r3
0x88cc vldr s0, [r11, #-56] ; 0xffffffc8
0x88d0 bl 0x8604 <std::ostream::operator<<(float)>
0x88d4 mov r3, r0
0x88d8 mov r0, r3
0x88dc ldr r1, [pc, #324] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x88e0 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88e4 ldr r0, [pc, #308] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x88e8 ldr r1, [pc, #308] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x88ec bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88f0 mov r3, r0
0x88f4 mov r0, r3
0x88f8 vldr s0, [r11, #-60] ; 0xffffffc4
0x88fc bl 0x8604 <std::ostream::operator<<(float)>
0x8900 mov r3, r0
0x8904 mov r0, r3
0x8908 ldr r1, [pc, #280] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x890c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8910 ldr r0, [pc, #264] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8914 ldr r1, [pc, #264] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8918 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x891c mov r3, r0
0x8920 mov r0, r3
0x8924 vldr s0, [r11, #-64] ; 0xffffffc0
0x8928 bl 0x8604 <std::ostream::operator<<(float)>
0x892c mov r3, r0
0x8930 mov r0, r3
0x8934 ldr r1, [pc, #236] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8938 bl 0x85ec <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 ldr r0, [pc, #220] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8940 ldr r1, [pc, #220] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8944 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8948 mov r3, r0
0x894c mov r0, r3
0x8950 vldr s0, [r11, #-68] ; 0xffffffbc
0x8954 bl 0x8604 <std::ostream::operator<<(float)>
0x8958 mov r3, r0
0x895c mov r0, r3
0x8960 ldr r1, [pc, #192] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8964 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8968 ldr r0, [pc, #176] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x896c ldr r1, [pc, #176] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x8970 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8974 mov r3, r0
0x8978 mov r0, r3
0x897c vldr s0, [r11, #4]
0x8980 bl 0x8604 <std::ostream::operator<<(float)>
0x8984 mov r3, r0
0x8988 mov r0, r3
0x898c ldr r1, [pc, #148] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8990 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8994 ldr r0, [pc, #132] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x8998 ldr r1, [pc, #132] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x899c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x89a0 mov r3, r0
0x89a4 mov r0, r3
0x89a8 vldr s0, [r11, #8]
0x89ac bl 0x8604 <std::ostream::operator<<(float)>
0x89b0 mov r3, r0
0x89b4 mov r0, r3
0x89b8 ldr r1, [pc, #104] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x89bc bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x89c0 ldr r0, [pc, #88] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x89c4 ldr r1, [pc, #88] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x89c8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x89cc mov r3, r0
0x89d0 mov r0, r3
0x89d4 vldr s0, [r11, #12]
0x89d8 bl 0x8604 <std::ostream::operator<<(float)>
0x89dc mov r3, r0
0x89e0 mov r0, r3
0x89e4 ldr r1, [pc, #60] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x89e8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x89ec ldr r0, [pc, #44] ; 0x8a20 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+676>
0x89f0 ldr r1, [pc, #44] ; 0x8a24 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+680>
0x89f4 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x89f8 mov r3, r0
0x89fc mov r0, r3
0x8a00 vldr s0, [r11, #16]
0x8a04 bl 0x8604 <std::ostream::operator<<(float)>
0x8a08 mov r3, r0
0x8a0c mov r0, r3
0x8a10 ldr r1, [pc, #16] ; 0x8a28 <receivesLots(double, double, double, double, double, double, float, float, float, float, float, float, float, float)+684>
0x8a14 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8a18 sub sp, r11, #4
0x8a1c pop {r11, pc}
0x8a20 andeq r1, r1, r0, ror #2
0x8a24 andeq r8, r0, r0, ror lr
0x8a28 andeq r8, r0, r12, ror lr
receivesLotsInts:
0x8a2c push {r11, lr}
0x8a30 add r11, sp, #4
0x8a34 sub sp, sp, #16
0x8a38 strd r0, [r11, #-12]
0x8a3c strd r2, [r11, #-20] ; 0xffffffec
0x8a40 ldr r0, [pc, #484] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8a44 ldr r1, [pc, #484] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8a48 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8a4c mov r3, r0
0x8a50 mov r0, r3
0x8a54 ldrd r2, [r11, #-12]
0x8a58 bl 0x8610 <std::ostream::operator<<(long long)>
0x8a5c mov r3, r0
0x8a60 mov r0, r3
0x8a64 ldr r1, [pc, #456] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8a68 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8a6c ldr r0, [pc, #440] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8a70 ldr r1, [pc, #440] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8a74 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8a78 mov r3, r0
0x8a7c mov r0, r3
0x8a80 ldrd r2, [r11, #-20] ; 0xffffffec
0x8a84 bl 0x8610 <std::ostream::operator<<(long long)>
0x8a88 mov r3, r0
0x8a8c mov r0, r3
0x8a90 ldr r1, [pc, #412] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8a94 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8a98 ldr r0, [pc, #396] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8a9c ldr r1, [pc, #396] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8aa0 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8aa4 mov r3, r0
0x8aa8 mov r0, r3
0x8aac ldrd r2, [r11, #4]
0x8ab0 bl 0x8610 <std::ostream::operator<<(long long)>
0x8ab4 mov r3, r0
0x8ab8 mov r0, r3
0x8abc ldr r1, [pc, #368] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8ac0 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8ac4 ldr r0, [pc, #352] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8ac8 ldr r1, [pc, #352] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8acc bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8ad0 mov r3, r0
0x8ad4 mov r0, r3
0x8ad8 ldr r1, [r11, #12]
0x8adc bl 0x85a4 <std::ostream::operator<<(int)>
0x8ae0 mov r3, r0
0x8ae4 mov r0, r3
0x8ae8 ldr r1, [pc, #324] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8aec bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8af0 ldr r0, [pc, #308] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8af4 ldr r1, [pc, #308] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8af8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8afc mov r3, r0
0x8b00 mov r0, r3
0x8b04 ldr r1, [r11, #16]
0x8b08 bl 0x85a4 <std::ostream::operator<<(int)>
0x8b0c mov r3, r0
0x8b10 mov r0, r3
0x8b14 ldr r1, [pc, #280] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8b18 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b1c ldr r0, [pc, #264] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8b20 ldr r1, [pc, #264] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8b24 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b28 mov r3, r0
0x8b2c mov r0, r3
0x8b30 ldr r1, [r11, #20]
0x8b34 bl 0x85a4 <std::ostream::operator<<(int)>
0x8b38 mov r3, r0
0x8b3c mov r0, r3
0x8b40 ldr r1, [pc, #236] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8b44 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b48 ldr r0, [pc, #220] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8b4c ldr r1, [pc, #220] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8b50 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b54 mov r3, r0
0x8b58 mov r0, r3
0x8b5c ldr r1, [r11, #24]
0x8b60 bl 0x85a4 <std::ostream::operator<<(int)>
0x8b64 mov r3, r0
0x8b68 mov r0, r3
0x8b6c ldr r1, [pc, #192] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8b70 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b74 ldr r0, [pc, #176] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8b78 ldr r1, [pc, #176] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8b7c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8b80 mov r3, r0
0x8b84 mov r0, r3
0x8b88 ldr r1, [r11, #28]
0x8b8c bl 0x85a4 <std::ostream::operator<<(int)>
0x8b90 mov r3, r0
0x8b94 mov r0, r3
0x8b98 ldr r1, [pc, #148] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8b9c bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8ba0 ldr r0, [pc, #132] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8ba4 ldr r1, [pc, #132] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8ba8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8bac mov r3, r0
0x8bb0 mov r0, r3
0x8bb4 ldr r1, [r11, #32]
0x8bb8 bl 0x85a4 <std::ostream::operator<<(int)>
0x8bbc mov r3, r0
0x8bc0 mov r0, r3
0x8bc4 ldr r1, [pc, #104] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8bc8 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8bcc ldr r0, [pc, #88] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8bd0 ldr r1, [pc, #88] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8bd4 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8bd8 mov r3, r0
0x8bdc mov r0, r3
0x8be0 ldr r1, [r11, #36] ; 0x24
0x8be4 bl 0x85a4 <std::ostream::operator<<(int)>
0x8be8 mov r3, r0
0x8bec mov r0, r3
0x8bf0 ldr r1, [pc, #60] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8bf4 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8bf8 ldr r0, [pc, #44] ; 0x8c2c <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+512>
0x8bfc ldr r1, [pc, #44] ; 0x8c30 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+516>
0x8c00 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8c04 mov r3, r0
0x8c08 mov r0, r3
0x8c0c ldr r1, [r11, #40] ; 0x28
0x8c10 bl 0x85a4 <std::ostream::operator<<(int)>
0x8c14 mov r3, r0
0x8c18 mov r0, r3
0x8c1c ldr r1, [pc, #16] ; 0x8c34 <receivesLotsInts(long long, long long, long long, int, int, int, int, int, int, int, int)+520>
0x8c20 bl 0x85ec <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8c24 sub sp, r11, #4
0x8c28 pop {r11, pc}
0x8c2c andeq r1, r1, r0, ror #2
0x8c30 andeq r8, r0, r0, ror lr
0x8c34 andeq r8, r0, r12, ror lr
From what I see: 16 "s" registers, but only 4 "r" registers?
Yes. 16 "s" registers and only 4 "r" registers.
The 64 bit integers are also aligned to even registers, but contrary to what is done for floats, the arguments are not reordered to use the otherwise empty registers. When calling the receiveMixedInts the first arg was put in r0, the second in r2 and r3, and the third was pushed on the stack, leaving r1 unused.
One last thing needs to be checked. And that is how the arguments that don't fit in the registers are pushed on the stack.
void funcArgsOnStack(int i0, int i1, int i2, int i3, int i4, double f0, double f1, double f2, int i5, double f3, double f4, double f5, double f6, double f7, double f8, int i6);
From what we've learned I suspect the result will be as following:
i6 on stack
f8 on stack
f7 in d7
f6 in d6
f5 in d5
f4 in d4
f3 in d3
i5 on stack
f2 in d2
f1 in d1
f0 in d0
i4 on stack
i3 in r3
i2 in r2
i1 in r1
i0 in r0
If I'm right, I have a pretty good idea on the algorithm that needs to be used to prepare the arguments for loading into the registers. The good part is that we can reuse most of what is already there for the Android ABI, we just need to treat floats and doubles differently.
The 64 bit integers are also aligned to even registers, but contrary to what is done for floats, the arguments are not reordered to use the otherwise empty registers. When calling the receiveMixedInts the first arg was put in r0, the second in r2 and r3, and the third was pushed on the stack, leaving r1 unused.
One last thing needs to be checked. And that is how the arguments that don't fit in the registers are pushed on the stack.
void funcArgsOnStack(int i0, int i1, int i2, int i3, int i4, double f0, double f1, double f2, int i5, double f3, double f4, double f5, double f6, double f7, double f8, int i6);
From what we've learned I suspect the result will be as following:
i6 on stack
f8 on stack
f7 in d7
f6 in d6
f5 in d5
f4 in d4
f3 in d3
i5 on stack
f2 in d2
f1 in d1
f0 in d0
i4 on stack
i3 in r3
i2 in r2
i1 in r1
i0 in r0
If I'm right, I have a pretty good idea on the algorithm that needs to be used to prepare the arguments for loading into the registers. The good part is that we can reuse most of what is already there for the Android ABI, we just need to treat floats and doubles differently.
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, here´s the new data.
main:
funcArgsOnStack:
I think this came out as you predicted?
#include <iostream>
void funcArgsOnStack(int i0, int i1, int i2, int i3, int i4,
double f0, double f1, double f2,
int i5,
double f3, double f4, double f5, double f6, double f7, double f8,
int i6)
{
std::cout << "Received " << i0 <<".\n";
std::cout << "Received " << i1 <<".\n";
std::cout << "Received " << i2 <<".\n";
std::cout << "Received " << i3 <<".\n";
std::cout << "Received " << i4 <<".\n";
std::cout << "Received " << f0 <<".\n";
std::cout << "Received " << f1 <<".\n";
std::cout << "Received " << f2 <<".\n";
std::cout << "Received " << i5 <<".\n";
std::cout << "Received " << f3 <<".\n";
std::cout << "Received " << f4 <<".\n";
std::cout << "Received " << f5 <<".\n";
std::cout << "Received " << f6 <<".\n";
std::cout << "Received " << f7 <<".\n";
std::cout << "Received " << f8 <<".\n";
std::cout << "Received " << i6 <<".\n";
}
int main()
{
funcArgsOnStack(0,1,2,3,4, 0.123456, 1.234567, 2.345678, 5, 3.456789, 4.56789, 5.6789, 6.789012,
7.890123, 8.9012345, 6);
return 0;
}
main:
0x8970 push {r11, lr}
0x8974 add r11, sp, #4
0x8978 sub sp, sp, #24
0x897c mov r3, #4
0x8980 str r3, [sp]
0x8984 mov r3, #5
0x8988 str r3, [sp, #4]
0x898c add r3, pc, #84 ; 0x54
0x8990 ldrd r2, [r3]
0x8994 strd r2, [sp, #8]
0x8998 mov r3, #6
0x899c str r3, [sp, #16]
0x89a0 mov r0, #0
0x89a4 mov r1, #1
0x89a8 mov r2, #2
0x89ac mov r3, #3
0x89b0 vldr d0, [pc, #56] ; 0x89f0 <main()+128>
0x89b4 vldr d1, [pc, #60] ; 0x89f8 <main()+136>
0x89b8 vldr d2, [pc, #64] ; 0x8a00 <main()+144>
0x89bc vldr d3, [pc, #68] ; 0x8a08 <main()+152>
0x89c0 vldr d4, [pc, #72] ; 0x8a10 <main()+160>
0x89c4 vldr d5, [pc, #76] ; 0x8a18 <main()+168>
0x89c8 vldr d6, [pc, #80] ; 0x8a20 <main()+176>
0x89cc vldr d7, [pc, #84] ; 0x8a28 <main()+184>
0x89d0 bl 0x8660 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)>
0x89d4 mov r3, #0
0x89d8 mov r0, r3
0x89dc sub sp, r11, #4
0x89e0 pop {r11, pc}
0x89e4 nop ; (mov r0, r0)
0x89e8 blls 0xfefcc10c
0x89ec eormi r12, r1, lr, ror #26
0x89f0 blx 0x1fb64f4
0x89f4 svccc 0x00bf9acf
0x89f8 orrspl r8, r11, #8847360 ; 0x870000
0x89fc svccc 0x00f3c0c9
0x8a00 bicle r9, r7, #268435469 ; 0x1000000d
0x8a04 strdmi r12, [r2], -r2
0x8a08 stc2l 1, cr6, [r1, #380] ; 0x17c
0x8a0c andmi r10, r11, r0, lsl #15
0x8a10 vst3.16 ; <UNDEFINED> instruction: 0xf4c6e6da
0x8a14 andsmi r4, r2, r4, lsl #11
0x8a18 svchi 0x00c50481
0x8a1c andsmi r11, r6, r1, lsr r7
0x8a20 movwgt r9, #2864 ; 0xb30
0x8a24 ; <UNDEFINED> instruction: 0x401b27f2
0x8a28 ldrbvs r10, [r9, -sp, ror #22]
0x8a2c andsmi r8, pc, r12, ror pc ; <UNPREDICTABLE>
funcArgsOnStack:
0x8660 push {r11, lr}
0x8664 add r11, sp, #4
0x8668 sub sp, sp, #80 ; 0x50
0x866c str r0, [r11, #-8]
0x8670 str r1, [r11, #-12]
0x8674 str r2, [r11, #-16]
0x8678 str r3, [r11, #-20]
0x867c vstr d0, [r11, #-28] ; 0xffffffe4
0x8680 vstr d1, [r11, #-36] ; 0xffffffdc
0x8684 vstr d2, [r11, #-44] ; 0xffffffd4
0x8688 vstr d3, [r11, #-52] ; 0xffffffcc
0x868c vstr d4, [r11, #-60] ; 0xffffffc4
0x8690 vstr d5, [r11, #-68] ; 0xffffffbc
0x8694 vstr d6, [r11, #-76] ; 0xffffffb4
0x8698 vstr d7, [r11, #-84] ; 0xffffffac
0x869c ldr r0, [pc, #704] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x86a0 ldr r1, [pc, #704] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x86a4 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x86a8 mov r3, r0
0x86ac mov r0, r3
0x86b0 ldr r1, [r11, #-8]
0x86b4 bl 0x854c <std::ostream::operator<<(int)>
0x86b8 mov r3, r0
0x86bc mov r0, r3
0x86c0 ldr r1, [pc, #676] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x86c4 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x86c8 ldr r0, [pc, #660] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x86cc ldr r1, [pc, #660] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x86d0 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x86d4 mov r3, r0
0x86d8 mov r0, r3
0x86dc ldr r1, [r11, #-12]
0x86e0 bl 0x854c <std::ostream::operator<<(int)>
0x86e4 mov r3, r0
0x86e8 mov r0, r3
0x86ec ldr r1, [pc, #632] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x86f0 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x86f4 ldr r0, [pc, #616] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x86f8 ldr r1, [pc, #616] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x86fc bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8700 mov r3, r0
0x8704 mov r0, r3
0x8708 ldr r1, [r11, #-16]
0x870c bl 0x854c <std::ostream::operator<<(int)>
0x8710 mov r3, r0
0x8714 mov r0, r3
0x8718 ldr r1, [pc, #588] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x871c bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8720 ldr r0, [pc, #572] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8724 ldr r1, [pc, #572] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8728 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x872c mov r3, r0
0x8730 mov r0, r3
0x8734 ldr r1, [r11, #-20]
0x8738 bl 0x854c <std::ostream::operator<<(int)>
0x873c mov r3, r0
0x8740 mov r0, r3
0x8744 ldr r1, [pc, #544] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8748 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x874c ldr r0, [pc, #528] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8750 ldr r1, [pc, #528] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8754 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8758 mov r3, r0
0x875c mov r0, r3
0x8760 ldr r1, [r11, #4]
0x8764 bl 0x854c <std::ostream::operator<<(int)>
0x8768 mov r3, r0
0x876c mov r0, r3
0x8770 ldr r1, [pc, #500] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8774 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8778 ldr r0, [pc, #484] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x877c ldr r1, [pc, #484] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8780 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8784 mov r3, r0
0x8788 mov r0, r3
0x878c vldr d0, [r11, #-28] ; 0xffffffe4
0x8790 bl 0x8540 <std::ostream::operator<<(double)>
0x8794 mov r3, r0
0x8798 mov r0, r3
0x879c ldr r1, [pc, #456] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x87a0 bl 0x8594 <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, #440] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x87a8 ldr r1, [pc, #440] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x87ac bl 0x8594 <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 mov r0, r3
0x87b8 vldr d0, [r11, #-36] ; 0xffffffdc
0x87bc bl 0x8540 <std::ostream::operator<<(double)>
0x87c0 mov r3, r0
0x87c4 mov r0, r3
0x87c8 ldr r1, [pc, #412] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x87cc bl 0x8594 <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, #396] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x87d4 ldr r1, [pc, #396] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x87d8 bl 0x8594 <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 r0, r3
0x87e4 vldr d0, [r11, #-44] ; 0xffffffd4
0x87e8 bl 0x8540 <std::ostream::operator<<(double)>
0x87ec mov r3, r0
0x87f0 mov r0, r3
0x87f4 ldr r1, [pc, #368] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x87f8 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x87fc ldr r0, [pc, #352] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8800 ldr r1, [pc, #352] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8804 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8808 mov r3, r0
0x880c mov r0, r3
0x8810 ldr r1, [r11, #8]
0x8814 bl 0x854c <std::ostream::operator<<(int)>
0x8818 mov r3, r0
0x881c mov r0, r3
0x8820 ldr r1, [pc, #324] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8824 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8828 ldr r0, [pc, #308] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x882c ldr r1, [pc, #308] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8830 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8834 mov r3, r0
0x8838 mov r0, r3
0x883c vldr d0, [r11, #-52] ; 0xffffffcc
0x8840 bl 0x8540 <std::ostream::operator<<(double)>
0x8844 mov r3, r0
0x8848 mov r0, r3
0x884c ldr r1, [pc, #280] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8850 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8854 ldr r0, [pc, #264] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8858 ldr r1, [pc, #264] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x885c bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8860 mov r3, r0
0x8864 mov r0, r3
0x8868 vldr d0, [r11, #-60] ; 0xffffffc4
0x886c bl 0x8540 <std::ostream::operator<<(double)>
0x8870 mov r3, r0
0x8874 mov r0, r3
0x8878 ldr r1, [pc, #236] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x887c bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8880 ldr r0, [pc, #220] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8884 ldr r1, [pc, #220] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8888 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x888c mov r3, r0
0x8890 mov r0, r3
0x8894 vldr d0, [r11, #-68] ; 0xffffffbc
0x8898 bl 0x8540 <std::ostream::operator<<(double)>
0x889c mov r3, r0
0x88a0 mov r0, r3
0x88a4 ldr r1, [pc, #192] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x88a8 bl 0x8594 <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 ldr r0, [pc, #176] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x88b0 ldr r1, [pc, #176] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x88b4 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88b8 mov r3, r0
0x88bc mov r0, r3
0x88c0 vldr d0, [r11, #-76] ; 0xffffffb4
0x88c4 bl 0x8540 <std::ostream::operator<<(double)>
0x88c8 mov r3, r0
0x88cc mov r0, r3
0x88d0 ldr r1, [pc, #148] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x88d4 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88d8 ldr r0, [pc, #132] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x88dc ldr r1, [pc, #132] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x88e0 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x88e4 mov r3, r0
0x88e8 mov r0, r3
0x88ec vldr d0, [r11, #-84] ; 0xffffffac
0x88f0 bl 0x8540 <std::ostream::operator<<(double)>
0x88f4 mov r3, r0
0x88f8 mov r0, r3
0x88fc ldr r1, [pc, #104] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8900 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8904 ldr r0, [pc, #88] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8908 ldr r1, [pc, #88] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x890c bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x8910 mov r3, r0
0x8914 mov r0, r3
0x8918 vldr d0, [r11, #12]
0x891c bl 0x8540 <std::ostream::operator<<(double)>
0x8920 mov r3, r0
0x8924 mov r0, r3
0x8928 ldr r1, [pc, #60] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x892c bl 0x8594 <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, #44] ; 0x8964 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+772>
0x8934 ldr r1, [pc, #44] ; 0x8968 <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+776>
0x8938 bl 0x8594 <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 mov r0, r3
0x8944 ldr r1, [r11, #20]
0x8948 bl 0x854c <std::ostream::operator<<(int)>
0x894c mov r3, r0
0x8950 mov r0, r3
0x8954 ldr r1, [pc, #16] ; 0x896c <funcArgsOnStack(int, int, int, int, int, double, double, double, int, double, double, double, double, double, double, int)+780>
0x8958 bl 0x8594 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)>
0x895c sub sp, r11, #4
0x8960 pop {r11, pc}
0x8964 andeq r0, r1, r0, asr #25
0x8968 andeq r8, r0, r0, lsr #22
0x896c andeq r8, r0, r12, lsr #22
I think this came out as you predicted?
Yes, it did.
So, from what I see the arguments needs to be prepared as the following pseudo code:
Of course, it will be necessary to update the as_callfunc_arm_gcc.S too, so the functions take the floatArgs and copy those into the registers. With the algorithm I described above it will be as simple as writing the instructions to copy each pair of elements from the floatArgs array into the d0 to d7 registers. From what I understood the d registers aliases two s registers so loading the d register or the loading each s register will give the same result.
The return of float or double can be handled in a similar way to what is done in as_callfunc_x86.cpp, i.e. after the call to the assembler routine returns to CallSystemFunctionNative, the code can check if the called function returns a float with if( sysFunc->hostReturnFloat ) and if so call another assembler routine that simply unloads the d0 register into r0 and r1, in order to return the float/double as a 64bit integer instead.
I hope you can do the implementation. Don't worry about keeping maintainability with iOS and Android, just get it to work on RPi. Once that is working I can help merge the code so it will work for all targets with the use of preprocessor defines.
So, from what I see the arguments needs to be prepared as the following pseudo code:
asDWORD genericArgs[MAX_ARGS]; // 4 "r" registers + stack
asDWORD floatArgs[16]; // 8 "d" or 16 "s" registers
int countGeneric = 0;
int countFloat = 0;
int freeSingleFloat = -1;
int argPos = 0;
for( asUINT n = 0; n < countArgs; n++ )
{
if( parameterTypes[n] is float )
{
if( freeSingleFloat != -1 )
{
floatArgs[freeSingleFloat] = args[argPos++];
freeSingleFloat = -1;
continue;
}
else if( countFloat < 15 )
{
floatArgs[countFloat++] = args[argPos++];
continue;
}
}
else if( parameterTypes[n] is double )
{
if( countFloat < 14 )
{
// Make sure the double is aligned on even registers
if( countFloat & 1 )
freeSingleFloat = countFloat++;
// Copy two dwords for the double
floatArgs[countFloat++] = args[argPos++];
floatArgs[countFloat++] = args[argPos++];
continue;
}
}
// else do whatever is already done for ANDROID in as_callfunc_arm.cpp
}
Of course, it will be necessary to update the as_callfunc_arm_gcc.S too, so the functions take the floatArgs and copy those into the registers. With the algorithm I described above it will be as simple as writing the instructions to copy each pair of elements from the floatArgs array into the d0 to d7 registers. From what I understood the d registers aliases two s registers so loading the d register or the loading each s register will give the same result.
The return of float or double can be handled in a similar way to what is done in as_callfunc_x86.cpp, i.e. after the call to the assembler routine returns to CallSystemFunctionNative, the code can check if the called function returns a float with if( sysFunc->hostReturnFloat ) and if so call another assembler routine that simply unloads the d0 register into r0 and r1, in order to return the float/double as a 64bit integer instead.
I hope you can do the implementation. Don't worry about keeping maintainability with iOS and Android, just get it to work on RPi. Once that is working I can help merge the code so it will work for all targets with the use of preprocessor defines.
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 ABI that is used by iOS, Android and other ARM based Linux'es is described here: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
Section 6 talks about floating point types - how they are stored in VFP registers.
Section 6 talks about floating point types - how they are stored in VFP registers.
Yes, I have that reference in as_callfunc_arm.cpp. It is the official ARM ABI. It is however not strictly followed on the various platforms, so it can not be directly used. iOS, Android, and Windows Phone all have slight differences, and none of them use the floating point registers to pass arguments.
Raspberry Pi is one platform that seems to come closest to follow it. Perhaps we'll find that it is 100% compliant.
Raspberry Pi is one platform that seems to come closest to follow it. Perhaps we'll find that it is 100% compliant.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Andreas, I need some help here.
In your pseudo code you check for floats and doubles, but never for ints or long longs, even though you declared an array for "r" registers + stack. Was that an error?
Then, in as_callfunc_arm.cpp you have:
What does takesObjByVal tell us? Also, I have trouble deciding where to put the new algo in the existing implementation. Would it be something like this?
In your pseudo code you check for floats and doubles, but never for ints or long longs, even though you declared an array for "r" registers + stack. Was that an error?
Then, in as_callfunc_arm.cpp you have:
#ifndef AS_ANDROID
if( sysFunc->takesObjByVal )
#endif
What does takesObjByVal tell us? Also, I have trouble deciding where to put the new algo in the existing implementation. Would it be something like this?
if (argType == float)
{....}
else if (argType == double)
{.....}
else
#ifndef AS_ANDROID
if( sysFunc->takesObjByVal )
#endif
{
#ifdef AS_ANDROID....
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement