annotate dyncall/dyncall_call_arm32_thumb_gas.s @ 315:3840e0188520

- allowing lookup of running executable's path by passing NULL to dynload's dlGetLibraryPath()
author Tassilo Philipp
date Wed, 06 Nov 2019 14:13:49 +0100
parents 00dd15cc5c87
children 351bb41d3bb1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 Package: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Library: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncall/dyncall_call_arm32_thumb_gas.s
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description: ARM Thumb call kernel implementation for GNU assembler.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 License:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 Copyright (c) 2007-2011 Daniel Adler <dadler@uni-goettingen.de>,
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 Tassilo Philipp <tphilipp@potion-studios.com>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 .text
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 #if !defined(__thumb2__)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 .code 16 /* THUMB mode */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 #endif
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 .globl dcCall_arm32_thumb
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 /* Main dyncall call. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 .thumb_func
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 dcCall_arm32_thumb:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 /* Prolog. This function never needs to spill inside its prolog, so just store the permanent registers. */
175
00dd15cc5c87 - fixed ARM32-THUMB stack alignment issues (found on Cortex-m0, thanks Darren Whobrey!)
cslag
parents: 27
diff changeset
39 /* Code below is not using high registers, so not storing them in prolog, which is more involved with thumb, anyways. */
00dd15cc5c87 - fixed ARM32-THUMB stack alignment issues (found on Cortex-m0, thanks Darren Whobrey!)
cslag
parents: 27
diff changeset
40 push {%r4-%r7, %r14} /* Frame ptr, permanent registers, link register -> save area on stack. */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 mov %r7, %r13 /* Set frame ptr. */
175
00dd15cc5c87 - fixed ARM32-THUMB stack alignment issues (found on Cortex-m0, thanks Darren Whobrey!)
cslag
parents: 27
diff changeset
42 sub %r13, #4 /* Realign stack to 8 bytes (b/c we stored 5 regs = 20b). */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 /* Call. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 mov %r4, %r0 /* Move 'fptr' to r4 (1st argument is passed in r0). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 mov %r5, %r1 /* Move 'args' to r5 (2nd argument is passed in r1). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 mov %r6, %r2 /* Move 'size' to r6 (3rd argument is passed in r2). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 cmp %r6, #16 /* Jump to call if no more than 4 arguments. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 ble call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 sub %r6, #16 /* Size of remaining arguments. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 mov %r0, %r13 /* Set stack pointer to top of stack. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 sub %r0, %r0, %r6
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 lsr %r0, #3 /* Align stack on 8 byte boundaries. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 lsl %r0, #3
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 mov %r13, %r0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 add %r1, #16 /* Let r1 point to remaining arguments. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 mov %r2, #0 /* Init byte counter to 0. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 .thumb_func
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 pushArgs:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 ldrb %r3, [%r1, %r2] /* Load a byte into r3. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 strb %r3, [%r0, %r2] /* Push byte onto stack. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 add %r2, %r2, #1 /* Increment byte counter. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 cmp %r2, %r6
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 bne pushArgs
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 .thumb_func
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 call:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 ldmia %r5!, {%r0-%r3} /* Load first 4 arguments for new call into r0-r3. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 /* 'blx %r4' workaround for ARMv4t in THUMB: */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 mov %r6, %r15 /* Load PC+2 instructions from here */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 add %r6, #5 /* Increment by 2 instructions (Address of 'Epilog') and set bit 0 (THUMB) */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 mov %r14, %r6 /* Store in link register. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 bx %r4 /* Branch and force THUMB-mode return (LR bit 0 set). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 /* Epilog. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 mov %r13, %r7 /* Reset stack ptr. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 pop {%r4-%r7, %r15} /* Restore permanent registers and program counter. (Force a stay in THUMB in ARMv4, whether ARMv5 can return in ARM or THUMB depending on the bit 0. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81