123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /*
- AngelCode Scripting Library
- Copyright (c) 2003-2015 Andreas Jonsson
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
- The original version of this library can be located at:
- http://www.angelcode.com/angelscript/
- Andreas Jonsson
- andreas@angelcode.com
- */
- // Assembly routines for the ARM call convention
- // Written by Fredrik Ehnbom in June 2009
- // Adapted to GNUC by darktemplar216 in September 2009
- // Small fixed to work under XCode GCC by Gilad Novik in October 2009
- #if !defined(AS_MAX_PORTABILITY)
- #if defined(__arm__) || defined(__ARM__)
- .align 2
- .globl _armFunc
- .globl _armFuncR0
- .globl _armFuncR0R1
- .globl _armFuncObjLast
- .globl _armFuncR0ObjLast
-
- _armFunc:
- stmdb sp!, {r4-r8, lr}
- mov r6, r0 // arg table
- movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
- mov r4, r2 // function address
- mov r8, #0
- beq nomoreargs
- // Load the first 4 arguments into r0-r3
- cmp r7, #4
- ldrge r0, [r6],#4
- cmp r7, #2*4
- ldrge r1, [r6],#4
- cmp r7, #3*4
- ldrge r2, [r6],#4
- cmp r7, #4*4
- ldrge r3, [r6],#4
- ble nomoreargs
- // Load the rest of the arguments onto the stack
- sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
- sub sp, sp, r7
- mov r8, r7
- stackargsloop:
- ldr r5, [r6], #4
- str r5, [sp], #4
- subs r7, r7, #4
- bne stackargsloop
- nomoreargs:
- sub sp, sp, r8
- blx r4
- add sp, sp, r8
- ldmia sp!, {r4-r8, pc}
- _armFuncObjLast:
- stmdb sp!, {r4-r8, lr}
- mov r6, r0 // arg table
- movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
- mov r4, r2 // function address
- mov r8, #0
- mov r0, r3 // objlast. might get overwritten
- str r3, [sp, #-4]! // objlast again.
- beq nomoreargsarmFuncObjLast
- // Load the first 4 arguments into r0-r3
- cmp r7, #4
- ldrge r0, [r6],#4
- cmp r7, #2*4
- ldrge r1, [r6],#4
- ldrlt r1, [sp]
- cmp r7, #3*4
- ldrge r2, [r6],#4
- ldrlt r2, [sp]
- cmp r7, #4*4
- ldrge r3, [r6],#4
- ldrlt r3, [sp]
- ble nomoreargsarmFuncObjLast
- // Load the rest of the arguments onto the stack
- sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
- sub sp, sp, r7
- mov r8, r7
- stackargslooparmFuncObjLast:
- ldr r5, [r6], #4
- str r5, [sp], #4
- subs r7, r7, #4
- bne stackargslooparmFuncObjLast
- nomoreargsarmFuncObjLast:
- sub sp, sp, r8
- blx r4
- add sp, sp, r8
- add sp, sp, #4
- ldmia sp!, {r4-r8, pc}
- _armFuncR0ObjLast:
- stmdb sp!, {r4-r8, lr}
- ldr r7, [sp,#6*4]
- str r7, [sp,#-4]!
- mov r6, r0 // arg table
- movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
- mov r4, r2 // function address
- mov r8, #0
- mov r0, r3 // r0 explicitly set
- ldr r1, [sp] // objlast. might get overwritten
- beq nomoreargsarmFuncR0ObjLast
- // Load the first 3 arguments into r1-r3
- cmp r7, #1*4
- ldrge r1, [r6],#4
- cmp r7, #2*4
- ldrge r2, [r6],#4
- ldrlt r2, [sp]
- cmp r7, #3*4
- ldrge r3, [r6],#4
- ldrlt r3, [sp]
- ble nomoreargsarmFuncR0ObjLast
- // Load the rest of the arguments onto the stack
- sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
- sub sp, sp, r7
- mov r8, r7
- stackargslooparmFuncR0ObjLast:
- ldr r5, [r6], #4
- str r5, [sp], #4
- subs r7, r7, #4
- bne stackargslooparmFuncR0ObjLast
- nomoreargsarmFuncR0ObjLast:
- sub sp, sp, r8
- blx r4
- add sp, sp, r8
- add sp, sp, #4
- ldmia sp!, {r4-r8, pc}
- _armFuncR0:
- stmdb sp!, {r4-r8, lr}
- mov r6, r0 // arg table
- movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
- mov r4, r2 // function address
- mov r8, #0
- mov r0, r3 // r0 explicitly set
- beq nomoreargsarmFuncR0
- // Load the first 3 arguments into r1-r3
- cmp r7, #1*4
- ldrge r1, [r6],#4
- cmp r7, #2*4
- ldrge r2, [r6],#4
- cmp r7, #3*4
- ldrge r3, [r6],#4
- ble nomoreargsarmFuncR0
- // Load the rest of the arguments onto the stack
- sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
- sub sp, sp, r7
- mov r8, r7
- stackargslooparmFuncR0:
- ldr r5, [r6], #4
- str r5, [sp], #4
- subs r7, r7, #4
- bne stackargslooparmFuncR0
- nomoreargsarmFuncR0:
- sub sp, sp, r8
- blx r4
- add sp, sp, r8
- ldmia sp!, {r4-r8, pc}
- _armFuncR0R1:
- stmdb sp!, {r4-r8, lr}
- mov r6, r0 // arg table
- movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
- mov r4, r2 // function address
- mov r8, #0
- mov r0, r3 // r0 explicitly set
- ldr r1, [sp, #6*4] // r1 explicitly set too
- beq nomoreargsarmFuncR0R1
- // Load the first 2 arguments into r2-r3
- cmp r7, #1*4
- ldrge r2, [r6],#4
- cmp r7, #2*4
- ldrge r3, [r6],#4
- ble nomoreargsarmFuncR0R1
- // Load the rest of the arguments onto the stack
- sub r7, r7, #2*4 // skip the 2 registers already loaded into r2-r3
- sub sp, sp, r7
- mov r8, r7
- stackargslooparmFuncR0R1:
- ldr r5, [r6], #4
- str r5, [sp], #4
- subs r7, r7, #4
- bne stackargslooparmFuncR0R1
- nomoreargsarmFuncR0R1:
- sub sp, sp, r8
- blx r4
- add sp, sp, r8
- ldmia sp!, {r4-r8, pc}
- #endif
- #endif /* !AS_MAX_PORTABILITY */
|