mips16.S revision 169690
133965Sjdp/* mips16 floating point support code 233965Sjdp Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. 338889Sjdp Contributed by Cygnus Support 460484Sobrien 533965SjdpThis file is free software; you can redistribute it and/or modify it 633965Sjdpunder the terms of the GNU General Public License as published by the 738889SjdpFree Software Foundation; either version 2, or (at your option) any 838889Sjdplater version. 938889Sjdp 1092828SobrienIn addition to the permissions in the GNU General Public License, the 1189857SobrienFree Software Foundation gives you unlimited permission to link the 1292828Sobriencompiled version of this file with other programs, and to distribute 1338889Sjdpthose programs without any restriction coming from the use of this 1489857Sobrienfile. (The General Public License restrictions do apply in other 1589857Sobrienrespects; for example, they cover modification of the file, and 1689857Sobriendistribution when not linked into another program.) 1789857Sobrien 1889857SobrienThis file is distributed in the hope that it will be useful, but 1989857SobrienWITHOUT ANY WARRANTY; without even the implied warranty of 2089857SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2189857SobrienGeneral Public License for more details. 2289857Sobrien 2389857SobrienYou should have received a copy of the GNU General Public License 2489857Sobrienalong with this program; see the file COPYING. If not, write to 2589857Sobrienthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 2689857SobrienBoston, MA 02110-1301, USA. */ 2789857Sobrien 2889857Sobrien/* As a special exception, if you link this library with other files, 2989857Sobrien some of which are compiled with GCC, to produce an executable, 3089857Sobrien this library does not by itself cause the resulting executable 3189857Sobrien to be covered by the GNU General Public License. 3238889Sjdp This exception does not however invalidate any other reasons why 3338889Sjdp the executable file might be covered by the GNU General Public License. */ 3438889Sjdp 3538889Sjdp/* This file contains mips16 floating point support functions. These 3638889Sjdp functions are called by mips16 code to handle floating point when 3738889Sjdp -msoft-float is not used. They accept the arguments and return 3838889Sjdp values using the soft-float calling convention, but do the actual 3938889Sjdp operation using the hard floating point instructions. */ 4038889Sjdp 4138889Sjdp/* This file contains 32 bit assembly code. */ 4238889Sjdp .set nomips16 4333965Sjdp 4433965Sjdp/* Start a function. */ 4533965Sjdp 4633965Sjdp#define STARTFN(NAME) .globl NAME; .ent NAME; NAME: 4733965Sjdp 4833965Sjdp/* Finish a function. */ 4933965Sjdp 5033965Sjdp#define ENDFN(NAME) .end NAME 5133965Sjdp 5233965Sjdp/* Single precision math. */ 5333965Sjdp 5433965Sjdp/* This macro defines a function which loads two single precision 5533965Sjdp values, performs an operation, and returns the single precision 5633965Sjdp result. */ 5733965Sjdp 5833965Sjdp#define SFOP(NAME, OPCODE) \ 5933965SjdpSTARTFN (NAME); \ 6033965Sjdp .set noreorder; \ 6133965Sjdp mtc1 $4,$f0; \ 6233965Sjdp mtc1 $5,$f2; \ 6333965Sjdp nop; \ 6433965Sjdp OPCODE $f0,$f0,$f2; \ 6533965Sjdp mfc1 $2,$f0; \ 6633965Sjdp j $31; \ 6733965Sjdp nop; \ 6833965Sjdp .set reorder; \ 6933965Sjdp ENDFN (NAME) 7033965Sjdp 7133965Sjdp#ifdef L_m16addsf3 7233965SjdpSFOP(__mips16_addsf3, add.s) 7389857Sobrien#endif 7477298Sobrien#ifdef L_m16subsf3 7577298SobrienSFOP(__mips16_subsf3, sub.s) 7677298Sobrien#endif 7777298Sobrien#ifdef L_m16mulsf3 7877298SobrienSFOP(__mips16_mulsf3, mul.s) 7977298Sobrien#endif 8077298Sobrien#ifdef L_m16divsf3 8177298SobrienSFOP(__mips16_divsf3, div.s) 8277298Sobrien#endif 8377298Sobrien 8477298Sobrien#define SFOP2(NAME, OPCODE) \ 8577298SobrienSTARTFN (NAME); \ 8677298Sobrien .set noreorder; \ 8777298Sobrien mtc1 $4,$f0; \ 8877298Sobrien nop; \ 8977298Sobrien OPCODE $f0,$f0; \ 9077298Sobrien mfc1 $2,$f0; \ 9177298Sobrien j $31; \ 9277298Sobrien nop; \ 9377298Sobrien .set reorder; \ 9438889Sjdp ENDFN (NAME) 9533965Sjdp 9633965Sjdp#ifdef L_m16negsf2 9733965SjdpSFOP2(__mips16_negsf2, neg.s) 9833965Sjdp#endif 9933965Sjdp#ifdef L_m16abssf2 10038889SjdpSFOP2(__mips16_abssf2, abs.s) 10160484Sobrien#endif 10238889Sjdp 10333965Sjdp/* Single precision comparisons. */ 10433965Sjdp 10589857Sobrien/* This macro defines a function which loads two single precision 10633965Sjdp values, performs a floating point comparison, and returns the 10733965Sjdp specified values according to whether the comparison is true or 10833965Sjdp false. */ 10933965Sjdp 11033965Sjdp#define SFCMP(NAME, OPCODE, TRUE, FALSE) \ 11189857SobrienSTARTFN (NAME); \ 11260484Sobrien mtc1 $4,$f0; \ 11360484Sobrien mtc1 $5,$f2; \ 11433965Sjdp OPCODE $f0,$f2; \ 11533965Sjdp li $2,TRUE; \ 11633965Sjdp bc1t 1f; \ 11733965Sjdp li $2,FALSE; \ 11860484Sobrien1:; \ 11933965Sjdp j $31; \ 12033965Sjdp ENDFN (NAME) 12133965Sjdp 12233965Sjdp/* This macro is like SFCMP, but it reverses the comparison. */ 12333965Sjdp 12433965Sjdp#define SFREVCMP(NAME, OPCODE, TRUE, FALSE) \ 12533965SjdpSTARTFN (NAME); \ 12633965Sjdp mtc1 $4,$f0; \ 12733965Sjdp mtc1 $5,$f2; \ 12833965Sjdp OPCODE $f2,$f0; \ 12933965Sjdp li $2,TRUE; \ 13033965Sjdp bc1t 1f; \ 13133965Sjdp li $2,FALSE; \ 13233965Sjdp1:; \ 13333965Sjdp j $31; \ 13433965Sjdp ENDFN (NAME) 13533965Sjdp 13633965Sjdp#ifdef L_m16eqsf2 13733965SjdpSFCMP(__mips16_eqsf2, c.eq.s, 0, 1) 13833965Sjdp#endif 13933965Sjdp#ifdef L_m16nesf2 14033965SjdpSFCMP(__mips16_nesf2, c.eq.s, 0, 1) 14160484Sobrien#endif 14260484Sobrien#ifdef L_m16gtsf2 14333965SjdpSFREVCMP(__mips16_gtsf2, c.lt.s, 1, 0) 14433965Sjdp#endif 14533965Sjdp#ifdef L_m16gesf2 14633965SjdpSFREVCMP(__mips16_gesf2, c.le.s, 0, -1) 14733965Sjdp#endif 14833965Sjdp#ifdef L_m16lesf2 14933965SjdpSFCMP(__mips16_lesf2, c.le.s, 0, 1) 15033965Sjdp#endif 15133965Sjdp#ifdef L_m16ltsf2 15233965SjdpSFCMP(__mips16_ltsf2, c.lt.s, -1, 0) 15333965Sjdp#endif 15433965Sjdp 15560484Sobrien/* Single precision conversions. */ 15633965Sjdp 15733965Sjdp#ifdef L_m16fltsisf 15877298SobrienSTARTFN (__mips16_floatsisf) 15977298Sobrien .set noreorder 16077298Sobrien mtc1 $4,$f0 16138889Sjdp nop 16238889Sjdp cvt.s.w $f0,$f0 16360484Sobrien mfc1 $2,$f0 16433965Sjdp j $31 16538889Sjdp nop 16638889Sjdp .set reorder 16777298Sobrien ENDFN (__mips16_floatsisf) 16889857Sobrien#endif 16938889Sjdp 17038889Sjdp#ifdef L_m16fix_truncsfsi 17138889SjdpSTARTFN (__mips16_fix_truncsfsi) 17260484Sobrien .set noreorder 17338889Sjdp mtc1 $4,$f0 17433965Sjdp nop 17589857Sobrien trunc.w.s $f0,$f0,$4 17660484Sobrien mfc1 $2,$f0 17760484Sobrien j $31 17860484Sobrien nop 17960484Sobrien .set reorder 18033965Sjdp ENDFN (__mips16_fix_truncsfsi) 18133965Sjdp#endif 18233965Sjdp 18360484Sobrien#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) 18460484Sobrien 18533965Sjdp/* The double precision operations. We need to use different code 18633965Sjdp based on the preprocessor symbol __mips64, because the way in which 18733965Sjdp double precision values will change. Without __mips64, the value 18833965Sjdp is passed in two 32 bit registers. With __mips64, the value is 18933965Sjdp passed in a single 64 bit register. */ 19038889Sjdp 19160484Sobrien/* Load the first double precision operand. */ 19233965Sjdp 19333965Sjdp#if defined(__mips64) 19489857Sobrien#define LDDBL1 dmtc1 $4,$f12 19589857Sobrien#elif defined(__mipsfp64) 19689857Sobrien#define LDDBL1 sw $4,0($29); sw $5,4($29); l.d $f12,0($29) 19789857Sobrien#elif defined(__MIPSEB__) 19889857Sobrien#define LDDBL1 mtc1 $4,$f13; mtc1 $5,$f12 19991041Sobrien#else 20033965Sjdp#define LDDBL1 mtc1 $4,$f12; mtc1 $5,$f13 20138889Sjdp#endif 20260484Sobrien 20333965Sjdp/* Load the second double precision operand. */ 20433965Sjdp 20577298Sobrien#if defined(__mips64) 20677298Sobrien/* XXX this should be $6 for Algo arg passing model */ 20777298Sobrien#define LDDBL2 dmtc1 $5,$f14 20877298Sobrien#elif defined(__mipsfp64) 20977298Sobrien#define LDDBL2 sw $6,8($29); sw $7,12($29); l.d $f14,8($29) 21077298Sobrien#elif defined(__MIPSEB__) 21133965Sjdp#define LDDBL2 mtc1 $6,$f15; mtc1 $7,$f14 21233965Sjdp#else 21338889Sjdp#define LDDBL2 mtc1 $6,$f14; mtc1 $7,$f15 21433965Sjdp#endif 21533965Sjdp 21633965Sjdp/* Move the double precision return value to the right place. */ 21733965Sjdp 21838889Sjdp#if defined(__mips64) 21960484Sobrien#define RETDBL dmfc1 $2,$f0 22033965Sjdp#elif defined(__mipsfp64) 22133965Sjdp#define RETDBL s.d $f0,0($29); lw $2,0($29); lw $3,4($29) 22260484Sobrien#elif defined(__MIPSEB__) 22360484Sobrien#define RETDBL mfc1 $2,$f1; mfc1 $3,$f0 22460484Sobrien#else 22560484Sobrien#define RETDBL mfc1 $2,$f0; mfc1 $3,$f1 22660484Sobrien#endif 22733965Sjdp 22833965Sjdp/* Double precision math. */ 22938889Sjdp 23060484Sobrien/* This macro defines a function which loads two double precision 23133965Sjdp values, performs an operation, and returns the double precision 23233965Sjdp result. */ 23333965Sjdp 23433965Sjdp#define DFOP(NAME, OPCODE) \ 23538889SjdpSTARTFN (NAME); \ 23660484Sobrien .set noreorder; \ 23733965Sjdp LDDBL1; \ 23833965Sjdp LDDBL2; \ 23938889Sjdp nop; \ 24033965Sjdp OPCODE $f0,$f12,$f14; \ 24138889Sjdp RETDBL; \ 24260484Sobrien j $31; \ 24333965Sjdp nop; \ 24433965Sjdp .set reorder; \ 24538889Sjdp ENDFN (NAME) 24638889Sjdp 24733965Sjdp#ifdef L_m16adddf3 24833965SjdpDFOP(__mips16_adddf3, add.d) 24938889Sjdp#endif 25060484Sobrien#ifdef L_m16subdf3 25133965SjdpDFOP(__mips16_subdf3, sub.d) 25233965Sjdp#endif 25338889Sjdp#ifdef L_m16muldf3 25460484SobrienDFOP(__mips16_muldf3, mul.d) 25533965Sjdp#endif 25633965Sjdp#ifdef L_m16divdf3 25738889SjdpDFOP(__mips16_divdf3, div.d) 25860484Sobrien#endif 25933965Sjdp 26033965Sjdp#define DFOP2(NAME, OPCODE) \ 26138889SjdpSTARTFN (NAME); \ 26233965Sjdp .set noreorder; \ 26333965Sjdp LDDBL1; \ 26438889Sjdp nop; \ 26560484Sobrien OPCODE $f0,$f12; \ 26633965Sjdp RETDBL; \ 26738889Sjdp j $31; \ 26838889Sjdp nop; \ 26938889Sjdp .set reorder; \ 27033965Sjdp ENDFN (NAME) 27138889Sjdp 27260484Sobrien#ifdef L_m16negdf2 27333965SjdpDFOP2(__mips16_negdf2, neg.d) 27433965Sjdp#endif 27533965Sjdp#ifdef L_m16absdf2 27638889SjdpDFOP2(__mips16_absdf2, abs.d) 27760484Sobrien#endif 27833965Sjdp 27933965Sjdp 28038889Sjdp/* Conversions between single and double precision. */ 28160484Sobrien 28233965Sjdp#ifdef L_m16extsfdf2 28333965SjdpSTARTFN (__mips16_extendsfdf2) 28438889Sjdp .set noreorder 28560484Sobrien mtc1 $4,$f12 28633965Sjdp nop 28738889Sjdp cvt.d.s $f0,$f12 28833965Sjdp RETDBL 28938889Sjdp j $31 29060484Sobrien nop 29133965Sjdp .set reorder 29238889Sjdp ENDFN (__mips16_extendsfdf2) 29338889Sjdp#endif 29460484Sobrien 29533965Sjdp#ifdef L_m16trdfsf2 29633965SjdpSTARTFN (__mips16_truncdfsf2) 29738889Sjdp .set noreorder 29860484Sobrien LDDBL1 29933965Sjdp nop 30033965Sjdp cvt.s.d $f0,$f12 30138889Sjdp mfc1 $2,$f0 30260484Sobrien j $31 30333965Sjdp nop 30433965Sjdp .set reorder 30538889Sjdp ENDFN (__mips16_truncdfsf2) 30633965Sjdp#endif 30733965Sjdp 30838889Sjdp/* Double precision comparisons. */ 30960484Sobrien 31033965Sjdp/* This macro defines a function which loads two double precision 31133965Sjdp values, performs a floating point comparison, and returns the 31238889Sjdp specified values according to whether the comparison is true or 31333965Sjdp false. */ 31438889Sjdp 31560484Sobrien#define DFCMP(NAME, OPCODE, TRUE, FALSE) \ 31633965SjdpSTARTFN (NAME); \ 31733965Sjdp LDDBL1; \ 31838889Sjdp LDDBL2; \ 31960484Sobrien OPCODE $f12,$f14; \ 32033965Sjdp li $2,TRUE; \ 32133965Sjdp bc1t 1f; \ 32238889Sjdp li $2,FALSE; \ 32333965Sjdp1:; \ 32438889Sjdp j $31; \ 32577298Sobrien ENDFN (NAME) 32677298Sobrien 32777298Sobrien/* This macro is like DFCMP, but it reverses the comparison. */ 32877298Sobrien 32977298Sobrien#define DFREVCMP(NAME, OPCODE, TRUE, FALSE) \ 33077298SobrienSTARTFN (NAME); \ 33138889Sjdp LDDBL1; \ 33238889Sjdp LDDBL2; \ 33338889Sjdp OPCODE $f14,$f12; \ 33438889Sjdp li $2,TRUE; \ 33533965Sjdp bc1t 1f; \ 33677298Sobrien li $2,FALSE; \ 33738889Sjdp1:; \ 33878828Sobrien j $31; \ 33989857Sobrien ENDFN (NAME) 34089857Sobrien 34133965Sjdp#ifdef L_m16eqdf2 34238889SjdpDFCMP(__mips16_eqdf2, c.eq.d, 0, 1) 34333965Sjdp#endif 34433965Sjdp#ifdef L_m16nedf2 34538889SjdpDFCMP(__mips16_nedf2, c.eq.d, 0, 1) 34660484Sobrien#endif 34733965Sjdp#ifdef L_m16gtdf2 34833965SjdpDFREVCMP(__mips16_gtdf2, c.lt.d, 1, 0) 34938889Sjdp#endif 35060484Sobrien#ifdef L_m16gedf2 35133965SjdpDFREVCMP(__mips16_gedf2, c.le.d, 0, -1) 35233965Sjdp#endif 35338889Sjdp#ifdef L_m16ledf2 35460484SobrienDFCMP(__mips16_ledf2, c.le.d, 0, 1) 35533965Sjdp#endif 35633965Sjdp#ifdef L_m16ltdf2 35738889SjdpDFCMP(__mips16_ltdf2, c.lt.d, -1, 0) 35860484Sobrien#endif 35933965Sjdp 36089857Sobrien/* Double precision conversions. */ 36133965Sjdp 36233965Sjdp#ifdef L_m16fltsidf 36333965SjdpSTARTFN (__mips16_floatsidf) 36438889Sjdp .set noreorder 36538889Sjdp mtc1 $4,$f12 36638889Sjdp nop 36738889Sjdp cvt.d.w $f0,$f12 36838889Sjdp RETDBL 36938889Sjdp j $31 37038889Sjdp nop 37138889Sjdp .set reorder 37238889Sjdp ENDFN (__mips16_floatsidf) 37360484Sobrien#endif 37438889Sjdp 37533965Sjdp#ifdef L_m16fix_truncdfsi 37633965SjdpSTARTFN (__mips16_fix_truncdfsi) 37760484Sobrien .set noreorder 37860484Sobrien LDDBL1 37960484Sobrien nop 38060484Sobrien trunc.w.d $f0,$f12,$4 38160484Sobrien mfc1 $2,$f0 38277298Sobrien j $31 38360484Sobrien nop 38477298Sobrien .set reorder 38560484Sobrien ENDFN (__mips16_fix_truncdfsi) 38677298Sobrien#endif 38777298Sobrien#endif /* !__mips_single_float */ 38860484Sobrien 38977298Sobrien/* These functions are used to return floating point values from 39060484Sobrien mips16 functions. In this case we can put mtc1 in a jump delay slot, 39177298Sobrien because we know that the next instruction will not refer to a floating 39260484Sobrien point register. */ 39377298Sobrien 39460484Sobrien#ifdef L_m16retsf 39560484SobrienSTARTFN (__mips16_ret_sf) 39660484Sobrien .set noreorder 39733965Sjdp j $31 39833965Sjdp mtc1 $2,$f0 39933965Sjdp .set reorder 40033965Sjdp ENDFN (__mips16_ret_sf) 40177298Sobrien#endif 40277298Sobrien 40377298Sobrien#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) 40477298Sobrien#ifdef L_m16retdf 40533965SjdpSTARTFN (__mips16_ret_df) 40660484Sobrien .set noreorder 40760484Sobrien#if defined(__mips64) 40860484Sobrien j $31 40960484Sobrien dmtc1 $2,$f0 41060484Sobrien#elif defined(__mipsfp64) 41160484Sobrien sw $2,0($29) 41260484Sobrien sw $3,4($29) 41360484Sobrien l.d $f0,0($29) 41460484Sobrien#elif defined(__MIPSEB__) 41560484Sobrien mtc1 $2,$f1 41689857Sobrien j $31 41789857Sobrien mtc1 $3,$f0 41889857Sobrien#else 41989857Sobrien mtc1 $2,$f0 42089857Sobrien j $31 42189857Sobrien mtc1 $3,$f1 42289857Sobrien#endif 42389857Sobrien .set reorder 42489857Sobrien ENDFN (__mips16_ret_df) 42589857Sobrien#endif 42689857Sobrien#endif /* !__mips_single_float */ 42792828Sobrien 42892828Sobrien/* These functions are used by 16 bit code when calling via a function 42992828Sobrien pointer. They must copy the floating point arguments from the gp 43092828Sobrien regs into the fp regs. The function to call will be in $2. The 43189857Sobrien exact set of floating point arguments to copy is encoded in the 43289857Sobrien function name; the final number is an fp_code, as described in 43389857Sobrien mips.h in the comment about CUMULATIVE_ARGS. */ 43489857Sobrien 43589857Sobrien#ifdef L_m16stub1 43660484Sobrien/* (float) */ 43760484SobrienSTARTFN (__mips16_call_stub_1) 43860484Sobrien .set noreorder 43960484Sobrien mtc1 $4,$f12 44033965Sjdp j $2 44133965Sjdp nop 44233965Sjdp .set reorder 44333965Sjdp ENDFN (__mips16_call_stub_1) 44433965Sjdp#endif 44533965Sjdp 44660484Sobrien#ifdef L_m16stub5 44733965Sjdp/* (float, float) */ 44833965SjdpSTARTFN (__mips16_call_stub_5) 44933965Sjdp .set noreorder 45033965Sjdp mtc1 $4,$f12 45133965Sjdp mtc1 $5,$f14 45233965Sjdp j $2 45333965Sjdp nop 45433965Sjdp .set reorder 45533965Sjdp ENDFN (__mips16_call_stub_5) 45633965Sjdp#endif 45733965Sjdp 45833965Sjdp#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) 45933965Sjdp 46033965Sjdp#ifdef L_m16stub2 46133965Sjdp/* (double) */ 46233965SjdpSTARTFN (__mips16_call_stub_2) 46333965Sjdp .set noreorder 46433965Sjdp LDDBL1 46533965Sjdp j $2 46633965Sjdp nop 46733965Sjdp .set reorder 46833965Sjdp ENDFN (__mips16_call_stub_2) 46933965Sjdp#endif 47033965Sjdp 47133965Sjdp#ifdef L_m16stub6 47233965Sjdp/* (double, float) */ 47333965SjdpSTARTFN (__mips16_call_stub_6) 47433965Sjdp .set noreorder 47533965Sjdp LDDBL1 47633965Sjdp mtc1 $6,$f14 47733965Sjdp j $2 47833965Sjdp nop 47933965Sjdp .set reorder 48033965Sjdp ENDFN (__mips16_call_stub_6) 48160484Sobrien#endif 48233965Sjdp 48333965Sjdp#ifdef L_m16stub9 48433965Sjdp/* (float, double) */ 48533965SjdpSTARTFN (__mips16_call_stub_9) 48633965Sjdp .set noreorder 48733965Sjdp mtc1 $4,$f12 48833965Sjdp LDDBL2 48933965Sjdp j $2 49033965Sjdp nop 49133965Sjdp .set reorder 49233965Sjdp ENDFN (__mips16_call_stub_9) 49333965Sjdp#endif 49438889Sjdp 49533965Sjdp#ifdef L_m16stub10 49633965Sjdp/* (double, double) */ 49733965SjdpSTARTFN (__mips16_call_stub_10) 49833965Sjdp .set noreorder 49933965Sjdp LDDBL1 50033965Sjdp LDDBL2 50133965Sjdp j $2 50233965Sjdp nop 50333965Sjdp .set reorder 50433965Sjdp ENDFN (__mips16_call_stub_10) 50533965Sjdp#endif 50633965Sjdp#endif /* !__mips_single_float */ 50733965Sjdp 50889857Sobrien/* Now we have the same set of functions, except that this time the 50933965Sjdp function being called returns an SFmode value. The calling 51033965Sjdp function will arrange to preserve $18, so these functions are free 51133965Sjdp to use it to hold the return address. 51289857Sobrien 51333965Sjdp Note that we do not know whether the function we are calling is 16 51433965Sjdp bit or 32 bit. However, it does not matter, because 16 bit 51589857Sobrien functions always return floating point values in both the gp and 51689857Sobrien the fp regs. It would be possible to check whether the function 51791041Sobrien being called is 16 bits, in which case the copy is unnecessary; 51891041Sobrien however, it's faster to always do the copy. */ 51991041Sobrien 52091041Sobrien#ifdef L_m16stubsf0 52191041Sobrien/* () */ 52291041SobrienSTARTFN (__mips16_call_stub_sf_0) 52391041Sobrien .set noreorder 52491041Sobrien move $18,$31 52591041Sobrien jal $2 52691041Sobrien nop 52791041Sobrien mfc1 $2,$f0 52838889Sjdp j $18 52938889Sjdp nop 53038889Sjdp .set reorder 53138889Sjdp ENDFN (__mips16_call_stub_sf_0) 53238889Sjdp#endif 53338889Sjdp 53438889Sjdp#ifdef L_m16stubsf1 53538889Sjdp/* (float) */ 53689857SobrienSTARTFN (__mips16_call_stub_sf_1) 53789857Sobrien .set noreorder 53889857Sobrien mtc1 $4,$f12 53989857Sobrien move $18,$31 54089857Sobrien jal $2 54189857Sobrien nop 54289857Sobrien mfc1 $2,$f0 54389857Sobrien j $18 54489857Sobrien nop 54589857Sobrien .set reorder 54689857Sobrien ENDFN (__mips16_call_stub_sf_1) 54738889Sjdp#endif 54838889Sjdp 54977298Sobrien#ifdef L_m16stubsf5 55089857Sobrien/* (float, float) */ 55160484SobrienSTARTFN (__mips16_call_stub_sf_5) 55289857Sobrien .set noreorder 55338889Sjdp mtc1 $4,$f12 55489857Sobrien mtc1 $5,$f14 55560484Sobrien move $18,$31 55638889Sjdp jal $2 55777298Sobrien nop 55838889Sjdp mfc1 $2,$f0 55960484Sobrien j $18 56060484Sobrien nop 56189857Sobrien .set reorder 56289857Sobrien ENDFN (__mips16_call_stub_sf_5) 56389857Sobrien#endif 56460484Sobrien 56538889Sjdp#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) 56689857Sobrien#ifdef L_m16stubsf2 56738889Sjdp/* (double) */ 56860484SobrienSTARTFN (__mips16_call_stub_sf_2) 56989857Sobrien .set noreorder 57089857Sobrien LDDBL1 57138889Sjdp move $18,$31 57289857Sobrien jal $2 57389857Sobrien nop 57489857Sobrien mfc1 $2,$f0 57538889Sjdp j $18 57638889Sjdp nop 57777298Sobrien .set reorder 57877298Sobrien ENDFN (__mips16_call_stub_sf_2) 57938889Sjdp#endif 58038889Sjdp 58160484Sobrien#ifdef L_m16stubsf6 58260484Sobrien/* (double, float) */ 58338889SjdpSTARTFN (__mips16_call_stub_sf_6) 58438889Sjdp .set noreorder 58589857Sobrien LDDBL1 58691041Sobrien mtc1 $6,$f14 58760484Sobrien move $18,$31 58860484Sobrien jal $2 58938889Sjdp nop 59038889Sjdp mfc1 $2,$f0 59189857Sobrien j $18 59238889Sjdp nop 59389857Sobrien .set reorder 59438889Sjdp ENDFN (__mips16_call_stub_sf_6) 59577298Sobrien#endif 59689857Sobrien 59789857Sobrien#ifdef L_m16stubsf9 59838889Sjdp/* (float, double) */ 59977298SobrienSTARTFN (__mips16_call_stub_sf_9) 60077298Sobrien .set noreorder 60189857Sobrien mtc1 $4,$f12 60238889Sjdp LDDBL2 60389857Sobrien move $18,$31 60489857Sobrien jal $2 60589857Sobrien nop 60689857Sobrien mfc1 $2,$f0 60789857Sobrien j $18 60889857Sobrien nop 60989857Sobrien .set reorder 61089857Sobrien ENDFN (__mips16_call_stub_sf_9) 61189857Sobrien#endif 61289857Sobrien 61389857Sobrien#ifdef L_m16stubsf10 61489857Sobrien/* (double, double) */ 61589857SobrienSTARTFN (__mips16_call_stub_sf_10) 61689857Sobrien .set noreorder 61789857Sobrien LDDBL1 61889857Sobrien LDDBL2 61989857Sobrien move $18,$31 62089857Sobrien jal $2 62189857Sobrien nop 62289857Sobrien mfc1 $2,$f0 62389857Sobrien j $18 62489857Sobrien nop 62589857Sobrien .set reorder 62689857Sobrien ENDFN (__mips16_call_stub_sf_10) 62789857Sobrien#endif 62889857Sobrien 62960484Sobrien/* Now we have the same set of functions again, except that this time 63060484Sobrien the function being called returns an DFmode value. */ 63177298Sobrien 63289857Sobrien#ifdef L_m16stubdf0 63338889Sjdp/* () */ 63489857SobrienSTARTFN (__mips16_call_stub_df_0) 63538889Sjdp .set noreorder 63689857Sobrien move $18,$31 63738889Sjdp jal $2 63838889Sjdp nop 63938889Sjdp RETDBL 64038889Sjdp j $18 64138889Sjdp nop 64238889Sjdp .set reorder 64338889Sjdp ENDFN (__mips16_call_stub_df_0) 64438889Sjdp#endif 64538889Sjdp 64638889Sjdp#ifdef L_m16stubdf1 64738889Sjdp/* (float) */ 64838889SjdpSTARTFN (__mips16_call_stub_df_1) 64938889Sjdp .set noreorder 65038889Sjdp mtc1 $4,$f12 65138889Sjdp move $18,$31 65238889Sjdp jal $2 65389857Sobrien nop 65438889Sjdp RETDBL 65538889Sjdp j $18 65689857Sobrien nop 65789857Sobrien .set reorder 65838889Sjdp ENDFN (__mips16_call_stub_df_1) 65938889Sjdp#endif 66038889Sjdp 66138889Sjdp#ifdef L_m16stubdf2 66289857Sobrien/* (double) */ 66389857SobrienSTARTFN (__mips16_call_stub_df_2) 66438889Sjdp .set noreorder 66538889Sjdp LDDBL1 66638889Sjdp move $18,$31 66738889Sjdp jal $2 66838889Sjdp nop 66938889Sjdp RETDBL 67038889Sjdp j $18 67138889Sjdp nop 67260484Sobrien .set reorder 67360484Sobrien ENDFN (__mips16_call_stub_df_2) 67460484Sobrien#endif 67560484Sobrien 67689857Sobrien#ifdef L_m16stubdf5 67789857Sobrien/* (float, float) */ 67838889SjdpSTARTFN (__mips16_call_stub_df_5) 67989857Sobrien .set noreorder 68038889Sjdp mtc1 $4,$f12 68189857Sobrien mtc1 $5,$f14 68238889Sjdp move $18,$31 68391041Sobrien jal $2 68489857Sobrien nop 68589857Sobrien RETDBL 68689857Sobrien j $18 68789857Sobrien nop 68889857Sobrien .set reorder 68938889Sjdp ENDFN (__mips16_call_stub_df_5) 69089857Sobrien#endif 69138889Sjdp 69289857Sobrien#ifdef L_m16stubdf6 69338889Sjdp/* (double, float) */ 69489857SobrienSTARTFN (__mips16_call_stub_df_6) 69538889Sjdp .set noreorder 69677298Sobrien LDDBL1 69777298Sobrien mtc1 $6,$f14 69838889Sjdp move $18,$31 69989857Sobrien jal $2 70038889Sjdp nop 70138889Sjdp RETDBL 70238889Sjdp j $18 70338889Sjdp nop 70438889Sjdp .set reorder 70538889Sjdp ENDFN (__mips16_call_stub_df_6) 70638889Sjdp#endif 70738889Sjdp 70838889Sjdp#ifdef L_m16stubdf9 70938889Sjdp/* (float, double) */ 71038889SjdpSTARTFN (__mips16_call_stub_df_9) 71189857Sobrien .set noreorder 71277298Sobrien mtc1 $4,$f12 71389857Sobrien LDDBL2 71477298Sobrien move $18,$31 71589857Sobrien jal $2 71677298Sobrien nop 71760484Sobrien RETDBL 71860484Sobrien j $18 71989857Sobrien nop 72060484Sobrien .set reorder 72160484Sobrien ENDFN (__mips16_call_stub_df_9) 72238889Sjdp#endif 72338889Sjdp 72433965Sjdp#ifdef L_m16stubdf10 72533965Sjdp/* (double, double) */ 72633965SjdpSTARTFN (__mips16_call_stub_df_10) 72733965Sjdp .set noreorder 72889857Sobrien LDDBL1 72989857Sobrien LDDBL2 73089857Sobrien move $18,$31 73189857Sobrien jal $2 73289857Sobrien nop 73389857Sobrien RETDBL 73489857Sobrien j $18 73533965Sjdp nop 73633965Sjdp .set reorder 73733965Sjdp ENDFN (__mips16_call_stub_df_10) 73833965Sjdp#endif 73933965Sjdp#endif /* !__mips_single_float */ 74038889Sjdp