libgcc2.h revision 146895
190075Sobrien/* Header file for libgcc2.c.  */
290075Sobrien/* Copyright (C) 2000, 2001
390075Sobrien   Free Software Foundation, Inc.
490075Sobrien
590075SobrienThis file is part of GCC.
690075Sobrien
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1190075Sobrien
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1690075Sobrien
1790075SobrienYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, USA.  */
2190075Sobrien
22117395Skan/* As a special exception, if you link this library with other files,
23117395Skan   some of which are compiled with GCC, to produce an executable,
24117395Skan   this library does not by itself cause the resulting executable
25117395Skan   to be covered by the GNU General Public License.
26117395Skan   This exception does not however invalidate any other reasons why
27117395Skan   the executable file might be covered by the GNU General Public License.  */
28117395Skan
29117395Skan
3090075Sobrien#ifndef GCC_LIBGCC2_H
3190075Sobrien#define GCC_LIBGCC2_H
3290075Sobrien
3390075Sobrienextern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t);
3490075Sobrienextern void __clear_cache (char *, char *);
3590075Sobrienextern void __eprintf (const char *, const char *, unsigned int, const char *)
3690075Sobrien  __attribute__ ((__noreturn__));
3790075Sobrien
3890075Sobrienstruct exception_descriptor;
3990075Sobrienextern short int __get_eh_table_language (struct exception_descriptor *);
4090075Sobrienextern short int __get_eh_table_version (struct exception_descriptor *);
4190075Sobrien
4290075Sobrien/* Permit the tm.h file to select the endianness to use just for this
4390075Sobrien   file.  This is used when the endianness is determined when the
4490075Sobrien   compiler is run.  */
4590075Sobrien
4690075Sobrien#ifndef LIBGCC2_WORDS_BIG_ENDIAN
4790075Sobrien#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
4890075Sobrien#endif
4990075Sobrien
5090075Sobrien#ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
5190075Sobrien#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
5290075Sobrien#endif
5390075Sobrien
5490075Sobrien#ifndef MIN_UNITS_PER_WORD
5590075Sobrien#define MIN_UNITS_PER_WORD UNITS_PER_WORD
5690075Sobrien#endif
5790075Sobrien
5890075Sobrien/* In the first part of this file, we are interfacing to calls generated
5990075Sobrien   by the compiler itself.  These calls pass values into these routines
6090075Sobrien   which have very specific modes (rather than very specific types), and
6190075Sobrien   these compiler-generated calls also expect any return values to have
6290075Sobrien   very specific modes (rather than very specific types).  Thus, we need
6390075Sobrien   to avoid using regular C language type names in this part of the file
6490075Sobrien   because the sizes for those types can be configured to be anything.
6590075Sobrien   Instead we use the following special type names.  */
6690075Sobrien
6790075Sobrientypedef		 int QItype	__attribute__ ((mode (QI)));
6890075Sobrientypedef unsigned int UQItype	__attribute__ ((mode (QI)));
6990075Sobrientypedef		 int HItype	__attribute__ ((mode (HI)));
7090075Sobrientypedef unsigned int UHItype	__attribute__ ((mode (HI)));
7190075Sobrien#if MIN_UNITS_PER_WORD > 1
72132718Skan/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1.  */
7390075Sobrientypedef 	 int SItype	__attribute__ ((mode (SI)));
7490075Sobrientypedef unsigned int USItype	__attribute__ ((mode (SI)));
7590075Sobrien#if LONG_LONG_TYPE_SIZE > 32
76132718Skan/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2.  */
7790075Sobrientypedef		 int DItype	__attribute__ ((mode (DI)));
7890075Sobrientypedef unsigned int UDItype	__attribute__ ((mode (DI)));
7990075Sobrien#if MIN_UNITS_PER_WORD > 4
80132718Skan/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4.  */
8190075Sobrientypedef		 int TItype	__attribute__ ((mode (TI)));
8290075Sobrientypedef unsigned int UTItype	__attribute__ ((mode (TI)));
8390075Sobrien#endif
8490075Sobrien#endif
8590075Sobrien#endif
8690075Sobrien
8790075Sobrien#if BITS_PER_UNIT == 8
8890075Sobrien
8990075Sobrientypedef 	float SFtype	__attribute__ ((mode (SF)));
9090075Sobrientypedef		float DFtype	__attribute__ ((mode (DF)));
9190075Sobrien
9290075Sobrien#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
9390075Sobrientypedef		float XFtype	__attribute__ ((mode (XF)));
9490075Sobrien#endif
9590075Sobrien#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
9690075Sobrientypedef		float TFtype	__attribute__ ((mode (TF)));
9790075Sobrien#endif
9890075Sobrien
9990075Sobrien#else /* BITS_PER_UNIT != 8 */
10090075Sobrien
10190075Sobrien/* On dsp's there are usually qf/hf/tqf modes used instead of the above.
10290075Sobrien   For now we don't support them in libgcc2.c.  */
10390075Sobrien
10490075Sobrien#undef L_fixdfdi
10590075Sobrien#undef L_fixsfdi
10690075Sobrien#undef L_fixtfdi
10790075Sobrien#undef L_fixunsdfdi
10890075Sobrien#undef L_fixunsdfsi
10990075Sobrien#undef L_fixunssfdi
11090075Sobrien#undef L_fixunssfsi
11190075Sobrien#undef L_fixunstfdi
11290075Sobrien#undef L_fixunsxfdi
11390075Sobrien#undef L_fixunsxfsi
11490075Sobrien#undef L_fixxfdi
11590075Sobrien#undef L_floatdidf
11690075Sobrien#undef L_floatdisf
11790075Sobrien#undef L_floatditf
11890075Sobrien#undef L_floatdixf
11990075Sobrien
12090075Sobrien#endif /* BITS_PER_UNIT != 8 */
12190075Sobrien
12290075Sobrientypedef int word_type __attribute__ ((mode (__word__)));
12390075Sobrien
12490075Sobrien/* Make sure that we don't accidentally use any normal C language built-in
12590075Sobrien   type names in the first part of this file.  Instead we want to use *only*
12690075Sobrien   the type names defined above.  The following macro definitions insure
12790075Sobrien   that if we *do* accidentally use some normal C language built-in type name,
12890075Sobrien   we will get a syntax error.  */
12990075Sobrien
13090075Sobrien#define char bogus_type
13190075Sobrien#define short bogus_type
13290075Sobrien#define int bogus_type
13390075Sobrien#define long bogus_type
13490075Sobrien#define unsigned bogus_type
13590075Sobrien#define float bogus_type
13690075Sobrien#define double bogus_type
13790075Sobrien
138146895Skan/* Versions prior to 3.4.4 were not taking into account the word size for
139146895Skan   the 5 trapping arithmetic functions absv, addv, subv, mulv and negv.  As
140146895Skan   a consequence, the si and di variants were always and the only ones emitted.
141146895Skan   To maintain backward compatibility, COMPAT_SIMODE_TRAPPING_ARITHMETIC is
142146895Skan   defined on platforms where it makes sense to still have the si variants
143146895Skan   emitted.  As a bonus, their implementation is now correct.  Note that the
144146895Skan   same mechanism should have been implemented for the di variants, but it
145146895Skan   turns out that no platform would define COMPAT_DIMODE_TRAPPING_ARITHMETIC
146146895Skan   if it existed.  */
147146895Skan
14890075Sobrien#if MIN_UNITS_PER_WORD > 4
14990075Sobrien#define W_TYPE_SIZE (8 * BITS_PER_UNIT)
15090075Sobrien#define Wtype	DItype
15190075Sobrien#define UWtype	UDItype
15290075Sobrien#define HWtype	DItype
15390075Sobrien#define UHWtype	UDItype
15490075Sobrien#define DWtype	TItype
15590075Sobrien#define UDWtype	UTItype
15690075Sobrien#define __NW(a,b)	__ ## a ## di ## b
15790075Sobrien#define __NDW(a,b)	__ ## a ## ti ## b
158146895Skan#define COMPAT_SIMODE_TRAPPING_ARITHMETIC
15990075Sobrien#elif MIN_UNITS_PER_WORD > 2 \
16090075Sobrien      || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)
16190075Sobrien#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
16290075Sobrien#define Wtype	SItype
16390075Sobrien#define UWtype	USItype
16490075Sobrien#define HWtype	SItype
16590075Sobrien#define UHWtype	USItype
16690075Sobrien#define DWtype	DItype
16790075Sobrien#define UDWtype	UDItype
16890075Sobrien#define __NW(a,b)	__ ## a ## si ## b
16990075Sobrien#define __NDW(a,b)	__ ## a ## di ## b
17090075Sobrien#elif MIN_UNITS_PER_WORD > 1
17190075Sobrien#define W_TYPE_SIZE (2 * BITS_PER_UNIT)
17290075Sobrien#define Wtype	HItype
17390075Sobrien#define UWtype	UHItype
17490075Sobrien#define HWtype	HItype
17590075Sobrien#define UHWtype	UHItype
17690075Sobrien#define DWtype	SItype
17790075Sobrien#define UDWtype	USItype
17890075Sobrien#define __NW(a,b)	__ ## a ## hi ## b
17990075Sobrien#define __NDW(a,b)	__ ## a ## si ## b
18090075Sobrien#else
18190075Sobrien#define W_TYPE_SIZE BITS_PER_UNIT
18290075Sobrien#define Wtype	QItype
18390075Sobrien#define UWtype  UQItype
18490075Sobrien#define HWtype	QItype
18590075Sobrien#define UHWtype	UQItype
18690075Sobrien#define DWtype	HItype
18790075Sobrien#define UDWtype	UHItype
18890075Sobrien#define __NW(a,b)	__ ## a ## qi ## b
18990075Sobrien#define __NDW(a,b)	__ ## a ## hi ## b
19090075Sobrien#endif
19190075Sobrien
19290075Sobrien#define Wtype_MAX ((Wtype)(((UWtype)1 << (W_TYPE_SIZE - 1)) - 1))
19390075Sobrien#define Wtype_MIN (- Wtype_MAX - 1)
19490075Sobrien
19590075Sobrien#define __muldi3	__NDW(mul,3)
19690075Sobrien#define __divdi3	__NDW(div,3)
19790075Sobrien#define __udivdi3	__NDW(udiv,3)
19890075Sobrien#define __moddi3	__NDW(mod,3)
19990075Sobrien#define __umoddi3	__NDW(umod,3)
20090075Sobrien#define __negdi2	__NDW(neg,2)
20190075Sobrien#define __lshrdi3	__NDW(lshr,3)
20290075Sobrien#define __ashldi3	__NDW(ashl,3)
20390075Sobrien#define __ashrdi3	__NDW(ashr,3)
20490075Sobrien#define __cmpdi2	__NDW(cmp,2)
20590075Sobrien#define __ucmpdi2	__NDW(ucmp,2)
20690075Sobrien#define __udivmoddi4	__NDW(udivmod,4)
20790075Sobrien#define __fixunstfDI	__NDW(fixunstf,)
20890075Sobrien#define __fixtfdi	__NDW(fixtf,)
20990075Sobrien#define __fixunsxfDI	__NDW(fixunsxf,)
21090075Sobrien#define __fixxfdi	__NDW(fixxf,)
21190075Sobrien#define __fixunsdfDI	__NDW(fixunsdf,)
21290075Sobrien#define __fixdfdi	__NDW(fixdf,)
21390075Sobrien#define __fixunssfDI	__NDW(fixunssf,)
21490075Sobrien#define __fixsfdi	__NDW(fixsf,)
21590075Sobrien#define __floatdixf	__NDW(float,xf)
21690075Sobrien#define __floatditf	__NDW(float,tf)
21790075Sobrien#define __floatdidf	__NDW(float,df)
21890075Sobrien#define __floatdisf	__NDW(float,sf)
21990075Sobrien#define __fixunsxfSI	__NW(fixunsxf,)
22090075Sobrien#define __fixunstfSI	__NW(fixunstf,)
22190075Sobrien#define __fixunsdfSI	__NW(fixunsdf,)
22290075Sobrien#define __fixunssfSI	__NW(fixunssf,)
22390075Sobrien
224146895Skan#define __absvSI2	__NW(absv,2)
225146895Skan#define __addvSI3	__NW(addv,3)
226146895Skan#define __subvSI3	__NW(subv,3)
227146895Skan#define __mulvSI3	__NW(mulv,3)
228146895Skan#define __negvSI2	__NW(negv,2)
229146895Skan#define __absvDI2	__NDW(absv,2)
230146895Skan#define __addvDI3	__NDW(addv,3)
231146895Skan#define __subvDI3	__NDW(subv,3)
232146895Skan#define __mulvDI3	__NDW(mulv,3)
233146895Skan#define __negvDI2	__NDW(negv,2)
234146895Skan
235132718Skan#define __ffsSI2	__NW(ffs,2)
236132718Skan#define __clzSI2	__NW(clz,2)
237132718Skan#define __ctzSI2	__NW(ctz,2)
238132718Skan#define __popcountSI2	__NW(popcount,2)
239132718Skan#define __paritySI2	__NW(parity,2)
240132718Skan#define __ffsDI2	__NDW(ffs,2)
241132718Skan#define __clzDI2	__NDW(clz,2)
242132718Skan#define __ctzDI2	__NDW(ctz,2)
243132718Skan#define __popcountDI2	__NDW(popcount,2)
244132718Skan#define __parityDI2	__NDW(parity,2)
245132718Skan
24690075Sobrienextern DWtype __muldi3 (DWtype, DWtype);
24790075Sobrienextern DWtype __divdi3 (DWtype, DWtype);
24890075Sobrienextern UDWtype __udivdi3 (UDWtype, UDWtype);
24990075Sobrienextern UDWtype __umoddi3 (UDWtype, UDWtype);
25090075Sobrienextern DWtype __moddi3 (DWtype, DWtype);
25190075Sobrien
25290075Sobrien/* __udivmoddi4 is static inline when building other libgcc2 portions.  */
25390075Sobrien#if (!defined (L_udivdi3) && !defined (L_divdi3) && \
25490075Sobrien     !defined (L_umoddi3) && !defined (L_moddi3))
25590075Sobrienextern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *);
25690075Sobrien#endif
25790075Sobrien
25890075Sobrien/* __negdi2 is static inline when building other libgcc2 portions.  */
25990075Sobrien#if !defined(L_divdi3) && !defined(L_moddi3)
26090075Sobrienextern DWtype __negdi2 (DWtype);
26190075Sobrien#endif
26290075Sobrien
26390075Sobrienextern DWtype __lshrdi3 (DWtype, word_type);
26490075Sobrienextern DWtype __ashldi3 (DWtype, word_type);
26590075Sobrienextern DWtype __ashrdi3 (DWtype, word_type);
26690075Sobrien
26790075Sobrien/* __udiv_w_sdiv is static inline when building other libgcc2 portions.  */
26890075Sobrien#if (!defined(L_udivdi3) && !defined(L_divdi3) && \
26990075Sobrien     !defined(L_umoddi3) && !defined(L_moddi3))
27090075Sobrienextern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
27190075Sobrien#endif
27290075Sobrien
27390075Sobrienextern word_type __cmpdi2 (DWtype, DWtype);
27490075Sobrienextern word_type __ucmpdi2 (DWtype, DWtype);
27590075Sobrien
276146895Skanextern Wtype __absvSI2 (Wtype);
277146895Skanextern Wtype __addvSI3 (Wtype, Wtype);
278146895Skanextern Wtype __subvSI3 (Wtype, Wtype);
279146895Skanextern Wtype __mulvSI3 (Wtype, Wtype);
280146895Skanextern Wtype __negvSI2 (Wtype);
281146895Skanextern DWtype __absvDI2 (DWtype);
282146895Skanextern DWtype __addvDI3 (DWtype, DWtype);
283146895Skanextern DWtype __subvDI3 (DWtype, DWtype);
284146895Skanextern DWtype __mulvDI3 (DWtype, DWtype);
285146895Skanextern DWtype __negvDI2 (DWtype);
28690075Sobrien
287146895Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
288146895Skanextern SItype __absvsi2 (SItype);
289146895Skanextern SItype __addvsi3 (SItype, SItype);
290146895Skanextern SItype __subvsi3 (SItype, SItype);
291146895Skanextern SItype __mulvsi3 (SItype, SItype);
292146895Skanextern SItype __negvsi2 (SItype);
293146895Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
294146895Skan
29590075Sobrien#if BITS_PER_UNIT == 8
29690075Sobrienextern DWtype __fixdfdi (DFtype);
29790075Sobrienextern DWtype __fixsfdi (SFtype);
29890075Sobrienextern DFtype __floatdidf (DWtype);
29990075Sobrienextern SFtype __floatdisf (DWtype);
30090075Sobrienextern UWtype __fixunsdfSI (DFtype);
30190075Sobrienextern UWtype __fixunssfSI (SFtype);
30290075Sobrienextern DWtype __fixunsdfDI (DFtype);
30390075Sobrienextern DWtype __fixunssfDI (SFtype);
30490075Sobrien
30590075Sobrien#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
30690075Sobrienextern DWtype __fixxfdi (XFtype);
30790075Sobrienextern DWtype __fixunsxfDI (XFtype);
30890075Sobrienextern XFtype __floatdixf (DWtype);
30990075Sobrienextern UWtype __fixunsxfSI (XFtype);
31090075Sobrien#endif
31190075Sobrien
31290075Sobrien#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
31390075Sobrienextern DWtype __fixunstfDI (TFtype);
31490075Sobrienextern DWtype __fixtfdi (TFtype);
31590075Sobrienextern TFtype __floatditf (DWtype);
31690075Sobrien#endif
31790075Sobrien#endif /* BITS_PER_UNIT == 8 */
31890075Sobrien
31990075Sobrien/* DWstructs are pairs of Wtype values in the order determined by
32090075Sobrien   LIBGCC2_WORDS_BIG_ENDIAN.  */
32190075Sobrien
32290075Sobrien#if LIBGCC2_WORDS_BIG_ENDIAN
32390075Sobrien  struct DWstruct {Wtype high, low;};
32490075Sobrien#else
32590075Sobrien  struct DWstruct {Wtype low, high;};
32690075Sobrien#endif
32790075Sobrien
32890075Sobrien/* We need this union to unpack/pack DImode values, since we don't have
32990075Sobrien   any arithmetic yet.  Incoming DImode parameters are stored into the
33090075Sobrien   `ll' field, and the unpacked result is read from the struct `s'.  */
33190075Sobrien
33290075Sobrientypedef union
33390075Sobrien{
33490075Sobrien  struct DWstruct s;
33590075Sobrien  DWtype ll;
33690075Sobrien} DWunion;
33790075Sobrien
33890075Sobrien#include "longlong.h"
33990075Sobrien
34090075Sobrien#endif /* ! GCC_LIBGCC2_H */
341