/* Subroutines needed by GCC output code on some machines. */ /* Compile this file with the Unix C compiler! */ /* Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. In addition to the permissions in the GNU General Public License, the Free Software Foundation gives you unlimited permission to link the compiled version of this file with other programs, and to distribute those programs without any restriction coming from the use of this file. (The General Public License restrictions do apply in other respects; for example, they cover modification of the file, and distribution when not linked into another program.) This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, if you link this library with other files, some of which are compiled with GCC, to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ #include "config.h" /* Don't use `fancy_abort' here even if config.h says to use it. */ #ifdef abort #undef abort #endif /* On some machines, cc is really GCC. For these machines, we can't expect these functions to be properly compiled unless GCC open codes the operation (which is precisely when the function won't be used). So allow tm.h to specify ways of accomplishing the operations by defining the macros perform_*. On a machine where cc is some other compiler, there is usually no reason to define perform_*. The other compiler normally has other ways of implementing all of these operations. In some cases a certain machine may come with GCC installed as cc or may have some other compiler. Then it may make sense for tm.h to define perform_* only if __GNUC__ is defined. */ #ifndef perform_mulsi3 #define perform_mulsi3(a, b) return a * b #endif #ifndef perform_divsi3 #define perform_divsi3(a, b) return a / b #endif #ifndef perform_udivsi3 #define perform_udivsi3(a, b) return a / b #endif #ifndef perform_modsi3 #define perform_modsi3(a, b) return a % b #endif #ifndef perform_umodsi3 #define perform_umodsi3(a, b) return a % b #endif #ifndef perform_lshrsi3 #define perform_lshrsi3(a, b) return a >> b #endif #ifndef perform_ashrsi3 #define perform_ashrsi3(a, b) return a >> b #endif #ifndef perform_ashlsi3 #define perform_ashlsi3(a, b) return a << b #endif #ifndef perform_adddf3 #define perform_adddf3(a, b) return a + b #endif #ifndef perform_subdf3 #define perform_subdf3(a, b) return a - b #endif #ifndef perform_muldf3 #define perform_muldf3(a, b) return a * b #endif #ifndef perform_divdf3 #define perform_divdf3(a, b) return a / b #endif #ifndef perform_addsf3 #define perform_addsf3(a, b) return INTIFY (a + b) #endif #ifndef perform_subsf3 #define perform_subsf3(a, b) return INTIFY (a - b) #endif #ifndef perform_mulsf3 #define perform_mulsf3(a, b) return INTIFY (a * b) #endif #ifndef perform_divsf3 #define perform_divsf3(a, b) return INTIFY (a / b) #endif #ifndef perform_negdf2 #define perform_negdf2(a) return -a #endif #ifndef perform_negsf2 #define perform_negsf2(a) return INTIFY (-a) #endif #ifndef perform_fixdfsi #define perform_fixdfsi(a) return (nongcc_SI_type) a; #endif #ifndef perform_fixsfsi #define perform_fixsfsi(a) return (nongcc_SI_type) a #endif #ifndef perform_floatsidf #define perform_floatsidf(a) return (double) a #endif #ifndef perform_floatsisf #define perform_floatsisf(a) return INTIFY ((float) a) #endif #ifndef perform_extendsfdf2 #define perform_extendsfdf2(a) return a #endif #ifndef perform_truncdfsf2 #define perform_truncdfsf2(a) return INTIFY (a) #endif /* Note that eqdf2 returns a value for "true" that is == 0, nedf2 returns a value for "true" that is != 0, gtdf2 returns a value for "true" that is > 0, and so on. */ #ifndef perform_eqdf2 #define perform_eqdf2(a, b) return !(a == b) #endif #ifndef perform_nedf2 #define perform_nedf2(a, b) return a != b #endif #ifndef perform_gtdf2 #define perform_gtdf2(a, b) return a > b #endif #ifndef perform_gedf2 #define perform_gedf2(a, b) return (a >= b) - 1 #endif #ifndef perform_ltdf2 #define perform_ltdf2(a, b) return -(a < b) #endif #ifndef perform_ledf2 #define perform_ledf2(a, b) return 1 - (a <= b) #endif #ifndef perform_eqsf2 #define perform_eqsf2(a, b) return !(a == b) #endif #ifndef perform_nesf2 #define perform_nesf2(a, b) return a != b #endif #ifndef perform_gtsf2 #define perform_gtsf2(a, b) return a > b #endif #ifndef perform_gesf2 #define perform_gesf2(a, b) return (a >= b) - 1 #endif #ifndef perform_ltsf2 #define perform_ltsf2(a, b) return -(a < b) #endif #ifndef perform_lesf2 #define perform_lesf2(a, b) return 1 - (a <= b); #endif /* Define the C data type to use for an SImode value. */ #ifndef nongcc_SI_type #define nongcc_SI_type long int #endif /* Define the C data type to use for a value of word size */ #ifndef nongcc_word_type #define nongcc_word_type nongcc_SI_type #endif /* Define the type to be used for returning an SF mode value and the method for turning a float into that type. These definitions work for machines where an SF value is returned in the same register as an int. */ #ifndef FLOAT_VALUE_TYPE #define FLOAT_VALUE_TYPE int #endif #ifndef INTIFY #define INTIFY(FLOATVAL) (intify.f = (FLOATVAL), intify.i) #endif #ifndef FLOATIFY #define FLOATIFY(INTVAL) ((INTVAL).f) #endif #ifndef FLOAT_ARG_TYPE #define FLOAT_ARG_TYPE union flt_or_int #endif union flt_or_value { FLOAT_VALUE_TYPE i; float f; }; union flt_or_int { int i; float f; }; #ifdef L_mulsi3 nongcc_SI_type __mulsi3 (a, b) nongcc_SI_type a, b; { perform_mulsi3 (a, b); } #endif #ifdef L_udivsi3 nongcc_SI_type __udivsi3 (a, b) unsigned nongcc_SI_type a, b; { perform_udivsi3 (a, b); } #endif #ifdef L_divsi3 nongcc_SI_type __divsi3 (a, b) nongcc_SI_type a, b; { perform_divsi3 (a, b); } #endif #ifdef L_umodsi3 nongcc_SI_type __umodsi3 (a, b) unsigned nongcc_SI_type a, b; { perform_umodsi3 (a, b); } #endif #ifdef L_modsi3 nongcc_SI_type __modsi3 (a, b) nongcc_SI_type a, b; { perform_modsi3 (a, b); } #endif #ifdef L_lshrsi3 nongcc_SI_type __lshrsi3 (a, b) unsigned nongcc_SI_type a, b; { perform_lshrsi3 (a, b); } #endif #ifdef L_ashrsi3 nongcc_SI_type __ashrsi3 (a, b) nongcc_SI_type a, b; { perform_ashrsi3 (a, b); } #endif #ifdef L_ashlsi3 nongcc_SI_type __ashlsi3 (a, b) nongcc_SI_type a, b; { perform_ashlsi3 (a, b); } #endif #ifdef L_divdf3 double __divdf3 (a, b) double a, b; { perform_divdf3 (a, b); } #endif #ifdef L_muldf3 double __muldf3 (a, b) double a, b; { perform_muldf3 (a, b); } #endif #ifdef L_negdf2 double __negdf2 (a) double a; { perform_negdf2 (a); } #endif #ifdef L_adddf3 double __adddf3 (a, b) double a, b; { perform_adddf3 (a, b); } #endif #ifdef L_subdf3 double __subdf3 (a, b) double a, b; { perform_subdf3 (a, b); } #endif /* Note that eqdf2 returns a value for "true" that is == 0, nedf2 returns a value for "true" that is != 0, gtdf2 returns a value for "true" that is > 0, and so on. */ #ifdef L_eqdf2 nongcc_word_type __eqdf2 (a, b) double a, b; { /* Value == 0 iff a == b. */ perform_eqdf2 (a, b); } #endif #ifdef L_nedf2 nongcc_word_type __nedf2 (a, b) double a, b; { /* Value != 0 iff a != b. */ perform_nedf2 (a, b); } #endif #ifdef L_gtdf2 nongcc_word_type __gtdf2 (a, b) double a, b; { /* Value > 0 iff a > b. */ perform_gtdf2 (a, b); } #endif #ifdef L_gedf2 nongcc_word_type __gedf2 (a, b) double a, b; { /* Value >= 0 iff a >= b. */ perform_gedf2 (a, b); } #endif #ifdef L_ltdf2 nongcc_word_type __ltdf2 (a, b) double a, b; { /* Value < 0 iff a < b. */ perform_ltdf2 (a, b); } #endif #ifdef L_ledf2 nongcc_word_type __ledf2 (a, b) double a, b; { /* Value <= 0 iff a <= b. */ perform_ledf2 (a, b); } #endif #ifdef L_fixdfsi nongcc_SI_type __fixdfsi (a) double a; { perform_fixdfsi (a); } #endif #ifdef L_fixsfsi nongcc_SI_type __fixsfsi (a) FLOAT_ARG_TYPE a; { union flt_or_value intify; perform_fixsfsi (FLOATIFY (a)); } #endif #ifdef L_floatsidf double __floatsidf (a) nongcc_SI_type a; { perform_floatsidf (a); } #endif #ifdef L_floatsisf FLOAT_VALUE_TYPE __floatsisf (a) nongcc_SI_type a; { union flt_or_value intify; perform_floatsisf (a); } #endif #ifdef L_addsf3 FLOAT_VALUE_TYPE __addsf3 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_value intify; perform_addsf3 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_negsf2 FLOAT_VALUE_TYPE __negsf2 (a) FLOAT_ARG_TYPE a; { union flt_or_value intify; perform_negsf2 (FLOATIFY (a)); } #endif #ifdef L_subsf3 FLOAT_VALUE_TYPE __subsf3 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_value intify; perform_subsf3 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_eqsf2 nongcc_word_type __eqsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value == 0 iff a == b. */ perform_eqsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_nesf2 nongcc_word_type __nesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value != 0 iff a != b. */ perform_nesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_gtsf2 nongcc_word_type __gtsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value > 0 iff a > b. */ perform_gtsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_gesf2 nongcc_word_type __gesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value >= 0 iff a >= b. */ perform_gesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_ltsf2 nongcc_word_type __ltsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value < 0 iff a < b. */ perform_ltsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_lesf2 nongcc_word_type __lesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value <= 0 iff a <= b. */ perform_lesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_mulsf3 FLOAT_VALUE_TYPE __mulsf3 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_value intify; perform_mulsf3 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_divsf3 FLOAT_VALUE_TYPE __divsf3 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_value intify; perform_divsf3 (FLOATIFY (a), FLOATIFY (b)); } #endif #ifdef L_truncdfsf2 FLOAT_VALUE_TYPE __truncdfsf2 (a) double a; { union flt_or_value intify; perform_truncdfsf2 (a); } #endif #ifdef L_extendsfdf2 double __extendsfdf2 (a) FLOAT_ARG_TYPE a; { union flt_or_value intify; perform_extendsfdf2 (FLOATIFY (a)); } #endif