annotate dyncall/dyncall_call_arm32_thumb_gas.s @ 406:351bb41d3bb1

- removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
author Tassilo Philipp
date Sun, 03 Oct 2021 10:34:56 +0200
parents 00dd15cc5c87
children
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
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
9 Copyright (c) 2007-2021 Daniel Adler <dadler@uni-goettingen.de>,
0
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. */
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
40 push {r4-r7, r14} /* Frame ptr, permanent registers, link register -> save area on stack. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
41 mov r7, r13 /* Set frame ptr. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
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. */
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
45 mov r4, r0 /* Move 'fptr' to r4 (1st argument is passed in r0). */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
46 mov r5, r1 /* Move 'args' to r5 (2nd argument is passed in r1). */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
47 mov r6, r2 /* Move 'size' to r6 (3rd argument is passed in r2). */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
49 cmp r6, #16 /* Jump to call if no more than 4 arguments. */
0
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
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
52 sub r6, #16 /* Size of remaining arguments. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
53 mov r0, r13 /* Set stack pointer to top of stack. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
54 sub r0, r0, r6
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
55 lsr r0, #3 /* Align stack on 8 byte boundaries. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
56 lsl r0, #3
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
57 mov r13, r0
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
59 add r1, #16 /* Let r1 point to remaining arguments. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
60 mov r2, #0 /* Init byte counter to 0. */
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:
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
63 ldrb r3, [r1, r2] /* Load a byte into r3. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
64 strb r3, [r0, r2] /* Push byte onto stack. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
65 add r2, r2, #1 /* Increment byte counter. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
66 cmp r2, r6
0
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:
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
70 ldmia r5!, {r0-r3} /* Load first 4 arguments for new call into r0-r3. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
71
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
72 /* 'blx r4' workaround for ARMv4t in THUMB: */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
73 mov r6, r15 /* Load PC+2 instructions from here */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
74 add r6, #5 /* Increment by 2 instructions (Address of 'Epilog') and set bit 0 (THUMB) */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
75 mov r14, r6 /* Store in link register. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
76 bx r4 /* Branch and force THUMB-mode return (LR bit 0 set). */
0
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. */
406
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
diff changeset
79 mov r13, r7 /* Reset stack ptr. */
351bb41d3bb1 - removed %-prefixes for register names from arm assembly files (was wrong to begin with, gas accepted them but the clang integrated assembler does not)
Tassilo Philipp
parents: 175
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. */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81