0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_mips_n64_gas.s
|
|
6 Description: mips "n64" abi call kernel implementation in GNU Assembler
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2007-2011 Daniel Adler <dadler@uni-goettingen.de>,
|
|
10 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
11
|
|
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
|
|
14 copyright notice and this permission notice appear in all copies.
|
|
15
|
|
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
|
24 */
|
|
25
|
|
26 .section .mdebug.abi64
|
|
27 .previous
|
|
28 .abicalls
|
|
29 .text
|
|
30 .align 2
|
|
31 .globl dcCall_mips_n64
|
|
32 .ent dcCall_mips_n64
|
|
33 dcCall_mips_n64:
|
|
34
|
|
35 /* Stack-frame prolog */
|
|
36
|
|
37 # .frame $fp,64,$31 /* vars=16, regs=3/0, args=0, extra=16 */
|
|
38 # .mask 0xd0000000,-8
|
|
39 # .fmask 0x00000000,0
|
|
40 dsubu $sp,$sp,64
|
|
41 sd $31,48($sp) /* save return address register (ra) */
|
|
42 sd $30,40($sp) /* save frame pointer register (fp) */
|
|
43 sd $28,32($sp) /* save global pointer register (gp) */
|
|
44 move $fp,$sp
|
|
45
|
|
46
|
|
47 /* arguments: */
|
|
48
|
|
49 /* $4 target function */
|
|
50 /* $5 register data */
|
|
51 /* $6 stack size */
|
|
52 /* $7 stack data */
|
|
53
|
|
54
|
|
55 /* allocate argument stack space */
|
|
56
|
|
57 dsubu $sp, $sp, $6
|
|
58
|
|
59 /* copy stack data */
|
|
60
|
|
61 /* n64 abi call assumptions:
|
|
62 - stack data is 16-byte aligned.
|
|
63 - no extra-storage for arguments passed via registers.
|
|
64 */
|
|
65
|
|
66 /* $12 source pointer (parameter stack data) */
|
|
67 /* $14 destination (stack pointer) */
|
|
68 /* $6 byte count */
|
|
69
|
|
70 move $12, $7
|
|
71 move $14, $sp
|
|
72
|
|
73 .next:
|
|
74 beq $6, $0, .skip
|
|
75 # nop
|
|
76 daddiu $6, $6, -8
|
|
77 ld $2, 0($12)
|
|
78 sd $2, 0($14)
|
|
79 daddiu $12,$12, 8
|
|
80 daddiu $14,$14, 8
|
|
81 b .next
|
|
82 .skip:
|
|
83 move $25, $4
|
|
84
|
|
85 /* load registers */
|
|
86
|
|
87 /* locals: */
|
|
88 /* $13 = register data */
|
|
89 /* $14 = useDouble flags */
|
|
90 move $13, $5
|
|
91 ld $14, 128($13)
|
|
92
|
|
93 /* load integer parameter registers */
|
|
94
|
|
95 ld $4 , 0($13)
|
|
96 ld $5 , 8($13)
|
|
97 ld $6 ,16($13)
|
|
98 ld $7 ,24($13)
|
|
99 ld $8 ,32($13)
|
|
100 ld $9 ,40($13)
|
|
101 ld $10,48($13)
|
|
102 ld $11,56($13)
|
|
103
|
|
104 /* load float-or-double floating pointer parameter registers
|
|
105 a 64-bit bitmask given at byte offset 128 of regdata indicates
|
|
106 if loading a float (bit cleared) or double (bit set), starting
|
|
107 at bit position 0 in bitmask.
|
|
108 */
|
|
109 .t0:
|
|
110 and $15, $14, 1
|
|
111 bgtz $15, .d0
|
|
112 .f0:
|
|
113 l.s $f12, 64($13)
|
|
114 j .t1
|
|
115 .d0:
|
|
116 l.d $f12, 64($13)
|
|
117
|
|
118 .t1:
|
|
119 and $15, $14, 2
|
|
120 bgtz $15, .d1
|
|
121 .f1:
|
|
122 l.s $f13, 72($13)
|
|
123 j .t2
|
|
124 .d1:
|
|
125 l.d $f13, 72($13)
|
|
126 .t2:
|
|
127 and $15, $14, 4
|
|
128 bgtz $15, .d2
|
|
129 .f2:
|
|
130 l.s $f14, 80($13)
|
|
131 j .t3
|
|
132 .d2:
|
|
133 l.d $f14, 80($13)
|
|
134 .t3:
|
|
135 and $15, $14, 8
|
|
136 bgtz $15, .d3
|
|
137 .f3:
|
|
138 l.s $f15, 88($13)
|
|
139 j .t4
|
|
140 .d3:
|
|
141 l.d $f15, 88($13)
|
|
142 .t4:
|
|
143 and $15, $14, 16
|
|
144 bgtz $15, .d4
|
|
145 .f4:
|
|
146 l.s $f16, 96($13)
|
|
147 j .t5
|
|
148 .d4:
|
|
149 l.d $f16, 96($13)
|
|
150 .t5:
|
|
151 and $15, $14, 32
|
|
152 bgtz $15, .d5
|
|
153 .f5:
|
|
154 l.s $f17,104($13)
|
|
155 j .t6
|
|
156 .d5:
|
|
157 l.d $f17,104($13)
|
|
158 .t6:
|
|
159 and $15, $14, 64
|
|
160 bgtz $15, .d6
|
|
161 .f6:
|
|
162 l.s $f18,112($13)
|
|
163 j .t7
|
|
164 .d6:
|
|
165 l.d $f18,112($13)
|
|
166 .t7:
|
|
167 and $15, $14, 128
|
|
168 bgtz $15, .d7
|
|
169 .f7:
|
|
170 l.s $f19,120($13)
|
|
171 j .fregend
|
|
172 .d7:
|
|
173 l.d $f19,120($13)
|
|
174
|
|
175 .fregend:
|
|
176
|
|
177 /* jump-and-link to register $25 */
|
|
178
|
|
179 jal $31, $25
|
124
|
180 nop /* branch-delay slot - no nop according to gcc assembly */
|
|
181 /* output, but let's play safe */
|
0
|
182
|
|
183 /* Stack-frame epilog */
|
|
184 move $sp,$fp
|
|
185 ld $ra,48($sp) /* restore ra register */
|
|
186 ld $fp,40($sp) /* restore fp register */
|
|
187 ld $gp,32($sp) /* restore gp register */
|
|
188 daddu $sp,$sp,64
|
|
189 j $ra
|
|
190 .end dcCall_mips_n64
|
|
191 .size dcCall_mips_n64, .-dcCall_mips_n64
|
|
192
|