]>
Commit | Line | Data |
---|---|---|
afba61d1 | 1 | /* mips16 floating point support code |
eb774d8d | 2 | Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. |
afba61d1 ILT |
3 | Contributed by Cygnus Support |
4 | ||
5 | This file is free software; you can redistribute it and/or modify it | |
6 | under the terms of the GNU General Public License as published by the | |
7 | Free Software Foundation; either version 2, or (at your option) any | |
8 | later version. | |
9 | ||
10 | In addition to the permissions in the GNU General Public License, the | |
11 | Free Software Foundation gives you unlimited permission to link the | |
12 | compiled version of this file with other programs, and to distribute | |
13 | those programs without any restriction coming from the use of this | |
14 | file. (The General Public License restrictions do apply in other | |
15 | respects; for example, they cover modification of the file, and | |
16 | distribution when not linked into another program.) | |
17 | ||
18 | This file is distributed in the hope that it will be useful, but | |
19 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 | General Public License for more details. | |
22 | ||
23 | You should have received a copy of the GNU General Public License | |
24 | along with this program; see the file COPYING. If not, write to | |
25 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
26 | Boston, MA 02111-1307, USA. */ | |
27 | ||
28 | /* As a special exception, if you link this library with other files, | |
29 | some of which are compiled with GCC, to produce an executable, | |
30 | this library does not by itself cause the resulting executable | |
31 | to be covered by the GNU General Public License. | |
32 | This exception does not however invalidate any other reasons why | |
33 | the executable file might be covered by the GNU General Public License. */ | |
34 | ||
35 | /* This file contains mips16 floating point support functions. These | |
36 | functions are called by mips16 code to handle floating point when | |
37 | -msoft-float is not used. They accept the arguments and return | |
38 | values using the soft-float calling convention, but do the actual | |
39 | operation using the hard floating point instructions. */ | |
40 | ||
41 | /* This file contains 32 bit assembly code. */ | |
42 | .set nomips16 | |
43 | ||
987ba558 | 44 | /* Start a function. */ |
afba61d1 ILT |
45 | |
46 | #define STARTFN(NAME) .globl NAME; .ent NAME; NAME: | |
47 | ||
48 | /* Finish a function. */ | |
49 | ||
50 | #define ENDFN(NAME) .end NAME | |
51 | ||
52 | /* Single precision math. */ | |
53 | ||
54 | /* This macro defines a function which loads two single precision | |
55 | values, performs an operation, and returns the single precision | |
56 | result. */ | |
57 | ||
58 | #define SFOP(NAME, OPCODE) \ | |
59 | STARTFN (NAME); \ | |
60 | .set noreorder; \ | |
61 | mtc1 $4,$f0; \ | |
62 | mtc1 $5,$f2; \ | |
63 | nop; \ | |
64 | OPCODE $f0,$f0,$f2; \ | |
65 | mfc1 $2,$f0; \ | |
66 | j $31; \ | |
67 | nop; \ | |
68 | .set reorder; \ | |
69 | ENDFN (NAME) | |
70 | ||
71 | #ifdef L_m16addsf3 | |
72 | SFOP(__mips16_addsf3, add.s) | |
73 | #endif | |
74 | #ifdef L_m16subsf3 | |
75 | SFOP(__mips16_subsf3, sub.s) | |
76 | #endif | |
77 | #ifdef L_m16mulsf3 | |
78 | SFOP(__mips16_mulsf3, mul.s) | |
79 | #endif | |
80 | #ifdef L_m16divsf3 | |
81 | SFOP(__mips16_divsf3, div.s) | |
82 | #endif | |
83 | ||
eb774d8d NS |
84 | #define SFOP2(NAME, OPCODE) \ |
85 | STARTFN (NAME); \ | |
86 | .set noreorder; \ | |
87 | mtc1 $4,$f0; \ | |
88 | nop; \ | |
89 | OPCODE $f0,$f0; \ | |
90 | mfc1 $2,$f0; \ | |
91 | j $31; \ | |
92 | nop; \ | |
93 | .set reorder; \ | |
94 | ENDFN (NAME) | |
95 | ||
96 | #ifdef L_m16negsf2 | |
97 | SFOP2(__mips16_negsf2, neg.s) | |
98 | #endif | |
99 | #ifdef L_m16abssf2 | |
100 | SFOP2(__mips16_abssf2, abs.s) | |
101 | #endif | |
102 | ||
afba61d1 ILT |
103 | /* Single precision comparisons. */ |
104 | ||
105 | /* This macro defines a function which loads two single precision | |
106 | values, performs a floating point comparison, and returns the | |
107 | specified values according to whether the comparison is true or | |
108 | false. */ | |
109 | ||
110 | #define SFCMP(NAME, OPCODE, TRUE, FALSE) \ | |
111 | STARTFN (NAME); \ | |
112 | mtc1 $4,$f0; \ | |
113 | mtc1 $5,$f2; \ | |
114 | OPCODE $f0,$f2; \ | |
115 | li $2,TRUE; \ | |
116 | bc1t 1f; \ | |
117 | li $2,FALSE; \ | |
118 | 1:; \ | |
119 | j $31; \ | |
120 | ENDFN (NAME) | |
121 | ||
122 | /* This macro is like SFCMP, but it reverses the comparison. */ | |
123 | ||
124 | #define SFREVCMP(NAME, OPCODE, TRUE, FALSE) \ | |
125 | STARTFN (NAME); \ | |
126 | mtc1 $4,$f0; \ | |
127 | mtc1 $5,$f2; \ | |
128 | OPCODE $f2,$f0; \ | |
129 | li $2,TRUE; \ | |
130 | bc1t 1f; \ | |
131 | li $2,FALSE; \ | |
132 | 1:; \ | |
133 | j $31; \ | |
134 | ENDFN (NAME) | |
135 | ||
136 | #ifdef L_m16eqsf2 | |
137 | SFCMP(__mips16_eqsf2, c.eq.s, 0, 1) | |
138 | #endif | |
139 | #ifdef L_m16nesf2 | |
140 | SFCMP(__mips16_nesf2, c.eq.s, 0, 1) | |
141 | #endif | |
142 | #ifdef L_m16gtsf2 | |
143 | SFREVCMP(__mips16_gtsf2, c.lt.s, 1, 0) | |
144 | #endif | |
145 | #ifdef L_m16gesf2 | |
146 | SFREVCMP(__mips16_gesf2, c.le.s, 0, -1) | |
147 | #endif | |
148 | #ifdef L_m16lesf2 | |
149 | SFCMP(__mips16_lesf2, c.le.s, 0, 1) | |
150 | #endif | |
151 | #ifdef L_m16ltsf2 | |
152 | SFCMP(__mips16_ltsf2, c.lt.s, -1, 0) | |
153 | #endif | |
154 | ||
155 | /* Single precision conversions. */ | |
156 | ||
157 | #ifdef L_m16fltsisf | |
158 | STARTFN (__mips16_floatsisf) | |
159 | .set noreorder | |
160 | mtc1 $4,$f0 | |
161 | nop | |
162 | cvt.s.w $f0,$f0 | |
163 | mfc1 $2,$f0 | |
164 | j $31 | |
165 | nop | |
166 | .set reorder | |
167 | ENDFN (__mips16_floatsisf) | |
168 | #endif | |
169 | ||
170 | #ifdef L_m16fixsfsi | |
171 | STARTFN (__mips16_fixsfsi) | |
172 | .set noreorder | |
173 | mtc1 $4,$f0 | |
174 | nop | |
175 | trunc.w.s $f0,$f0,$4 | |
176 | mfc1 $2,$f0 | |
177 | j $31 | |
178 | nop | |
179 | .set reorder | |
180 | ENDFN (__mips16_fixsfsi) | |
181 | #endif | |
182 | ||
eb774d8d NS |
183 | #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) |
184 | ||
afba61d1 ILT |
185 | /* The double precision operations. We need to use different code |
186 | based on the preprocessor symbol __mips64, because the way in which | |
187 | double precision values will change. Without __mips64, the value | |
188 | is passed in two 32 bit registers. With __mips64, the value is | |
189 | passed in a single 64 bit register. */ | |
190 | ||
191 | /* Load the first double precision operand. */ | |
192 | ||
eb774d8d NS |
193 | #if defined(__mips64) |
194 | #define LDDBL1 dmtc1 $4,$f12 | |
195 | #elif defined(__mipsfp64) | |
196 | #define LDDBL1 sw $4,0($29); sw $5,4($29); l.d $f12,0($29) | |
197 | #elif defined(__MIPSEB__) | |
198 | #define LDDBL1 mtc1 $4,$f13; mtc1 $5,$f12 | |
199 | #else | |
200 | #define LDDBL1 mtc1 $4,$f12; mtc1 $5,$f13 | |
afba61d1 ILT |
201 | #endif |
202 | ||
203 | /* Load the second double precision operand. */ | |
204 | ||
eb774d8d NS |
205 | #if defined(__mips64) |
206 | /* XXX this should be $6 for Algo arg passing model */ | |
207 | #define LDDBL2 dmtc1 $5,$f14 | |
208 | #elif defined(__mipsfp64) | |
209 | #define LDDBL2 sw $6,8($29); sw $7,12($29); l.d $f14,8($29) | |
210 | #elif defined(__MIPSEB__) | |
211 | #define LDDBL2 mtc1 $6,$f15; mtc1 $7,$f14 | |
212 | #else | |
213 | #define LDDBL2 mtc1 $6,$f14; mtc1 $7,$f15 | |
214 | #endif | |
215 | ||
afba61d1 ILT |
216 | /* Move the double precision return value to the right place. */ |
217 | ||
eb774d8d | 218 | #if defined(__mips64) |
afba61d1 | 219 | #define RETDBL dmfc1 $2,$f0 |
eb774d8d NS |
220 | #elif defined(__mipsfp64) |
221 | #define RETDBL s.d $f0,0($29); lw $2,0($29); lw $3,4($29) | |
222 | #elif defined(__MIPSEB__) | |
afba61d1 | 223 | #define RETDBL mfc1 $2,$f1; mfc1 $3,$f0 |
eb774d8d NS |
224 | #else |
225 | #define RETDBL mfc1 $2,$f0; mfc1 $3,$f1 | |
afba61d1 | 226 | #endif |
eb774d8d | 227 | |
afba61d1 ILT |
228 | /* Double precision math. */ |
229 | ||
230 | /* This macro defines a function which loads two double precision | |
231 | values, performs an operation, and returns the double precision | |
232 | result. */ | |
233 | ||
234 | #define DFOP(NAME, OPCODE) \ | |
235 | STARTFN (NAME); \ | |
236 | .set noreorder; \ | |
237 | LDDBL1; \ | |
238 | LDDBL2; \ | |
239 | nop; \ | |
eb774d8d | 240 | OPCODE $f0,$f12,$f14; \ |
afba61d1 ILT |
241 | RETDBL; \ |
242 | j $31; \ | |
243 | nop; \ | |
244 | .set reorder; \ | |
245 | ENDFN (NAME) | |
246 | ||
247 | #ifdef L_m16adddf3 | |
248 | DFOP(__mips16_adddf3, add.d) | |
249 | #endif | |
250 | #ifdef L_m16subdf3 | |
251 | DFOP(__mips16_subdf3, sub.d) | |
252 | #endif | |
253 | #ifdef L_m16muldf3 | |
254 | DFOP(__mips16_muldf3, mul.d) | |
255 | #endif | |
256 | #ifdef L_m16divdf3 | |
257 | DFOP(__mips16_divdf3, div.d) | |
258 | #endif | |
259 | ||
eb774d8d NS |
260 | #define DFOP2(NAME, OPCODE) \ |
261 | STARTFN (NAME); \ | |
262 | .set noreorder; \ | |
263 | LDDBL1; \ | |
264 | nop; \ | |
265 | OPCODE $f0,$f12; \ | |
266 | RETDBL; \ | |
267 | j $31; \ | |
268 | nop; \ | |
269 | .set reorder; \ | |
270 | ENDFN (NAME) | |
271 | ||
272 | #ifdef L_m16negdf2 | |
273 | DFOP2(__mips16_negdf2, neg.d) | |
274 | #endif | |
275 | #ifdef L_m16absdf2 | |
276 | DFOP2(__mips16_absdf2, abs.d) | |
277 | #endif | |
278 | ||
279 | ||
afba61d1 ILT |
280 | /* Conversions between single and double precision. */ |
281 | ||
282 | #ifdef L_m16extsfdf2 | |
283 | STARTFN (__mips16_extendsfdf2) | |
284 | .set noreorder | |
eb774d8d | 285 | mtc1 $4,$f12 |
afba61d1 | 286 | nop |
eb774d8d | 287 | cvt.d.s $f0,$f12 |
afba61d1 ILT |
288 | RETDBL |
289 | j $31 | |
290 | nop | |
291 | .set reorder | |
292 | ENDFN (__mips16_extendsfdf2) | |
293 | #endif | |
294 | ||
295 | #ifdef L_m16trdfsf2 | |
296 | STARTFN (__mips16_truncdfsf2) | |
297 | .set noreorder | |
298 | LDDBL1 | |
299 | nop | |
eb774d8d | 300 | cvt.s.d $f0,$f12 |
afba61d1 ILT |
301 | mfc1 $2,$f0 |
302 | j $31 | |
303 | nop | |
304 | .set reorder | |
305 | ENDFN (__mips16_truncdfsf2) | |
306 | #endif | |
307 | ||
308 | /* Double precision comparisons. */ | |
309 | ||
310 | /* This macro defines a function which loads two double precision | |
311 | values, performs a floating point comparison, and returns the | |
312 | specified values according to whether the comparison is true or | |
313 | false. */ | |
314 | ||
315 | #define DFCMP(NAME, OPCODE, TRUE, FALSE) \ | |
316 | STARTFN (NAME); \ | |
317 | LDDBL1; \ | |
318 | LDDBL2; \ | |
eb774d8d | 319 | OPCODE $f12,$f14; \ |
afba61d1 ILT |
320 | li $2,TRUE; \ |
321 | bc1t 1f; \ | |
322 | li $2,FALSE; \ | |
323 | 1:; \ | |
324 | j $31; \ | |
325 | ENDFN (NAME) | |
326 | ||
327 | /* This macro is like DFCMP, but it reverses the comparison. */ | |
328 | ||
329 | #define DFREVCMP(NAME, OPCODE, TRUE, FALSE) \ | |
330 | STARTFN (NAME); \ | |
331 | LDDBL1; \ | |
332 | LDDBL2; \ | |
a3bc83cc | 333 | OPCODE $f14,$f12; \ |
afba61d1 ILT |
334 | li $2,TRUE; \ |
335 | bc1t 1f; \ | |
336 | li $2,FALSE; \ | |
337 | 1:; \ | |
338 | j $31; \ | |
339 | ENDFN (NAME) | |
340 | ||
341 | #ifdef L_m16eqdf2 | |
342 | DFCMP(__mips16_eqdf2, c.eq.d, 0, 1) | |
343 | #endif | |
344 | #ifdef L_m16nedf2 | |
345 | DFCMP(__mips16_nedf2, c.eq.d, 0, 1) | |
346 | #endif | |
347 | #ifdef L_m16gtdf2 | |
348 | DFREVCMP(__mips16_gtdf2, c.lt.d, 1, 0) | |
349 | #endif | |
350 | #ifdef L_m16gedf2 | |
351 | DFREVCMP(__mips16_gedf2, c.le.d, 0, -1) | |
352 | #endif | |
353 | #ifdef L_m16ledf2 | |
354 | DFCMP(__mips16_ledf2, c.le.d, 0, 1) | |
355 | #endif | |
356 | #ifdef L_m16ltdf2 | |
357 | DFCMP(__mips16_ltdf2, c.lt.d, -1, 0) | |
358 | #endif | |
359 | ||
360 | /* Double precision conversions. */ | |
361 | ||
362 | #ifdef L_m16fltsidf | |
363 | STARTFN (__mips16_floatsidf) | |
364 | .set noreorder | |
eb774d8d | 365 | mtc1 $4,$f12 |
afba61d1 | 366 | nop |
eb774d8d | 367 | cvt.d.w $f0,$f12 |
afba61d1 ILT |
368 | RETDBL |
369 | j $31 | |
370 | nop | |
371 | .set reorder | |
372 | ENDFN (__mips16_floatsidf) | |
373 | #endif | |
374 | ||
375 | #ifdef L_m16fixdfsi | |
376 | STARTFN (__mips16_fixdfsi) | |
377 | .set noreorder | |
378 | LDDBL1 | |
379 | nop | |
eb774d8d | 380 | trunc.w.d $f0,$f12,$4 |
afba61d1 ILT |
381 | mfc1 $2,$f0 |
382 | j $31 | |
383 | nop | |
384 | .set reorder | |
385 | ENDFN (__mips16_fixdfsi) | |
386 | #endif | |
eb774d8d | 387 | #endif /* !__mips_single_float */ |
afba61d1 ILT |
388 | |
389 | /* These functions are used to return floating point values from | |
46b9a73c RS |
390 | mips16 functions. In this case we can put mtc1 in a jump delay slot, |
391 | because we know that the next instruction will not refer to a floating | |
392 | point register. */ | |
afba61d1 ILT |
393 | |
394 | #ifdef L_m16retsf | |
395 | STARTFN (__mips16_ret_sf) | |
396 | .set noreorder | |
397 | j $31 | |
398 | mtc1 $2,$f0 | |
399 | .set reorder | |
400 | ENDFN (__mips16_ret_sf) | |
401 | #endif | |
402 | ||
eb774d8d | 403 | #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) |
afba61d1 ILT |
404 | #ifdef L_m16retdf |
405 | STARTFN (__mips16_ret_df) | |
406 | .set noreorder | |
eb774d8d NS |
407 | #if defined(__mips64) |
408 | j $31 | |
409 | dmtc1 $2,$f0 | |
410 | #elif defined(__mipsfp64) | |
411 | sw $2,0($29) | |
412 | sw $3,4($29) | |
413 | l.d $f0,0($29) | |
414 | #elif defined(__MIPSEB__) | |
afba61d1 ILT |
415 | mtc1 $2,$f1 |
416 | j $31 | |
417 | mtc1 $3,$f0 | |
eb774d8d NS |
418 | #else |
419 | mtc1 $2,$f0 | |
420 | j $31 | |
421 | mtc1 $3,$f1 | |
422 | #endif | |
423 | .set reorder | |
afba61d1 ILT |
424 | ENDFN (__mips16_ret_df) |
425 | #endif | |
eb774d8d | 426 | #endif /* !__mips_single_float */ |
afba61d1 ILT |
427 | |
428 | /* These functions are used by 16 bit code when calling via a function | |
429 | pointer. They must copy the floating point arguments from the gp | |
430 | regs into the fp regs. The function to call will be in $2. The | |
431 | exact set of floating point arguments to copy is encoded in the | |
432 | function name; the final number is an fp_code, as described in | |
433 | mips.h in the comment about CUMULATIVE_ARGS. */ | |
434 | ||
435 | #ifdef L_m16stub1 | |
436 | /* (float) */ | |
437 | STARTFN (__mips16_call_stub_1) | |
438 | .set noreorder | |
439 | mtc1 $4,$f12 | |
440 | j $2 | |
441 | nop | |
442 | .set reorder | |
443 | ENDFN (__mips16_call_stub_1) | |
444 | #endif | |
445 | ||
afba61d1 ILT |
446 | #ifdef L_m16stub5 |
447 | /* (float, float) */ | |
448 | STARTFN (__mips16_call_stub_5) | |
449 | .set noreorder | |
450 | mtc1 $4,$f12 | |
451 | mtc1 $5,$f14 | |
452 | j $2 | |
453 | nop | |
454 | .set reorder | |
455 | ENDFN (__mips16_call_stub_5) | |
456 | #endif | |
457 | ||
eb774d8d NS |
458 | #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) |
459 | ||
460 | #ifdef L_m16stub2 | |
461 | /* (double) */ | |
462 | STARTFN (__mips16_call_stub_2) | |
463 | .set noreorder | |
464 | LDDBL1 | |
465 | j $2 | |
466 | nop | |
467 | .set reorder | |
468 | ENDFN (__mips16_call_stub_2) | |
469 | #endif | |
470 | ||
afba61d1 ILT |
471 | #ifdef L_m16stub6 |
472 | /* (double, float) */ | |
473 | STARTFN (__mips16_call_stub_6) | |
474 | .set noreorder | |
eb774d8d | 475 | LDDBL1 |
afba61d1 ILT |
476 | mtc1 $6,$f14 |
477 | j $2 | |
478 | nop | |
479 | .set reorder | |
480 | ENDFN (__mips16_call_stub_6) | |
481 | #endif | |
482 | ||
483 | #ifdef L_m16stub9 | |
484 | /* (float, double) */ | |
485 | STARTFN (__mips16_call_stub_9) | |
486 | .set noreorder | |
487 | mtc1 $4,$f12 | |
eb774d8d | 488 | LDDBL2 |
afba61d1 ILT |
489 | j $2 |
490 | nop | |
491 | .set reorder | |
492 | ENDFN (__mips16_call_stub_9) | |
493 | #endif | |
494 | ||
495 | #ifdef L_m16stub10 | |
496 | /* (double, double) */ | |
497 | STARTFN (__mips16_call_stub_10) | |
498 | .set noreorder | |
eb774d8d NS |
499 | LDDBL1 |
500 | LDDBL2 | |
afba61d1 ILT |
501 | j $2 |
502 | nop | |
503 | .set reorder | |
504 | ENDFN (__mips16_call_stub_10) | |
505 | #endif | |
eb774d8d | 506 | #endif /* !__mips_single_float */ |
afba61d1 ILT |
507 | |
508 | /* Now we have the same set of functions, except that this time the | |
509 | function being called returns an SFmode value. The calling | |
510 | function will arrange to preserve $18, so these functions are free | |
511 | to use it to hold the return address. | |
512 | ||
513 | Note that we do not know whether the function we are calling is 16 | |
514 | bit or 32 bit. However, it does not matter, because 16 bit | |
515 | functions always return floating point values in both the gp and | |
516 | the fp regs. It would be possible to check whether the function | |
517 | being called is 16 bits, in which case the copy is unnecessary; | |
518 | however, it's faster to always do the copy. */ | |
519 | ||
520 | #ifdef L_m16stubsf0 | |
521 | /* () */ | |
522 | STARTFN (__mips16_call_stub_sf_0) | |
523 | .set noreorder | |
524 | move $18,$31 | |
525 | jal $2 | |
526 | nop | |
eb774d8d | 527 | mfc1 $2,$f0 |
afba61d1 ILT |
528 | j $18 |
529 | nop | |
530 | .set reorder | |
531 | ENDFN (__mips16_call_stub_sf_0) | |
532 | #endif | |
533 | ||
534 | #ifdef L_m16stubsf1 | |
535 | /* (float) */ | |
536 | STARTFN (__mips16_call_stub_sf_1) | |
537 | .set noreorder | |
538 | mtc1 $4,$f12 | |
539 | move $18,$31 | |
540 | jal $2 | |
541 | nop | |
eb774d8d | 542 | mfc1 $2,$f0 |
afba61d1 ILT |
543 | j $18 |
544 | nop | |
545 | .set reorder | |
546 | ENDFN (__mips16_call_stub_sf_1) | |
547 | #endif | |
548 | ||
eb774d8d NS |
549 | #ifdef L_m16stubsf5 |
550 | /* (float, float) */ | |
551 | STARTFN (__mips16_call_stub_sf_5) | |
afba61d1 | 552 | .set noreorder |
eb774d8d NS |
553 | mtc1 $4,$f12 |
554 | mtc1 $5,$f14 | |
afba61d1 ILT |
555 | move $18,$31 |
556 | jal $2 | |
557 | nop | |
eb774d8d | 558 | mfc1 $2,$f0 |
afba61d1 ILT |
559 | j $18 |
560 | nop | |
561 | .set reorder | |
eb774d8d | 562 | ENDFN (__mips16_call_stub_sf_5) |
afba61d1 ILT |
563 | #endif |
564 | ||
eb774d8d NS |
565 | #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) |
566 | #ifdef L_m16stubsf2 | |
567 | /* (double) */ | |
568 | STARTFN (__mips16_call_stub_sf_2) | |
afba61d1 | 569 | .set noreorder |
eb774d8d | 570 | LDDBL1 |
afba61d1 ILT |
571 | move $18,$31 |
572 | jal $2 | |
573 | nop | |
eb774d8d | 574 | mfc1 $2,$f0 |
afba61d1 ILT |
575 | j $18 |
576 | nop | |
577 | .set reorder | |
eb774d8d | 578 | ENDFN (__mips16_call_stub_sf_2) |
afba61d1 ILT |
579 | #endif |
580 | ||
581 | #ifdef L_m16stubsf6 | |
582 | /* (double, float) */ | |
583 | STARTFN (__mips16_call_stub_sf_6) | |
584 | .set noreorder | |
eb774d8d | 585 | LDDBL1 |
afba61d1 ILT |
586 | mtc1 $6,$f14 |
587 | move $18,$31 | |
588 | jal $2 | |
589 | nop | |
eb774d8d | 590 | mfc1 $2,$f0 |
afba61d1 ILT |
591 | j $18 |
592 | nop | |
593 | .set reorder | |
594 | ENDFN (__mips16_call_stub_sf_6) | |
595 | #endif | |
596 | ||
597 | #ifdef L_m16stubsf9 | |
598 | /* (float, double) */ | |
599 | STARTFN (__mips16_call_stub_sf_9) | |
600 | .set noreorder | |
601 | mtc1 $4,$f12 | |
eb774d8d | 602 | LDDBL2 |
afba61d1 ILT |
603 | move $18,$31 |
604 | jal $2 | |
605 | nop | |
eb774d8d | 606 | mfc1 $2,$f0 |
afba61d1 ILT |
607 | j $18 |
608 | nop | |
609 | .set reorder | |
610 | ENDFN (__mips16_call_stub_sf_9) | |
611 | #endif | |
612 | ||
613 | #ifdef L_m16stubsf10 | |
614 | /* (double, double) */ | |
615 | STARTFN (__mips16_call_stub_sf_10) | |
616 | .set noreorder | |
eb774d8d NS |
617 | LDDBL1 |
618 | LDDBL2 | |
afba61d1 ILT |
619 | move $18,$31 |
620 | jal $2 | |
621 | nop | |
eb774d8d | 622 | mfc1 $2,$f0 |
afba61d1 ILT |
623 | j $18 |
624 | nop | |
625 | .set reorder | |
626 | ENDFN (__mips16_call_stub_sf_10) | |
627 | #endif | |
628 | ||
629 | /* Now we have the same set of functions again, except that this time | |
630 | the function being called returns an DFmode value. */ | |
631 | ||
632 | #ifdef L_m16stubdf0 | |
633 | /* () */ | |
634 | STARTFN (__mips16_call_stub_df_0) | |
635 | .set noreorder | |
636 | move $18,$31 | |
637 | jal $2 | |
638 | nop | |
eb774d8d | 639 | RETDBL |
afba61d1 ILT |
640 | j $18 |
641 | nop | |
642 | .set reorder | |
643 | ENDFN (__mips16_call_stub_df_0) | |
644 | #endif | |
645 | ||
646 | #ifdef L_m16stubdf1 | |
647 | /* (float) */ | |
648 | STARTFN (__mips16_call_stub_df_1) | |
649 | .set noreorder | |
650 | mtc1 $4,$f12 | |
651 | move $18,$31 | |
652 | jal $2 | |
653 | nop | |
eb774d8d | 654 | RETDBL |
afba61d1 ILT |
655 | j $18 |
656 | nop | |
657 | .set reorder | |
658 | ENDFN (__mips16_call_stub_df_1) | |
659 | #endif | |
660 | ||
661 | #ifdef L_m16stubdf2 | |
662 | /* (double) */ | |
663 | STARTFN (__mips16_call_stub_df_2) | |
664 | .set noreorder | |
eb774d8d | 665 | LDDBL1 |
afba61d1 ILT |
666 | move $18,$31 |
667 | jal $2 | |
668 | nop | |
eb774d8d | 669 | RETDBL |
afba61d1 ILT |
670 | j $18 |
671 | nop | |
672 | .set reorder | |
673 | ENDFN (__mips16_call_stub_df_2) | |
674 | #endif | |
675 | ||
676 | #ifdef L_m16stubdf5 | |
677 | /* (float, float) */ | |
678 | STARTFN (__mips16_call_stub_df_5) | |
679 | .set noreorder | |
680 | mtc1 $4,$f12 | |
681 | mtc1 $5,$f14 | |
682 | move $18,$31 | |
683 | jal $2 | |
684 | nop | |
eb774d8d | 685 | RETDBL |
afba61d1 ILT |
686 | j $18 |
687 | nop | |
688 | .set reorder | |
689 | ENDFN (__mips16_call_stub_df_5) | |
690 | #endif | |
691 | ||
692 | #ifdef L_m16stubdf6 | |
693 | /* (double, float) */ | |
694 | STARTFN (__mips16_call_stub_df_6) | |
695 | .set noreorder | |
eb774d8d | 696 | LDDBL1 |
afba61d1 ILT |
697 | mtc1 $6,$f14 |
698 | move $18,$31 | |
699 | jal $2 | |
700 | nop | |
eb774d8d | 701 | RETDBL |
afba61d1 ILT |
702 | j $18 |
703 | nop | |
704 | .set reorder | |
705 | ENDFN (__mips16_call_stub_df_6) | |
706 | #endif | |
707 | ||
708 | #ifdef L_m16stubdf9 | |
709 | /* (float, double) */ | |
710 | STARTFN (__mips16_call_stub_df_9) | |
711 | .set noreorder | |
712 | mtc1 $4,$f12 | |
eb774d8d | 713 | LDDBL2 |
afba61d1 ILT |
714 | move $18,$31 |
715 | jal $2 | |
716 | nop | |
eb774d8d | 717 | RETDBL |
afba61d1 ILT |
718 | j $18 |
719 | nop | |
720 | .set reorder | |
721 | ENDFN (__mips16_call_stub_df_9) | |
722 | #endif | |
723 | ||
724 | #ifdef L_m16stubdf10 | |
725 | /* (double, double) */ | |
726 | STARTFN (__mips16_call_stub_df_10) | |
727 | .set noreorder | |
eb774d8d NS |
728 | LDDBL1 |
729 | LDDBL2 | |
afba61d1 ILT |
730 | move $18,$31 |
731 | jal $2 | |
732 | nop | |
eb774d8d | 733 | RETDBL |
afba61d1 ILT |
734 | j $18 |
735 | nop | |
736 | .set reorder | |
737 | ENDFN (__mips16_call_stub_df_10) | |
738 | #endif | |
eb774d8d NS |
739 | #endif /* !__mips_single_float */ |
740 |