]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/mips/mips16.S
extend.texi: (micromips, nomicromips, nocompression): Document new function attributes.
[thirdparty/gcc.git] / libgcc / config / mips / mips16.S
1 /* mips16 floating point support code
2 Copyright (C) 1996-2013 Free Software Foundation, Inc.
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 3, or (at your option) any
8 later version.
9
10 This file is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 #ifdef __mips_micromips
25 /* DO NOTHING */
26 #else
27
28 /* This file contains mips16 floating point support functions. These
29 functions are called by mips16 code to handle floating point when
30 -msoft-float is not used. They accept the arguments and return
31 values using the soft-float calling convention, but do the actual
32 operation using the hard floating point instructions. */
33
34 #if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64)
35
36 /* This file contains 32-bit assembly code. */
37 .set nomips16
38
39 /* Start a function. */
40
41 #define STARTFN(NAME) .globl NAME; .ent NAME; NAME:
42
43 /* Finish a function. */
44
45 #define ENDFN(NAME) .end NAME
46
47 /* ARG1
48 The FPR that holds the first floating-point argument.
49
50 ARG2
51 The FPR that holds the second floating-point argument.
52
53 RET
54 The FPR that holds a floating-point return value. */
55
56 #define RET $f0
57 #define ARG1 $f12
58 #ifdef __mips64
59 #define ARG2 $f13
60 #else
61 #define ARG2 $f14
62 #endif
63
64 /* Set 64-bit register GPR so that its high 32 bits contain HIGH_FPR
65 and so that its low 32 bits contain LOW_FPR. */
66 #define MERGE_GPRf(GPR, HIGH_FPR, LOW_FPR) \
67 .set noat; \
68 mfc1 $1, LOW_FPR; \
69 mfc1 GPR, HIGH_FPR; \
70 dsll $1, $1, 32; \
71 dsll GPR, GPR, 32; \
72 dsrl $1, $1, 32; \
73 or GPR, GPR, $1; \
74 .set at
75
76 /* Move the high 32 bits of GPR to HIGH_FPR and the low 32 bits of
77 GPR to LOW_FPR. */
78 #define MERGE_GPRt(GPR, HIGH_FPR, LOW_FPR) \
79 .set noat; \
80 dsrl $1, GPR, 32; \
81 mtc1 GPR, LOW_FPR; \
82 mtc1 $1, HIGH_FPR; \
83 .set at
84
85 /* Jump to T, and use "OPCODE, OP2" to implement a delayed move. */
86 #define DELAYt(T, OPCODE, OP2) \
87 .set noreorder; \
88 jr T; \
89 OPCODE, OP2; \
90 .set reorder
91
92 /* Use "OPCODE. OP2" and jump to T. */
93 #define DELAYf(T, OPCODE, OP2) OPCODE, OP2; jr T
94
95 /* MOVE_SF_BYTE0(D)
96 Move the first single-precision floating-point argument between
97 GPRs and FPRs.
98
99 MOVE_SI_BYTE0(D)
100 Likewise the first single-precision integer argument.
101
102 MOVE_SF_BYTE4(D)
103 Move the second single-precision floating-point argument between
104 GPRs and FPRs, given that the first argument occupies 4 bytes.
105
106 MOVE_SF_BYTE8(D)
107 Move the second single-precision floating-point argument between
108 GPRs and FPRs, given that the first argument occupies 8 bytes.
109
110 MOVE_DF_BYTE0(D)
111 Move the first double-precision floating-point argument between
112 GPRs and FPRs.
113
114 MOVE_DF_BYTE8(D)
115 Likewise the second double-precision floating-point argument.
116
117 MOVE_SF_RET(D, T)
118 Likewise a single-precision floating-point return value,
119 then jump to T.
120
121 MOVE_SC_RET(D, T)
122 Likewise a complex single-precision floating-point return value.
123
124 MOVE_DF_RET(D, T)
125 Likewise a double-precision floating-point return value.
126
127 MOVE_DC_RET(D, T)
128 Likewise a complex double-precision floating-point return value.
129
130 MOVE_SI_RET(D, T)
131 Likewise a single-precision integer return value.
132
133 The D argument is "t" to move to FPRs and "f" to move from FPRs.
134 The return macros may assume that the target of the jump does not
135 use a floating-point register. */
136
137 #define MOVE_SF_RET(D, T) DELAY##D (T, m##D##c1 $2,$f0)
138 #define MOVE_SI_RET(D, T) DELAY##D (T, m##D##c1 $2,$f0)
139
140 #if defined(__mips64) && defined(__MIPSEB__)
141 #define MOVE_SC_RET(D, T) MERGE_GPR##D ($2, $f0, $f1); jr T
142 #elif defined(__mips64)
143 /* The high 32 bits of $2 correspond to the second word in memory;
144 i.e. the imaginary part. */
145 #define MOVE_SC_RET(D, T) MERGE_GPR##D ($2, $f1, $f0); jr T
146 #elif __mips_fpr == 64
147 #define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f1)
148 #else
149 #define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f2)
150 #endif
151
152 #if defined(__mips64)
153 #define MOVE_SF_BYTE0(D) m##D##c1 $4,$f12
154 #define MOVE_SF_BYTE4(D) m##D##c1 $5,$f13
155 #define MOVE_SF_BYTE8(D) m##D##c1 $5,$f13
156 #else
157 #define MOVE_SF_BYTE0(D) m##D##c1 $4,$f12
158 #define MOVE_SF_BYTE4(D) m##D##c1 $5,$f14
159 #define MOVE_SF_BYTE8(D) m##D##c1 $6,$f14
160 #endif
161 #define MOVE_SI_BYTE0(D) MOVE_SF_BYTE0(D)
162
163 #if defined(__mips64)
164 #define MOVE_DF_BYTE0(D) dm##D##c1 $4,$f12
165 #define MOVE_DF_BYTE8(D) dm##D##c1 $5,$f13
166 #define MOVE_DF_RET(D, T) DELAY##D (T, dm##D##c1 $2,$f0)
167 #define MOVE_DC_RET(D, T) dm##D##c1 $3,$f1; MOVE_DF_RET (D, T)
168 #elif __mips_fpr == 64 && defined(__MIPSEB__)
169 #define MOVE_DF_BYTE0(D) m##D##c1 $5,$f12; m##D##hc1 $4,$f12
170 #define MOVE_DF_BYTE8(D) m##D##c1 $7,$f14; m##D##hc1 $6,$f14
171 #define MOVE_DF_RET(D, T) m##D##c1 $3,$f0; DELAY##D (T, m##D##hc1 $2,$f0)
172 #define MOVE_DC_RET(D, T) m##D##c1 $5,$f1; m##D##hc1 $4,$f1; MOVE_DF_RET (D, T)
173 #elif __mips_fpr == 64
174 #define MOVE_DF_BYTE0(D) m##D##c1 $4,$f12; m##D##hc1 $5,$f12
175 #define MOVE_DF_BYTE8(D) m##D##c1 $6,$f14; m##D##hc1 $7,$f14
176 #define MOVE_DF_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##hc1 $3,$f0)
177 #define MOVE_DC_RET(D, T) m##D##c1 $4,$f1; m##D##hc1 $5,$f1; MOVE_DF_RET (D, T)
178 #elif defined(__MIPSEB__)
179 /* FPRs are little-endian. */
180 #define MOVE_DF_BYTE0(D) m##D##c1 $4,$f13; m##D##c1 $5,$f12
181 #define MOVE_DF_BYTE8(D) m##D##c1 $6,$f15; m##D##c1 $7,$f14
182 #define MOVE_DF_RET(D, T) m##D##c1 $2,$f1; DELAY##D (T, m##D##c1 $3,$f0)
183 #define MOVE_DC_RET(D, T) m##D##c1 $4,$f3; m##D##c1 $5,$f2; MOVE_DF_RET (D, T)
184 #else
185 #define MOVE_DF_BYTE0(D) m##D##c1 $4,$f12; m##D##c1 $5,$f13
186 #define MOVE_DF_BYTE8(D) m##D##c1 $6,$f14; m##D##c1 $7,$f15
187 #define MOVE_DF_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f1)
188 #define MOVE_DC_RET(D, T) m##D##c1 $4,$f2; m##D##c1 $5,$f3; MOVE_DF_RET (D, T)
189 #endif
190
191 /* Single-precision math. */
192
193 /* Define a function NAME that loads two single-precision values,
194 performs FPU operation OPCODE on them, and returns the single-
195 precision result. */
196
197 #define OPSF3(NAME, OPCODE) \
198 STARTFN (NAME); \
199 MOVE_SF_BYTE0 (t); \
200 MOVE_SF_BYTE4 (t); \
201 OPCODE RET,ARG1,ARG2; \
202 MOVE_SF_RET (f, $31); \
203 ENDFN (NAME)
204
205 #ifdef L_m16addsf3
206 OPSF3 (__mips16_addsf3, add.s)
207 #endif
208 #ifdef L_m16subsf3
209 OPSF3 (__mips16_subsf3, sub.s)
210 #endif
211 #ifdef L_m16mulsf3
212 OPSF3 (__mips16_mulsf3, mul.s)
213 #endif
214 #ifdef L_m16divsf3
215 OPSF3 (__mips16_divsf3, div.s)
216 #endif
217
218 /* Define a function NAME that loads a single-precision value,
219 performs FPU operation OPCODE on it, and returns the single-
220 precision result. */
221
222 #define OPSF2(NAME, OPCODE) \
223 STARTFN (NAME); \
224 MOVE_SF_BYTE0 (t); \
225 OPCODE RET,ARG1; \
226 MOVE_SF_RET (f, $31); \
227 ENDFN (NAME)
228
229 #ifdef L_m16negsf2
230 OPSF2 (__mips16_negsf2, neg.s)
231 #endif
232 #ifdef L_m16abssf2
233 OPSF2 (__mips16_abssf2, abs.s)
234 #endif
235
236 /* Single-precision comparisons. */
237
238 /* Define a function NAME that loads two single-precision values,
239 performs floating point comparison OPCODE, and returns TRUE or
240 FALSE depending on the result. */
241
242 #define CMPSF(NAME, OPCODE, TRUE, FALSE) \
243 STARTFN (NAME); \
244 MOVE_SF_BYTE0 (t); \
245 MOVE_SF_BYTE4 (t); \
246 OPCODE ARG1,ARG2; \
247 li $2,TRUE; \
248 bc1t 1f; \
249 li $2,FALSE; \
250 1:; \
251 j $31; \
252 ENDFN (NAME)
253
254 /* Like CMPSF, but reverse the comparison operands. */
255
256 #define REVCMPSF(NAME, OPCODE, TRUE, FALSE) \
257 STARTFN (NAME); \
258 MOVE_SF_BYTE0 (t); \
259 MOVE_SF_BYTE4 (t); \
260 OPCODE ARG2,ARG1; \
261 li $2,TRUE; \
262 bc1t 1f; \
263 li $2,FALSE; \
264 1:; \
265 j $31; \
266 ENDFN (NAME)
267
268 #ifdef L_m16eqsf2
269 CMPSF (__mips16_eqsf2, c.eq.s, 0, 1)
270 #endif
271 #ifdef L_m16nesf2
272 CMPSF (__mips16_nesf2, c.eq.s, 0, 1)
273 #endif
274 #ifdef L_m16gtsf2
275 REVCMPSF (__mips16_gtsf2, c.lt.s, 1, 0)
276 #endif
277 #ifdef L_m16gesf2
278 REVCMPSF (__mips16_gesf2, c.le.s, 0, -1)
279 #endif
280 #ifdef L_m16lesf2
281 CMPSF (__mips16_lesf2, c.le.s, 0, 1)
282 #endif
283 #ifdef L_m16ltsf2
284 CMPSF (__mips16_ltsf2, c.lt.s, -1, 0)
285 #endif
286 #ifdef L_m16unordsf2
287 CMPSF(__mips16_unordsf2, c.un.s, 1, 0)
288 #endif
289
290
291 /* Single-precision conversions. */
292
293 #ifdef L_m16fltsisf
294 STARTFN (__mips16_floatsisf)
295 MOVE_SF_BYTE0 (t)
296 cvt.s.w RET,ARG1
297 MOVE_SF_RET (f, $31)
298 ENDFN (__mips16_floatsisf)
299 #endif
300
301 #ifdef L_m16fltunsisf
302 STARTFN (__mips16_floatunsisf)
303 .set noreorder
304 bltz $4,1f
305 MOVE_SF_BYTE0 (t)
306 .set reorder
307 cvt.s.w RET,ARG1
308 MOVE_SF_RET (f, $31)
309 1:
310 and $2,$4,1
311 srl $3,$4,1
312 or $2,$2,$3
313 mtc1 $2,RET
314 cvt.s.w RET,RET
315 add.s RET,RET,RET
316 MOVE_SF_RET (f, $31)
317 ENDFN (__mips16_floatunsisf)
318 #endif
319
320 #ifdef L_m16fix_truncsfsi
321 STARTFN (__mips16_fix_truncsfsi)
322 MOVE_SF_BYTE0 (t)
323 trunc.w.s RET,ARG1,$4
324 MOVE_SI_RET (f, $31)
325 ENDFN (__mips16_fix_truncsfsi)
326 #endif
327
328 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
329
330 /* Double-precision math. */
331
332 /* Define a function NAME that loads two double-precision values,
333 performs FPU operation OPCODE on them, and returns the double-
334 precision result. */
335
336 #define OPDF3(NAME, OPCODE) \
337 STARTFN (NAME); \
338 MOVE_DF_BYTE0 (t); \
339 MOVE_DF_BYTE8 (t); \
340 OPCODE RET,ARG1,ARG2; \
341 MOVE_DF_RET (f, $31); \
342 ENDFN (NAME)
343
344 #ifdef L_m16adddf3
345 OPDF3 (__mips16_adddf3, add.d)
346 #endif
347 #ifdef L_m16subdf3
348 OPDF3 (__mips16_subdf3, sub.d)
349 #endif
350 #ifdef L_m16muldf3
351 OPDF3 (__mips16_muldf3, mul.d)
352 #endif
353 #ifdef L_m16divdf3
354 OPDF3 (__mips16_divdf3, div.d)
355 #endif
356
357 /* Define a function NAME that loads a double-precision value,
358 performs FPU operation OPCODE on it, and returns the double-
359 precision result. */
360
361 #define OPDF2(NAME, OPCODE) \
362 STARTFN (NAME); \
363 MOVE_DF_BYTE0 (t); \
364 OPCODE RET,ARG1; \
365 MOVE_DF_RET (f, $31); \
366 ENDFN (NAME)
367
368 #ifdef L_m16negdf2
369 OPDF2 (__mips16_negdf2, neg.d)
370 #endif
371 #ifdef L_m16absdf2
372 OPDF2 (__mips16_absdf2, abs.d)
373 #endif
374
375 /* Conversions between single and double precision. */
376
377 #ifdef L_m16extsfdf2
378 STARTFN (__mips16_extendsfdf2)
379 MOVE_SF_BYTE0 (t)
380 cvt.d.s RET,ARG1
381 MOVE_DF_RET (f, $31)
382 ENDFN (__mips16_extendsfdf2)
383 #endif
384
385 #ifdef L_m16trdfsf2
386 STARTFN (__mips16_truncdfsf2)
387 MOVE_DF_BYTE0 (t)
388 cvt.s.d RET,ARG1
389 MOVE_SF_RET (f, $31)
390 ENDFN (__mips16_truncdfsf2)
391 #endif
392
393 /* Double-precision comparisons. */
394
395 /* Define a function NAME that loads two double-precision values,
396 performs floating point comparison OPCODE, and returns TRUE or
397 FALSE depending on the result. */
398
399 #define CMPDF(NAME, OPCODE, TRUE, FALSE) \
400 STARTFN (NAME); \
401 MOVE_DF_BYTE0 (t); \
402 MOVE_DF_BYTE8 (t); \
403 OPCODE ARG1,ARG2; \
404 li $2,TRUE; \
405 bc1t 1f; \
406 li $2,FALSE; \
407 1:; \
408 j $31; \
409 ENDFN (NAME)
410
411 /* Like CMPDF, but reverse the comparison operands. */
412
413 #define REVCMPDF(NAME, OPCODE, TRUE, FALSE) \
414 STARTFN (NAME); \
415 MOVE_DF_BYTE0 (t); \
416 MOVE_DF_BYTE8 (t); \
417 OPCODE ARG2,ARG1; \
418 li $2,TRUE; \
419 bc1t 1f; \
420 li $2,FALSE; \
421 1:; \
422 j $31; \
423 ENDFN (NAME)
424
425 #ifdef L_m16eqdf2
426 CMPDF (__mips16_eqdf2, c.eq.d, 0, 1)
427 #endif
428 #ifdef L_m16nedf2
429 CMPDF (__mips16_nedf2, c.eq.d, 0, 1)
430 #endif
431 #ifdef L_m16gtdf2
432 REVCMPDF (__mips16_gtdf2, c.lt.d, 1, 0)
433 #endif
434 #ifdef L_m16gedf2
435 REVCMPDF (__mips16_gedf2, c.le.d, 0, -1)
436 #endif
437 #ifdef L_m16ledf2
438 CMPDF (__mips16_ledf2, c.le.d, 0, 1)
439 #endif
440 #ifdef L_m16ltdf2
441 CMPDF (__mips16_ltdf2, c.lt.d, -1, 0)
442 #endif
443 #ifdef L_m16unorddf2
444 CMPDF(__mips16_unorddf2, c.un.d, 1, 0)
445 #endif
446
447 /* Double-precision conversions. */
448
449 #ifdef L_m16fltsidf
450 STARTFN (__mips16_floatsidf)
451 MOVE_SI_BYTE0 (t)
452 cvt.d.w RET,ARG1
453 MOVE_DF_RET (f, $31)
454 ENDFN (__mips16_floatsidf)
455 #endif
456
457 #ifdef L_m16fltunsidf
458 STARTFN (__mips16_floatunsidf)
459 MOVE_SI_BYTE0 (t)
460 cvt.d.w RET,ARG1
461 bgez $4,1f
462 li.d ARG1, 4.294967296e+9
463 add.d RET, RET, ARG1
464 1: MOVE_DF_RET (f, $31)
465 ENDFN (__mips16_floatunsidf)
466 #endif
467
468 #ifdef L_m16fix_truncdfsi
469 STARTFN (__mips16_fix_truncdfsi)
470 MOVE_DF_BYTE0 (t)
471 trunc.w.d RET,ARG1,$4
472 MOVE_SI_RET (f, $31)
473 ENDFN (__mips16_fix_truncdfsi)
474 #endif
475 #endif /* !__mips_single_float */
476
477 /* Define a function NAME that moves a return value of mode MODE from
478 FPRs to GPRs. */
479
480 #define RET_FUNCTION(NAME, MODE) \
481 STARTFN (NAME); \
482 MOVE_##MODE##_RET (t, $31); \
483 ENDFN (NAME)
484
485 #ifdef L_m16retsf
486 RET_FUNCTION (__mips16_ret_sf, SF)
487 #endif
488
489 #ifdef L_m16retsc
490 RET_FUNCTION (__mips16_ret_sc, SC)
491 #endif
492
493 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
494 #ifdef L_m16retdf
495 RET_FUNCTION (__mips16_ret_df, DF)
496 #endif
497
498 #ifdef L_m16retdc
499 RET_FUNCTION (__mips16_ret_dc, DC)
500 #endif
501 #endif /* !__mips_single_float */
502
503 /* STUB_ARGS_X copies the arguments from GPRs to FPRs for argument
504 code X. X is calculated as ARG1 + ARG2 * 4, where ARG1 and ARG2
505 classify the first and second arguments as follows:
506
507 1: a single-precision argument
508 2: a double-precision argument
509 0: no argument, or not one of the above. */
510
511 #define STUB_ARGS_0 /* () */
512 #define STUB_ARGS_1 MOVE_SF_BYTE0 (t) /* (sf) */
513 #define STUB_ARGS_5 MOVE_SF_BYTE0 (t); MOVE_SF_BYTE4 (t) /* (sf, sf) */
514 #define STUB_ARGS_9 MOVE_SF_BYTE0 (t); MOVE_DF_BYTE8 (t) /* (sf, df) */
515 #define STUB_ARGS_2 MOVE_DF_BYTE0 (t) /* (df) */
516 #define STUB_ARGS_6 MOVE_DF_BYTE0 (t); MOVE_SF_BYTE8 (t) /* (df, sf) */
517 #define STUB_ARGS_10 MOVE_DF_BYTE0 (t); MOVE_DF_BYTE8 (t) /* (df, df) */
518
519 /* These functions are used by 16-bit code when calling via a function
520 pointer. They must copy the floating point arguments from the GPRs
521 to FPRs and then call function $2. */
522
523 #define CALL_STUB_NO_RET(NAME, CODE) \
524 STARTFN (NAME); \
525 STUB_ARGS_##CODE; \
526 .set noreorder; \
527 jr $2; \
528 move $25,$2; \
529 .set reorder; \
530 ENDFN (NAME)
531
532 #ifdef L_m16stub1
533 CALL_STUB_NO_RET (__mips16_call_stub_1, 1)
534 #endif
535
536 #ifdef L_m16stub5
537 CALL_STUB_NO_RET (__mips16_call_stub_5, 5)
538 #endif
539
540 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
541
542 #ifdef L_m16stub2
543 CALL_STUB_NO_RET (__mips16_call_stub_2, 2)
544 #endif
545
546 #ifdef L_m16stub6
547 CALL_STUB_NO_RET (__mips16_call_stub_6, 6)
548 #endif
549
550 #ifdef L_m16stub9
551 CALL_STUB_NO_RET (__mips16_call_stub_9, 9)
552 #endif
553
554 #ifdef L_m16stub10
555 CALL_STUB_NO_RET (__mips16_call_stub_10, 10)
556 #endif
557 #endif /* !__mips_single_float */
558
559 /* Now we have the same set of functions, except that this time the
560 function being called returns an SFmode, SCmode, DFmode or DCmode
561 value; we need to instantiate a set for each case. The calling
562 function will arrange to preserve $18, so these functions are free
563 to use it to hold the return address.
564
565 Note that we do not know whether the function we are calling is 16
566 bit or 32 bit. However, it does not matter, because 16-bit
567 functions always return floating point values in both the gp and
568 the fp regs. It would be possible to check whether the function
569 being called is 16 bits, in which case the copy is unnecessary;
570 however, it's faster to always do the copy. */
571
572 #define CALL_STUB_RET(NAME, CODE, MODE) \
573 STARTFN (NAME); \
574 .cfi_startproc; \
575 /* Create a fake CFA 4 bytes below the stack pointer. */ \
576 .cfi_def_cfa 29,-4; \
577 /* "Save" $sp in itself so we don't use the fake CFA. \
578 This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */ \
579 .cfi_escape 0x16,29,1,0x6d; \
580 move $18,$31; \
581 .cfi_register 31,18; \
582 STUB_ARGS_##CODE; \
583 .set noreorder; \
584 jalr $2; \
585 move $25,$2; \
586 .set reorder; \
587 MOVE_##MODE##_RET (f, $18); \
588 .cfi_endproc; \
589 ENDFN (NAME)
590
591 /* First, instantiate the single-float set. */
592
593 #ifdef L_m16stubsf0
594 CALL_STUB_RET (__mips16_call_stub_sf_0, 0, SF)
595 #endif
596
597 #ifdef L_m16stubsf1
598 CALL_STUB_RET (__mips16_call_stub_sf_1, 1, SF)
599 #endif
600
601 #ifdef L_m16stubsf5
602 CALL_STUB_RET (__mips16_call_stub_sf_5, 5, SF)
603 #endif
604
605 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
606 #ifdef L_m16stubsf2
607 CALL_STUB_RET (__mips16_call_stub_sf_2, 2, SF)
608 #endif
609
610 #ifdef L_m16stubsf6
611 CALL_STUB_RET (__mips16_call_stub_sf_6, 6, SF)
612 #endif
613
614 #ifdef L_m16stubsf9
615 CALL_STUB_RET (__mips16_call_stub_sf_9, 9, SF)
616 #endif
617
618 #ifdef L_m16stubsf10
619 CALL_STUB_RET (__mips16_call_stub_sf_10, 10, SF)
620 #endif
621 #endif /* !__mips_single_float */
622
623
624 /* Now we have the same set of functions again, except that this time
625 the function being called returns an DFmode value. */
626
627 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
628 #ifdef L_m16stubdf0
629 CALL_STUB_RET (__mips16_call_stub_df_0, 0, DF)
630 #endif
631
632 #ifdef L_m16stubdf1
633 CALL_STUB_RET (__mips16_call_stub_df_1, 1, DF)
634 #endif
635
636 #ifdef L_m16stubdf5
637 CALL_STUB_RET (__mips16_call_stub_df_5, 5, DF)
638 #endif
639
640 #ifdef L_m16stubdf2
641 CALL_STUB_RET (__mips16_call_stub_df_2, 2, DF)
642 #endif
643
644 #ifdef L_m16stubdf6
645 CALL_STUB_RET (__mips16_call_stub_df_6, 6, DF)
646 #endif
647
648 #ifdef L_m16stubdf9
649 CALL_STUB_RET (__mips16_call_stub_df_9, 9, DF)
650 #endif
651
652 #ifdef L_m16stubdf10
653 CALL_STUB_RET (__mips16_call_stub_df_10, 10, DF)
654 #endif
655 #endif /* !__mips_single_float */
656
657
658 /* Ho hum. Here we have the same set of functions again, this time
659 for when the function being called returns an SCmode value. */
660
661 #ifdef L_m16stubsc0
662 CALL_STUB_RET (__mips16_call_stub_sc_0, 0, SC)
663 #endif
664
665 #ifdef L_m16stubsc1
666 CALL_STUB_RET (__mips16_call_stub_sc_1, 1, SC)
667 #endif
668
669 #ifdef L_m16stubsc5
670 CALL_STUB_RET (__mips16_call_stub_sc_5, 5, SC)
671 #endif
672
673 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
674 #ifdef L_m16stubsc2
675 CALL_STUB_RET (__mips16_call_stub_sc_2, 2, SC)
676 #endif
677
678 #ifdef L_m16stubsc6
679 CALL_STUB_RET (__mips16_call_stub_sc_6, 6, SC)
680 #endif
681
682 #ifdef L_m16stubsc9
683 CALL_STUB_RET (__mips16_call_stub_sc_9, 9, SC)
684 #endif
685
686 #ifdef L_m16stubsc10
687 CALL_STUB_RET (__mips16_call_stub_sc_10, 10, SC)
688 #endif
689 #endif /* !__mips_single_float */
690
691
692 /* Finally, another set of functions for DCmode. */
693
694 #if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT)
695 #ifdef L_m16stubdc0
696 CALL_STUB_RET (__mips16_call_stub_dc_0, 0, DC)
697 #endif
698
699 #ifdef L_m16stubdc1
700 CALL_STUB_RET (__mips16_call_stub_dc_1, 1, DC)
701 #endif
702
703 #ifdef L_m16stubdc5
704 CALL_STUB_RET (__mips16_call_stub_dc_5, 5, DC)
705 #endif
706
707 #ifdef L_m16stubdc2
708 CALL_STUB_RET (__mips16_call_stub_dc_2, 2, DC)
709 #endif
710
711 #ifdef L_m16stubdc6
712 CALL_STUB_RET (__mips16_call_stub_dc_6, 6, DC)
713 #endif
714
715 #ifdef L_m16stubdc9
716 CALL_STUB_RET (__mips16_call_stub_dc_9, 9, DC)
717 #endif
718
719 #ifdef L_m16stubdc10
720 CALL_STUB_RET (__mips16_call_stub_dc_10, 10, DC)
721 #endif
722 #endif /* !__mips_single_float */
723
724 #endif
725 #endif /* __mips_micromips */