AngelscriptLanguageServer/server/src/Native/angelscript/source/as_callfunc_arm_msvc.asm

250 lines
6.8 KiB
NASM

;
; AngelCode Scripting Library
; Copyright (c) 2003-2014 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 used for Windows CE
; Written by Fredrik Ehnbom in June 2009
; MSVC currently doesn't support inline assembly for the ARM platform
; so this separate file is needed.
; Compile with Microsoft ARM assembler (armasm)
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
AREA |.rdata|, DATA, READONLY
EXPORT armFunc
EXPORT armFuncR0
EXPORT armFuncR0R1
EXPORT armFuncObjLast
EXPORT armFuncR0ObjLast
AREA |.text|, CODE, ARM, ALIGN=3
ALIGN 8
armFunc PROC
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}
ENDP
ALIGN 8
armFuncObjLast PROC
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 |nomoreargs@armFuncObjLast|
; 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 |nomoreargs@armFuncObjLast|
; 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@armFuncObjLast|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncObjLast|
|nomoreargs@armFuncObjLast|
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0ObjLast PROC
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 |nomoreargs@armFuncR0ObjLast|
; 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 |nomoreargs@armFuncR0ObjLast|
; 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
|stackargsloop@armFuncR0ObjLast|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0ObjLast|
|nomoreargs@armFuncR0ObjLast|
sub sp, sp, r8
blx r4
add sp, sp, r8
add sp, sp, #4
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0 PROC
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 |nomoreargs@armFuncR0|
; 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 |nomoreargs@armFuncR0|
; 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
|stackargsloop@armFuncR0|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0|
|nomoreargs@armFuncR0|
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
ENDP
ALIGN 8
armFuncR0R1 PROC
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 |nomoreargs@armFuncR0R1|
; 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 |nomoreargs@armFuncR0R1|
; 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
|stackargsloop@armFuncR0R1|
ldr r5, [r6], #4
str r5, [sp], #4
subs r7, r7, #4
bne |stackargsloop@armFuncR0R1|
|nomoreargs@armFuncR0R1|
sub sp, sp, r8
blx r4
add sp, sp, r8
ldmia sp!, {r4-r8, pc}
ENDP
END