annotate dyncall/dyncall_call_arm32_thumb_gas.s @ 663:127b569978cc default tip

- another tweak handling clang trying to be too smart (see last commit)
author Tassilo Philipp
date Sun, 24 Mar 2024 13:52:44 +0100
parents 351bb41d3bb1
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