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