comparison dyncallback/dyncall_callback_ppc32.S @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children c04be81f4874
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
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
9 Copyright (c) 2015 Daniel Adler <dadler@uni-goettingen.de>
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
28 .machine ppc
29 .text
30 .align 2
31
32 /* Struct DCCallback */
33
34 DCB_THUNK = 0
35 DCB_HANDLER = 24
36 DCB_CLEANUP = 28
37 DCB_USERDATA = 32
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:
77 r1 Stack Pointer
78 r3-r10 Integer Arguments
79 f1-f8 Floating-point Arguments
80 r11 Thunk Pointer
81
82 */
83
84 /* prolog */
85
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 */
89 stwu r1, -FRAMESIZE(r1)
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)
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)
99
100 stfd f1, SP_FREGS + 0*8(r1) /* spill 8 (of 13) float parameter registers */
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
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 is thunk pointer) */
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 */
120
121 /* branch-and-link to DCCallback.handler */
122 lwz r12, DCB_HANDLER(r11)
123 mtctr r12
124 bctrl
125 /* check result type */
126 cmpi cr0, r3, 'f
127 beq .f32
128 cmpi cr0, r3, 'd
129 beq .f64
130 .i64:
131 lwz r3, SP_RESULT (r1)
132 lwz r4, SP_RESULT + 4 (r1)
133 .end:
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
141 .f64:
142 lfd f1, SP_RESULT(r1)
143 b .end
144