Mercurial > pub > dyncall > dyncall
comparison 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 |
comparison
equal
deleted
inserted
replaced
405:e221473a8217 | 406:351bb41d3bb1 |
---|---|
4 Library: dyncall | 4 Library: dyncall |
5 File: dyncall/dyncall_call_arm32_thumb_gas.s | 5 File: dyncall/dyncall_call_arm32_thumb_gas.s |
6 Description: ARM Thumb call kernel implementation for GNU assembler. | 6 Description: ARM Thumb call kernel implementation for GNU assembler. |
7 License: | 7 License: |
8 | 8 |
9 Copyright (c) 2007-2011 Daniel Adler <dadler@uni-goettingen.de>, | 9 Copyright (c) 2007-2021 Daniel Adler <dadler@uni-goettingen.de>, |
10 Tassilo Philipp <tphilipp@potion-studios.com> | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 | 11 |
12 Permission to use, copy, modify, and distribute this software for any | 12 Permission to use, copy, modify, and distribute this software for any |
13 purpose with or without fee is hereby granted, provided that the above | 13 purpose with or without fee is hereby granted, provided that the above |
14 copyright notice and this permission notice appear in all copies. | 14 copyright notice and this permission notice appear in all copies. |
35 .thumb_func | 35 .thumb_func |
36 dcCall_arm32_thumb: | 36 dcCall_arm32_thumb: |
37 | 37 |
38 /* Prolog. This function never needs to spill inside its prolog, so just store the permanent registers. */ | 38 /* Prolog. This function never needs to spill inside its prolog, so just store the permanent registers. */ |
39 /* Code below is not using high registers, so not storing them in prolog, which is more involved with thumb, anyways. */ | 39 /* Code below is not using high registers, so not storing them in prolog, which is more involved with thumb, anyways. */ |
40 push {%r4-%r7, %r14} /* Frame ptr, permanent registers, link register -> save area on stack. */ | 40 push {r4-r7, r14} /* Frame ptr, permanent registers, link register -> save area on stack. */ |
41 mov %r7, %r13 /* Set frame ptr. */ | 41 mov r7, r13 /* Set frame ptr. */ |
42 sub %r13, #4 /* Realign stack to 8 bytes (b/c we stored 5 regs = 20b). */ | 42 sub r13, #4 /* Realign stack to 8 bytes (b/c we stored 5 regs = 20b). */ |
43 | 43 |
44 /* Call. */ | 44 /* Call. */ |
45 mov %r4, %r0 /* Move 'fptr' to r4 (1st argument is passed in r0). */ | 45 mov r4, r0 /* Move 'fptr' to r4 (1st argument is passed in r0). */ |
46 mov %r5, %r1 /* Move 'args' to r5 (2nd argument is passed in r1). */ | 46 mov r5, r1 /* Move 'args' to r5 (2nd argument is passed in r1). */ |
47 mov %r6, %r2 /* Move 'size' to r6 (3rd argument is passed in r2). */ | 47 mov r6, r2 /* Move 'size' to r6 (3rd argument is passed in r2). */ |
48 | 48 |
49 cmp %r6, #16 /* Jump to call if no more than 4 arguments. */ | 49 cmp r6, #16 /* Jump to call if no more than 4 arguments. */ |
50 ble call | 50 ble call |
51 | 51 |
52 sub %r6, #16 /* Size of remaining arguments. */ | 52 sub r6, #16 /* Size of remaining arguments. */ |
53 mov %r0, %r13 /* Set stack pointer to top of stack. */ | 53 mov r0, r13 /* Set stack pointer to top of stack. */ |
54 sub %r0, %r0, %r6 | 54 sub r0, r0, r6 |
55 lsr %r0, #3 /* Align stack on 8 byte boundaries. */ | 55 lsr r0, #3 /* Align stack on 8 byte boundaries. */ |
56 lsl %r0, #3 | 56 lsl r0, #3 |
57 mov %r13, %r0 | 57 mov r13, r0 |
58 | 58 |
59 add %r1, #16 /* Let r1 point to remaining arguments. */ | 59 add r1, #16 /* Let r1 point to remaining arguments. */ |
60 mov %r2, #0 /* Init byte counter to 0. */ | 60 mov r2, #0 /* Init byte counter to 0. */ |
61 .thumb_func | 61 .thumb_func |
62 pushArgs: | 62 pushArgs: |
63 ldrb %r3, [%r1, %r2] /* Load a byte into r3. */ | 63 ldrb r3, [r1, r2] /* Load a byte into r3. */ |
64 strb %r3, [%r0, %r2] /* Push byte onto stack. */ | 64 strb r3, [r0, r2] /* Push byte onto stack. */ |
65 add %r2, %r2, #1 /* Increment byte counter. */ | 65 add r2, r2, #1 /* Increment byte counter. */ |
66 cmp %r2, %r6 | 66 cmp r2, r6 |
67 bne pushArgs | 67 bne pushArgs |
68 .thumb_func | 68 .thumb_func |
69 call: | 69 call: |
70 ldmia %r5!, {%r0-%r3} /* Load first 4 arguments for new call into r0-r3. */ | 70 ldmia r5!, {r0-r3} /* Load first 4 arguments for new call into r0-r3. */ |
71 | 71 |
72 /* 'blx %r4' workaround for ARMv4t in THUMB: */ | 72 /* 'blx r4' workaround for ARMv4t in THUMB: */ |
73 mov %r6, %r15 /* Load PC+2 instructions from here */ | 73 mov r6, r15 /* Load PC+2 instructions from here */ |
74 add %r6, #5 /* Increment by 2 instructions (Address of 'Epilog') and set bit 0 (THUMB) */ | 74 add r6, #5 /* Increment by 2 instructions (Address of 'Epilog') and set bit 0 (THUMB) */ |
75 mov %r14, %r6 /* Store in link register. */ | 75 mov r14, r6 /* Store in link register. */ |
76 bx %r4 /* Branch and force THUMB-mode return (LR bit 0 set). */ | 76 bx r4 /* Branch and force THUMB-mode return (LR bit 0 set). */ |
77 | 77 |
78 /* Epilog. */ | 78 /* Epilog. */ |
79 mov %r13, %r7 /* Reset stack ptr. */ | 79 mov r13, r7 /* Reset stack ptr. */ |
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. */ | 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. */ |
81 | 81 |