Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_callback_ppc32.S @ 588:dfc2e6ee8782 r1.4-RC3
- more robust endian detection, on some platforms inclusion of endian.h led to assuming wrong endianness (subtle if inclusion was in
- syscall test: added newline to output
author | Tassilo Philipp |
---|---|
date | Mon, 19 Sep 2022 09:54:21 +0200 |
parents | 26aa936d4841 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
5 File: dyncallback/dyncall_callback_ppc32.S | |
6 Description: Callback Thunk Entry for PowerPC 32-bit System V Big-Endian ABI | |
7 License: | |
8 | |
281 | 9 Copyright (c) 2015-2018 Daniel Adler <dadler@uni-goettingen.de> |
0 | 10 |
11 Permission to use, copy, modify, and distribute this software for any | |
12 purpose with or without fee is hereby granted, provided that the above | |
13 copyright notice and this permission notice appear in all copies. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
22 | |
23 */ | |
24 | |
25 | |
26 #include "../portasm/portasm-ppc.S" | |
27 | |
369
26aa936d4841
- removed all .machine ppc pseudo-ops (see prev commit)
Tassilo Philipp
parents:
368
diff
changeset
|
28 /* .machine ppc /* clang's integrated as doesn't handle this on anything but Darwin (at least for clang <= 9) */ |
239 | 29 .text |
30 .align 2 | |
0 | 31 |
32 /* Struct DCCallback */ | |
33 | |
239 | 34 DCB_THUNK = 0 |
35 DCB_HANDLER = 24 | |
36 DCB_CLEANUP = 28 | |
37 DCB_USERDATA = 32 | |
0 | 38 |
39 /* Struct DCArgs */ | |
40 | |
41 ARGS_IREGS = 0 | |
42 ARGS_FREGS = ARGS_IREGS + 4*8 | |
43 ARGS_SP = ARGS_FREGS + 8*13 | |
44 ARGS_ICNT = ARGS_SP + 4 | |
45 ARGS_FCNT = ARGS_ICNT + 4 | |
46 ARGS_SIZE = ARGS_FCNT + 4 | |
47 | |
48 /* Struct DCValue */ | |
49 | |
50 RESULT_SIZE = 8 | |
51 | |
52 /* Stack Offsets: */ | |
53 | |
54 SP_PREV = 0 | |
55 SP_LR = (SP_PREV + 4) | |
56 SP_PAR = SP_LR + 4 | |
57 PAR_SZ = 0 | |
58 SP_ARGS = SP_PAR + PAR_SZ | |
59 SP_IREGS = SP_ARGS + ARGS_IREGS | |
60 SP_FREGS = SP_ARGS + ARGS_FREGS | |
61 SP_SP = SP_ARGS + ARGS_SP | |
62 SP_ICNT = SP_ARGS + ARGS_ICNT | |
63 SP_FCNT = SP_ARGS + ARGS_FCNT | |
64 SP_RESULT = SP_ARGS + ARGS_SIZE | |
65 SP_SIZE = SP_RESULT + RESULT_SIZE | |
66 | |
67 #define ALIGN(M,X) ( M+(X-1) & (-X) ) | |
68 | |
69 FRAMESIZE = ALIGN(SP_SIZE,16) | |
70 | |
71 GLOBAL_C(dcCallbackThunkEntry) | |
72 ENTRY_C(dcCallbackThunkEntry) | |
73 | |
74 /* -------------------------------------------------------------------------- | |
75 | |
76 Input: | |
239 | 77 r1 Stack Pointer |
78 r3-r10 Integer Arguments | |
79 f1-f8 Floating-point Arguments | |
80 r11 Thunk Pointer | |
0 | 81 |
82 */ | |
239 | 83 |
0 | 84 /* prolog */ |
85 | |
239 | 86 mflr r0 |
87 stw r0, SP_LR(r1) /* store return address */ | |
88 addi r12,r1, SP_PAR /* temporary r12: parameter area on callers stack frame */ | |
0 | 89 stwu r1, -FRAMESIZE(r1) |
239 | 90 |
91 stw r3, SP_IREGS + 0*4(r1) /* spill 8 integer parameter registers */ | |
92 stw r4, SP_IREGS + 1*4(r1) | |
93 stw r5, SP_IREGS + 2*4(r1) | |
0 | 94 stw r6, SP_IREGS + 3*4(r1) |
95 stw r7, SP_IREGS + 4*4(r1) | |
96 stw r8, SP_IREGS + 5*4(r1) | |
97 stw r9, SP_IREGS + 6*4(r1) | |
98 stw r10,SP_IREGS + 7*4(r1) | |
239 | 99 |
100 stfd f1, SP_FREGS + 0*8(r1) /* spill 8 (of 13) float parameter registers */ | |
0 | 101 stfd f2, SP_FREGS + 1*8(r1) |
102 stfd f3, SP_FREGS + 2*8(r1) | |
103 stfd f4, SP_FREGS + 3*8(r1) | |
104 stfd f5, SP_FREGS + 4*8(r1) | |
105 stfd f6, SP_FREGS + 5*8(r1) | |
106 stfd f7, SP_FREGS + 6*8(r1) | |
107 stfd f8, SP_FREGS + 7*8(r1) | |
108 | |
239 | 109 stw r12,SP_SP(r1) /* init stack pointer */ |
110 xor r0, r0, r0 /* init register counters */ | |
111 stw r0, SP_ICNT(r1) | |
112 stw r0, SP_FCNT(r1) | |
113 stw r0, SP_RESULT(r1) /* init result object */ | |
114 stw r0, SP_RESULT + 4(r1) | |
115 /* invoke callback handler */ | |
116 mr r3, r11 /* arg 1: DCCallback* pcb (r11 = thunk ptr) */ | |
117 addi r4, r1, SP_ARGS /* arg 2: DCArgs* args */ | |
118 addi r5, r1, SP_RESULT /* arg 3: DCValue* result */ | |
119 lwz r6, DCB_USERDATA(r11) /* arg 4: void* userdata */ | |
0 | 120 |
239 | 121 /* branch-and-link to DCCallback.handler */ |
122 lwz r12, DCB_HANDLER(r11) | |
123 mtctr r12 | |
0 | 124 bctrl |
239 | 125 /* check result type */ |
357
d982a00c2177
- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
Tassilo Philipp
parents:
281
diff
changeset
|
126 cmpi cr0, 0, r3, 0x66 /* 'f */ |
239 | 127 beq .f32 |
357
d982a00c2177
- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
Tassilo Philipp
parents:
281
diff
changeset
|
128 cmpi cr0, 0, r3, 0x64 /* 'd */ |
239 | 129 beq .f64 |
0 | 130 .i64: |
239 | 131 lwz r3, SP_RESULT (r1) |
132 lwz r4, SP_RESULT + 4 (r1) | |
0 | 133 .end: |
239 | 134 lwz r1, SP_PREV(r1) /* restore stack pointer */ |
135 lwz r0, SP_LR(r1) /* load link register with return address */ | |
136 mtlr r0 | |
137 blr /* branch back to link register */ | |
138 .f32: | |
139 lfs f1, SP_RESULT(r1) | |
140 b .end | |
0 | 141 .f64: |
239 | 142 lfd f1, SP_RESULT(r1) |
143 b .end | |
144 |