1992-01-28 04:44:05 +01:00
|
|
|
|
/* More subroutines needed by GCC output code on some machines. */
|
|
|
|
|
/* Compile this one with gcc. */
|
2001-01-31 04:53:32 +01:00
|
|
|
|
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
2002-08-13 14:11:20 +02:00
|
|
|
|
2000, 2001, 2002 Free Software Foundation, Inc.
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 16:35:51 +02:00
|
|
|
|
This file is part of GCC.
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 16:35:51 +02:00
|
|
|
|
GCC 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.
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2000-05-16 01:14:17 +02:00
|
|
|
|
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 into combinations with other programs,
|
|
|
|
|
and to distribute those combinations 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 a combine
|
|
|
|
|
executable.)
|
|
|
|
|
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 16:35:51 +02:00
|
|
|
|
GCC 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.
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
Makefile.in, [...]: replace "GNU CC" with "GCC".
* Makefile.in, alias.c, basic-block.h, bb-reorder.c, bitmap.c,
bitmap.h, builtin-types.def, builtins.c, builtins.def,
c-aux-info.c, c-common.c, c-common.def, c-common.h,
c-convert.c, c-decl.c, c-dump.c, c-dump.h, c-errors.c,
c-format.c, c-lang.c, c-lex.c, c-lex.h, c-parse.in,
c-pragma.c, c-pragma.h, c-semantics.c, c-tree.h, c-typeck.c,
caller-save.c, calls.c, collect2.c, collect2.h, combine.c,
conditions.h, config.gcc, configure.frag, configure.in,
conflict.c, convert.c, convert.h, cppspec.c, crtstuff.c,
cse.c, cselib.c, cselib.h, dbxout.c, dbxout.h, defaults.h,
dependence.c, df.c, df.h, diagnostic.c, diagnostic.h,
doloop.c, dominance.c, dwarf.h, dwarf2.h, dwarf2asm.c,
dwarf2asm.h, dwarf2out.c, dwarf2out.h, dwarfout.c,
emit-rtl.c, errors.c, errors.h, except.c, except.h,
exgettext, explow.c, expmed.c, expr.c, expr.h, final.c,
fixproto, flags.h, flow.c, fold-const.c, fp-test.c,
function.c, function.h, gbl-ctors.h, gcc.c, gcc.h, gcc.hlp,
gccspec.c, gcov-io.h, gcse.c, genattr.c, genattrtab.c,
gencheck.c, gencodes.c, genconfig.c, genemit.c,
genextract.c, genflags.c, gengenrtl.c, genmultilib,
genopinit.c, genoutput.c, genpeep.c, genrecog.c,
gensupport.c, gensupport.h, ggc-callbacks.c, ggc-common.c,
ggc-none.c, ggc-page.c, ggc-simple.c, ggc.h, global.c,
graph.c, graph.h, gthr-aix.h, gthr-dce.h, gthr-posix.h,
gthr-rtems.h, gthr-single.h, gthr-solaris.h, gthr-vxworks.h,
gthr-win32.h, gthr.h, haifa-sched.c, halfpic.c, halfpic.h,
hard-reg-set.h, hwint.h, ifcvt.c, input.h, insn-addr.h,
integrate.c, integrate.h, jump.c, lcm.c, libgcc2.c,
libgcc2.h, lists.c, local-alloc.c, loop.c, loop.h,
machmode.def, machmode.h, main.c, mbchar.c, mbchar.h,
mips-tdump.c, mips-tfile.c, mklibgcc.in, mkmap-flat.awk,
mkmap-symver.awk, optabs.c, output.h, params.c, params.def,
params.h, predict.c, predict.def, predict.h, prefix.c,
prefix.h, print-rtl.c, print-tree.c, profile.c, protoize.c,
read-rtl.c, real.c, real.h, recog.c, recog.h, reg-stack.c,
regclass.c, regmove.c, regrename.c, regs.h, reload.c,
reload.h, reload1.c, reorg.c, resource.c, resource.h, rtl.c,
rtl.def, rtl.h, rtlanal.c, sbitmap.c, sbitmap.h,
sched-deps.c, sched-ebb.c, sched-int.h, sched-rgn.c,
sched-vis.c, sdbout.c, sdbout.h, sibcall.c, simplify-rtx.c,
ssa-ccp.c, ssa-dce.c, ssa.c, ssa.h, stmt.c, stor-layout.c,
stringpool.c, system.h, timevar.c, timevar.def, timevar.h,
tlink.c, toplev.c, toplev.h, tree.c, tree.def, tree.h,
tsystem.h, unroll.c, unwind-dw2-fde.c, unwind-dw2-fde.h,
unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h,
unwind.inc, varasm.c, varray.c, varray.h, xcoffout.c,
xcoffout.h: replace "GNU CC" with "GCC".
From-SVN: r45105
2001-08-22 16:35:51 +02:00
|
|
|
|
along with GCC; see the file COPYING. If not, write to the Free
|
|
|
|
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
|
02111-1307, USA. */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
/* It is incorrect to include config.h here, because this file is being
|
|
|
|
|
compiled for the target, and hence definitions concerning only the host
|
|
|
|
|
do not apply. */
|
|
|
|
|
|
1992-07-17 11:57:24 +02:00
|
|
|
|
#include "tconfig.h"
|
2000-02-01 22:30:52 +01:00
|
|
|
|
#include "tsystem.h"
|
2002-12-16 19:23:00 +01:00
|
|
|
|
#include "coretypes.h"
|
|
|
|
|
#include "tm.h"
|
1998-04-17 10:26:33 +02:00
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
/* Don't use `fancy_abort' here even if config.h says to use it. */
|
|
|
|
|
#ifdef abort
|
|
|
|
|
#undef abort
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-03-09 04:39:09 +01:00
|
|
|
|
#include "libgcc2.h"
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2002-07-31 01:55:09 +02:00
|
|
|
|
#ifdef DECLARE_LIBRARY_RENAMES
|
|
|
|
|
DECLARE_LIBRARY_RENAMES
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-07-22 02:15:49 +02:00
|
|
|
|
#if defined (L_negdi2)
|
2000-10-19 17:44:32 +02:00
|
|
|
|
DWtype
|
|
|
|
|
__negdi2 (DWtype u)
|
|
|
|
|
{
|
|
|
|
|
DWunion w;
|
|
|
|
|
DWunion uu;
|
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
|
|
|
|
|
w.s.low = -uu.s.low;
|
|
|
|
|
w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
|
|
|
|
|
|
|
|
|
|
return w.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
#ifdef L_addvsi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype
|
|
|
|
|
__addvsi3 (Wtype a, Wtype b)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = a + b;
|
|
|
|
|
|
|
|
|
|
if (b >= 0 ? w < a : w > a)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
2001-07-16 11:16:04 +02:00
|
|
|
|
}
|
2000-10-19 17:44:32 +02:00
|
|
|
|
#endif
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
#ifdef L_addvdi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__addvdi3 (DWtype a, DWtype b)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = a + b;
|
|
|
|
|
|
|
|
|
|
if (b >= 0 ? w < a : w > a)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_subvsi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype
|
|
|
|
|
__subvsi3 (Wtype a, Wtype b)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
|
|
|
|
#ifdef L_addvsi3
|
|
|
|
|
return __addvsi3 (a, (-b));
|
|
|
|
|
#else
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = a - b;
|
|
|
|
|
|
|
|
|
|
if (b >= 0 ? w > a : w < a)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_subvdi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__subvdi3 (DWtype a, DWtype b)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
|
|
|
|
#ifdef L_addvdi3
|
|
|
|
|
return (a, (-b));
|
|
|
|
|
#else
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = a - b;
|
|
|
|
|
|
|
|
|
|
if (b >= 0 ? w > a : w < a)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_mulvsi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype
|
|
|
|
|
__mulvsi3 (Wtype a, Wtype b)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = a * b;
|
|
|
|
|
|
2000-10-19 18:25:21 +02:00
|
|
|
|
if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_negvsi2
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype
|
|
|
|
|
__negvsi2 (Wtype a)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2002-05-30 22:55:11 +02:00
|
|
|
|
Wtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = -a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
if (a >= 0 ? w > 0 : w < 0)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_negvdi2
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__negvdi2 (DWtype a)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2002-05-30 22:55:11 +02:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = -a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
if (a >= 0 ? w > 0 : w < 0)
|
|
|
|
|
abort ();
|
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
return w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_absvsi2
|
2000-12-16 23:43:58 +01:00
|
|
|
|
Wtype
|
|
|
|
|
__absvsi2 (Wtype a)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2002-05-30 22:55:11 +02:00
|
|
|
|
Wtype w = a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
if (a < 0)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#ifdef L_negvsi2
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = __negvsi2 (a);
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#else
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = -a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
if (w < 0)
|
|
|
|
|
abort ();
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_absvdi2
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__absvdi2 (DWtype a)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2002-05-30 22:55:11 +02:00
|
|
|
|
DWtype w = a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
if (a < 0)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#ifdef L_negvsi2
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = __negvsi2 (a);
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#else
|
2002-05-30 22:55:11 +02:00
|
|
|
|
w = -a;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
if (w < 0)
|
|
|
|
|
abort ();
|
2000-10-18 23:33:41 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2002-05-30 22:55:11 +02:00
|
|
|
|
return w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_mulvdi3
|
2000-12-16 23:43:58 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__mulvdi3 (DWtype u, DWtype v)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
{
|
2002-05-30 22:55:11 +02:00
|
|
|
|
DWtype w;
|
2000-10-18 23:33:41 +02:00
|
|
|
|
|
|
|
|
|
w = u * v;
|
|
|
|
|
|
2000-10-19 17:44:32 +02:00
|
|
|
|
if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
|
2000-10-18 23:33:41 +02:00
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2003-01-17 04:28:11 +01:00
|
|
|
|
/* Unless shift functions are defined with full ANSI prototypes,
|
(__negdi2, __lshrdi3, __ashldi3, __ashrdi3, __ffsdi2):
Use ANSI style definition with full prototype.
(__muldi3, __udiv_w_sdiv, __udivmoddi4, __divdi3, __moddi3) : Likewise.
(__udivmoddi4, __udivdi3, __cmpdi2, __ucmpdi2) : Likewise.
(__fixunstfdi, __fixtfdi, __fixunsxfdi, __fixxfdi) : Likewise.
(__fixunsdfdi, __fixdfdi, __floatdixf, __floatditf) : Likewise.
(__floatdidf, __floatdisf, __fixunsxfsi, __fixunsdfsi) : Likewise.
(__gcc_bcmp, __eprintf, gopen, gclose, __bb_init_file) : Likewise.
(__bb_init_trace_func, __clear_cache, mprotect) : Likewise.
(__enable_execute_stack, cacheflush, exit) : Likewise.
(find_exception_table, __find_first_exception_table_match) : Likewise.
From-SVN: r13658
1997-02-16 13:55:15 +01:00
|
|
|
|
parameter b will be promoted to int if word_type is smaller than an int. */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L_lshrdi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__lshrdi3 (DWtype u, word_type b)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion w;
|
1995-01-12 17:13:44 +01:00
|
|
|
|
word_type bm;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion uu;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
if (b == 0)
|
|
|
|
|
return u;
|
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (bm <= 0)
|
|
|
|
|
{
|
|
|
|
|
w.s.high = 0;
|
2000-04-15 18:34:38 +02:00
|
|
|
|
w.s.low = (UWtype) uu.s.high >> -bm;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-04-15 18:34:38 +02:00
|
|
|
|
UWtype carries = (UWtype) uu.s.high << bm;
|
|
|
|
|
|
|
|
|
|
w.s.high = (UWtype) uu.s.high >> b;
|
|
|
|
|
w.s.low = ((UWtype) uu.s.low >> b) | carries;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return w.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_ashldi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__ashldi3 (DWtype u, word_type b)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion w;
|
1995-01-12 17:13:44 +01:00
|
|
|
|
word_type bm;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion uu;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
if (b == 0)
|
|
|
|
|
return u;
|
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (bm <= 0)
|
|
|
|
|
{
|
|
|
|
|
w.s.low = 0;
|
2000-04-15 18:34:38 +02:00
|
|
|
|
w.s.high = (UWtype) uu.s.low << -bm;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-04-15 18:34:38 +02:00
|
|
|
|
UWtype carries = (UWtype) uu.s.low >> bm;
|
|
|
|
|
|
|
|
|
|
w.s.low = (UWtype) uu.s.low << b;
|
|
|
|
|
w.s.high = ((UWtype) uu.s.high << b) | carries;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return w.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_ashrdi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__ashrdi3 (DWtype u, word_type b)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion w;
|
1995-01-12 17:13:44 +01:00
|
|
|
|
word_type bm;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion uu;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
if (b == 0)
|
|
|
|
|
return u;
|
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (bm <= 0)
|
|
|
|
|
{
|
|
|
|
|
/* w.s.high = 1..1 or 0..0 */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
w.s.low = uu.s.high >> -bm;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-04-15 18:34:38 +02:00
|
|
|
|
UWtype carries = (UWtype) uu.s.high << bm;
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
w.s.high = uu.s.high >> b;
|
2000-04-15 18:34:38 +02:00
|
|
|
|
w.s.low = ((UWtype) uu.s.low >> b) | carries;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return w.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1993-01-13 05:30:11 +01:00
|
|
|
|
#ifdef L_ffsdi2
|
[multiple changes]
2003-02-01 Richard Henderson <rth@redhat.com>
* optabs.c (expand_unop): Use word_mode for outmode of bit scaners.
* libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2): Change
return type to Wtype.
* libgcc-std.ver (GCC_3.4): Fix inheritance.
* config/i386/i386.md (ffssi2): Use nonimmediate_operand for
expander input constraint.
2003-02-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
* optabs.h (optab_index): Add OTI_clz, OTI_ctz, OTI_popcount and
OTI_parity.
(clz_optab, ctz_optab, popcount_optab, parity_optab): New.
* optabs.c (widen_clz, expand_parity): New.
(expand_unop): Handle clz and parity. Hardcode SImode as outmode
for libcalls to clz, ctz, popcount, and parity.
(init_optabs): Init clz_optab, ctz_optab, popcount_optab and
parity_optab, and set up libfunc handlers.
* libgcc2.c (__clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2,
__popcount_tab): New.
* libgcc2.h: Declare them.
* libgcc-std.ver (GCC_3.4): Add new functions from libgcc2.c.
* genopinit.c (optabs): Add clz_optab, ctz_optab, popcount_optab
and parity_optab.
* builtin-types.def (BT_FN_INT_LONG, BT_FN_INT_LONGLONG): New.
* builtins.def (BUILT_IN_CLZ, BUILT_IN_CTZ, BUILT_IN_POPCOUNT,
BUILT_IN_PARITY, BUILT_IN_FFSL, BUILT_IN_CLZL, BUILT_IN_CTZL,
BUILT_IN_POPCOUNTL, BUILT_IN_PARITYL, BUILT_IN_FFSLL,
BUILT_IN_CLZLL, BUILT_IN_CTZLL, BUILT_IN_POPCOUNTLL,
BUILT_IN_PARITYLL): New.
* builtins.c (expand_builtin_unop): Rename from expand_builtin_ffs
and add optab argument.
(expand_builtin): Expand BUILT_IN_{FFS,CLZ,POPCOUNT,PARITY}*.
* tree.def (CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR, PARITY_EXPR): New.
* expr.c (expand_expr): Handle them.
* fold-const.c (tree_expr_nonnegative_p): Likewise.
* rtl.def (CLZ, CTZ, POPCOUNT, PARITY): New.
* reload1.c (eliminate_regs): Handle them.
(elimination_effects): Likewise.
* function.c (instantiate_virtual_regs_1): Likewise
* genattrtab.c (check_attr_value): Likewise.
* simplify-rtx.c (simplify_unary_operation): Likewise.
* c-common.c (c_common_truthvalue_conversion): Handle POPCOUNT_EXPR.
* combine.c (combine_simplify_rtx): Handle POPCOUNT and PARITY.
(nonzero_bits): Handle CLZ, CTZ, POPCOUNT and PARITY.
* config/alpha/alpha.md (clzdi2, ctzdi2, popcountdi2): New.
* config/arm/arm.c (arm_init_builtins): Rename __builtin_clz to
__builtin_arm_clz.
* Makefile.in (LIB2FUNCS_1, LIB2FUNCS_2): Move...
* mklibgcc.in (lib2funcs): ...here and merge. Add new members.
* doc/extend.texi (Other Builtins): Add new builtins.
* doc/md.texi (Standard Names): Add new patterns.
From-SVN: r62252
2003-02-01 20:00:02 +01:00
|
|
|
|
Wtype
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__ffsdi2 (DWtype u)
|
1993-01-13 05:30:11 +01:00
|
|
|
|
{
|
2000-10-06 07:29:56 +02:00
|
|
|
|
DWunion uu;
|
|
|
|
|
UWtype word, count, add;
|
|
|
|
|
|
1993-01-13 05:30:11 +01:00
|
|
|
|
uu.ll = u;
|
2000-10-06 07:29:56 +02:00
|
|
|
|
if (uu.s.low != 0)
|
|
|
|
|
word = uu.s.low, add = 0;
|
|
|
|
|
else if (uu.s.high != 0)
|
|
|
|
|
word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
count_trailing_zeros (count, word);
|
|
|
|
|
return count + add + 1;
|
1993-01-13 05:30:11 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L_muldi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__muldi3 (DWtype u, DWtype v)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion w;
|
|
|
|
|
DWunion uu, vv;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
uu.ll = u,
|
|
|
|
|
vv.ll = v;
|
|
|
|
|
|
|
|
|
|
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
1999-12-27 09:34:45 +01:00
|
|
|
|
w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
|
|
|
|
|
+ (UWtype) uu.s.high * (UWtype) vv.s.low);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
return w.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-10-21 22:25:38 +02:00
|
|
|
|
#if (defined (L_udivdi3) || defined (L_divdi3) || \
|
|
|
|
|
defined (L_umoddi3) || defined (L_moddi3))
|
2002-10-22 01:10:38 +02:00
|
|
|
|
#if defined (sdiv_qrnnd)
|
2002-10-21 22:25:38 +02:00
|
|
|
|
#define L_udiv_w_sdiv
|
|
|
|
|
#endif
|
2002-10-22 01:10:38 +02:00
|
|
|
|
#endif
|
2002-10-21 22:25:38 +02:00
|
|
|
|
|
1992-07-10 00:30:59 +02:00
|
|
|
|
#ifdef L_udiv_w_sdiv
|
1995-10-19 23:48:45 +01:00
|
|
|
|
#if defined (sdiv_qrnnd)
|
2002-10-21 22:25:38 +02:00
|
|
|
|
#if (defined (L_udivdi3) || defined (L_divdi3) || \
|
|
|
|
|
defined (L_umoddi3) || defined (L_moddi3))
|
2002-10-23 12:47:24 +02:00
|
|
|
|
static inline __attribute__ ((__always_inline__))
|
2002-10-21 22:25:38 +02:00
|
|
|
|
#endif
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype
|
|
|
|
|
__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
|
1992-07-07 21:58:52 +02:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype q, r;
|
|
|
|
|
UWtype c0, c1, b1;
|
1992-07-07 21:58:52 +02:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if ((Wtype) d >= 0)
|
1992-07-07 21:58:52 +02:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
|
1992-07-07 21:58:52 +02:00
|
|
|
|
{
|
|
|
|
|
/* dividend, divisor, and quotient are nonnegative */
|
|
|
|
|
sdiv_qrnnd (q, r, a1, a0, d);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
|
1992-07-07 21:58:52 +02:00
|
|
|
|
/* Divide (c1*2^32 + c0) by d */
|
|
|
|
|
sdiv_qrnnd (q, r, c1, c0, d);
|
|
|
|
|
/* Add 2^31 to quotient */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
q += (UWtype) 1 << (W_TYPE_SIZE - 1);
|
1992-07-07 21:58:52 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
|
|
|
|
|
c1 = a1 >> 1; /* A/2 */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
|
1992-07-07 21:58:52 +02:00
|
|
|
|
|
|
|
|
|
if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
|
|
|
|
|
{
|
|
|
|
|
sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
|
|
|
|
|
|
|
|
|
|
r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
|
|
|
|
|
if ((d & 1) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (r >= q)
|
|
|
|
|
r = r - q;
|
|
|
|
|
else if (q - r <= d)
|
|
|
|
|
{
|
|
|
|
|
r = r - q + d;
|
|
|
|
|
q--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
r = r - q + 2*d;
|
|
|
|
|
q -= 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
|
|
|
|
|
{
|
|
|
|
|
c1 = (b1 - 1) - c1;
|
|
|
|
|
c0 = ~c0; /* logical NOT */
|
|
|
|
|
|
|
|
|
|
sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
|
|
|
|
|
|
|
|
|
|
q = ~q; /* (A/2)/b1 */
|
|
|
|
|
r = (b1 - 1) - r;
|
|
|
|
|
|
|
|
|
|
r = 2*r + (a0 & 1); /* A/(2*b1) */
|
|
|
|
|
|
|
|
|
|
if ((d & 1) != 0)
|
|
|
|
|
{
|
|
|
|
|
if (r >= q)
|
|
|
|
|
r = r - q;
|
|
|
|
|
else if (q - r <= d)
|
|
|
|
|
{
|
|
|
|
|
r = r - q + d;
|
|
|
|
|
q--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
r = r - q + 2*d;
|
|
|
|
|
q -= 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else /* Implies c1 = b1 */
|
|
|
|
|
{ /* Hence a1 = d - 1 = 2*b1 - 1 */
|
|
|
|
|
if (a0 >= -d)
|
|
|
|
|
{
|
|
|
|
|
q = -1;
|
|
|
|
|
r = a0 + d;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
q = -2;
|
|
|
|
|
r = a0 + 2*d;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*rp = r;
|
|
|
|
|
return q;
|
|
|
|
|
}
|
1995-10-19 23:48:45 +01:00
|
|
|
|
#else
|
|
|
|
|
/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype
|
|
|
|
|
__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
|
|
|
|
|
UWtype a1 __attribute__ ((__unused__)),
|
|
|
|
|
UWtype a0 __attribute__ ((__unused__)),
|
|
|
|
|
UWtype d __attribute__ ((__unused__)))
|
1998-03-18 08:18:06 +01:00
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1995-10-19 23:48:45 +01:00
|
|
|
|
#endif
|
1992-07-07 21:58:52 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
1995-09-01 01:26:53 +02:00
|
|
|
|
#if (defined (L_udivdi3) || defined (L_divdi3) || \
|
|
|
|
|
defined (L_umoddi3) || defined (L_moddi3))
|
|
|
|
|
#define L_udivmoddi4
|
|
|
|
|
#endif
|
|
|
|
|
|
[multiple changes]
2003-02-01 Richard Henderson <rth@redhat.com>
* optabs.c (expand_unop): Use word_mode for outmode of bit scaners.
* libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2): Change
return type to Wtype.
* libgcc-std.ver (GCC_3.4): Fix inheritance.
* config/i386/i386.md (ffssi2): Use nonimmediate_operand for
expander input constraint.
2003-02-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
* optabs.h (optab_index): Add OTI_clz, OTI_ctz, OTI_popcount and
OTI_parity.
(clz_optab, ctz_optab, popcount_optab, parity_optab): New.
* optabs.c (widen_clz, expand_parity): New.
(expand_unop): Handle clz and parity. Hardcode SImode as outmode
for libcalls to clz, ctz, popcount, and parity.
(init_optabs): Init clz_optab, ctz_optab, popcount_optab and
parity_optab, and set up libfunc handlers.
* libgcc2.c (__clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2,
__popcount_tab): New.
* libgcc2.h: Declare them.
* libgcc-std.ver (GCC_3.4): Add new functions from libgcc2.c.
* genopinit.c (optabs): Add clz_optab, ctz_optab, popcount_optab
and parity_optab.
* builtin-types.def (BT_FN_INT_LONG, BT_FN_INT_LONGLONG): New.
* builtins.def (BUILT_IN_CLZ, BUILT_IN_CTZ, BUILT_IN_POPCOUNT,
BUILT_IN_PARITY, BUILT_IN_FFSL, BUILT_IN_CLZL, BUILT_IN_CTZL,
BUILT_IN_POPCOUNTL, BUILT_IN_PARITYL, BUILT_IN_FFSLL,
BUILT_IN_CLZLL, BUILT_IN_CTZLL, BUILT_IN_POPCOUNTLL,
BUILT_IN_PARITYLL): New.
* builtins.c (expand_builtin_unop): Rename from expand_builtin_ffs
and add optab argument.
(expand_builtin): Expand BUILT_IN_{FFS,CLZ,POPCOUNT,PARITY}*.
* tree.def (CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR, PARITY_EXPR): New.
* expr.c (expand_expr): Handle them.
* fold-const.c (tree_expr_nonnegative_p): Likewise.
* rtl.def (CLZ, CTZ, POPCOUNT, PARITY): New.
* reload1.c (eliminate_regs): Handle them.
(elimination_effects): Likewise.
* function.c (instantiate_virtual_regs_1): Likewise
* genattrtab.c (check_attr_value): Likewise.
* simplify-rtx.c (simplify_unary_operation): Likewise.
* c-common.c (c_common_truthvalue_conversion): Handle POPCOUNT_EXPR.
* combine.c (combine_simplify_rtx): Handle POPCOUNT and PARITY.
(nonzero_bits): Handle CLZ, CTZ, POPCOUNT and PARITY.
* config/alpha/alpha.md (clzdi2, ctzdi2, popcountdi2): New.
* config/arm/arm.c (arm_init_builtins): Rename __builtin_clz to
__builtin_arm_clz.
* Makefile.in (LIB2FUNCS_1, LIB2FUNCS_2): Move...
* mklibgcc.in (lib2funcs): ...here and merge. Add new members.
* doc/extend.texi (Other Builtins): Add new builtins.
* doc/md.texi (Standard Names): Add new patterns.
From-SVN: r62252
2003-02-01 20:00:02 +01:00
|
|
|
|
#if (defined (L_clzsi2) || defined (L_clzdi2) || \
|
|
|
|
|
defined (L_ctzsi2) || defined (L_ctzdi2))
|
|
|
|
|
extern const UQItype __clz_tab[];
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-10-06 07:29:56 +02:00
|
|
|
|
#ifdef L_clz
|
|
|
|
|
const UQItype __clz_tab[] =
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
|
|
|
|
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
|
|
|
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
|
|
|
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
|
|
|
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
|
|
|
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
|
|
|
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
|
|
|
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
|
|
|
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
|
|
|
|
};
|
2000-10-06 07:29:56 +02:00
|
|
|
|
#endif
|
[multiple changes]
2003-02-01 Richard Henderson <rth@redhat.com>
* optabs.c (expand_unop): Use word_mode for outmode of bit scaners.
* libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2): Change
return type to Wtype.
* libgcc-std.ver (GCC_3.4): Fix inheritance.
* config/i386/i386.md (ffssi2): Use nonimmediate_operand for
expander input constraint.
2003-02-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
* optabs.h (optab_index): Add OTI_clz, OTI_ctz, OTI_popcount and
OTI_parity.
(clz_optab, ctz_optab, popcount_optab, parity_optab): New.
* optabs.c (widen_clz, expand_parity): New.
(expand_unop): Handle clz and parity. Hardcode SImode as outmode
for libcalls to clz, ctz, popcount, and parity.
(init_optabs): Init clz_optab, ctz_optab, popcount_optab and
parity_optab, and set up libfunc handlers.
* libgcc2.c (__clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
__popcountsi2, __popcountdi2, __paritysi2 __paritydi2,
__popcount_tab): New.
* libgcc2.h: Declare them.
* libgcc-std.ver (GCC_3.4): Add new functions from libgcc2.c.
* genopinit.c (optabs): Add clz_optab, ctz_optab, popcount_optab
and parity_optab.
* builtin-types.def (BT_FN_INT_LONG, BT_FN_INT_LONGLONG): New.
* builtins.def (BUILT_IN_CLZ, BUILT_IN_CTZ, BUILT_IN_POPCOUNT,
BUILT_IN_PARITY, BUILT_IN_FFSL, BUILT_IN_CLZL, BUILT_IN_CTZL,
BUILT_IN_POPCOUNTL, BUILT_IN_PARITYL, BUILT_IN_FFSLL,
BUILT_IN_CLZLL, BUILT_IN_CTZLL, BUILT_IN_POPCOUNTLL,
BUILT_IN_PARITYLL): New.
* builtins.c (expand_builtin_unop): Rename from expand_builtin_ffs
and add optab argument.
(expand_builtin): Expand BUILT_IN_{FFS,CLZ,POPCOUNT,PARITY}*.
* tree.def (CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR, PARITY_EXPR): New.
* expr.c (expand_expr): Handle them.
* fold-const.c (tree_expr_nonnegative_p): Likewise.
* rtl.def (CLZ, CTZ, POPCOUNT, PARITY): New.
* reload1.c (eliminate_regs): Handle them.
(elimination_effects): Likewise.
* function.c (instantiate_virtual_regs_1): Likewise
* genattrtab.c (check_attr_value): Likewise.
* simplify-rtx.c (simplify_unary_operation): Likewise.
* c-common.c (c_common_truthvalue_conversion): Handle POPCOUNT_EXPR.
* combine.c (combine_simplify_rtx): Handle POPCOUNT and PARITY.
(nonzero_bits): Handle CLZ, CTZ, POPCOUNT and PARITY.
* config/alpha/alpha.md (clzdi2, ctzdi2, popcountdi2): New.
* config/arm/arm.c (arm_init_builtins): Rename __builtin_clz to
__builtin_arm_clz.
* Makefile.in (LIB2FUNCS_1, LIB2FUNCS_2): Move...
* mklibgcc.in (lib2funcs): ...here and merge. Add new members.
* doc/extend.texi (Other Builtins): Add new builtins.
* doc/md.texi (Standard Names): Add new patterns.
From-SVN: r62252
2003-02-01 20:00:02 +01:00
|
|
|
|
|
|
|
|
|
#ifdef L_clzsi2
|
|
|
|
|
Wtype
|
|
|
|
|
__clzsi2 (USItype x)
|
|
|
|
|
{
|
|
|
|
|
Wtype a;
|
|
|
|
|
|
|
|
|
|
/* Note that we've already verified that BITS_PER_UNIT == 8, and
|
|
|
|
|
thus SItype is 32 bits wide. */
|
|
|
|
|
if (x < (1 << 2 * 8))
|
|
|
|
|
if (x < (1 << 1 * 8))
|
|
|
|
|
a = 0 * 8;
|
|
|
|
|
else
|
|
|
|
|
a = 1 * 8;
|
|
|
|
|
else
|
|
|
|
|
if (x < (1 << 3 * 8))
|
|
|
|
|
a = 2 * 8;
|
|
|
|
|
else
|
|
|
|
|
a = 3 * 8;
|
|
|
|
|
|
|
|
|
|
return 32 - (__clz_tab[x >> a] + a);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_clzdi2
|
|
|
|
|
Wtype
|
|
|
|
|
__clzdi2 (UDItype x)
|
|
|
|
|
{
|
|
|
|
|
Wtype a;
|
|
|
|
|
|
|
|
|
|
/* Note that we've already verified that BITS_PER_UNIT == 8, and
|
|
|
|
|
thus DItype is 64 bits wide. */
|
|
|
|
|
for (a = 64 - 8; a > 0; a -= 8)
|
|
|
|
|
if (((x >> a) & 0xff) != 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
return 64 - (__clz_tab[x >> a] + a);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_ctzsi2
|
|
|
|
|
Wtype
|
|
|
|
|
__ctzsi2 (USItype x)
|
|
|
|
|
{
|
|
|
|
|
Wtype a;
|
|
|
|
|
|
|
|
|
|
x = x & -x;
|
|
|
|
|
|
|
|
|
|
/* Note that we've already verified that BITS_PER_UNIT == 8, and
|
|
|
|
|
thus SItype is 32 bits wide. */
|
|
|
|
|
if (x < (1 << 2 * 8))
|
|
|
|
|
if (x < (1 << 1 * 8))
|
|
|
|
|
a = 0 * 8;
|
|
|
|
|
else
|
|
|
|
|
a = 1 * 8;
|
|
|
|
|
else
|
|
|
|
|
if (x < (1 << 3 * 8))
|
|
|
|
|
a = 2 * 8;
|
|
|
|
|
else
|
|
|
|
|
a = 3 * 8;
|
|
|
|
|
|
|
|
|
|
return __clz_tab[x >> a] + a - 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_ctzdi2
|
|
|
|
|
Wtype
|
|
|
|
|
__ctzdi2 (UDItype x)
|
|
|
|
|
{
|
|
|
|
|
Wtype a;
|
|
|
|
|
|
|
|
|
|
x = x & -x;
|
|
|
|
|
for (a = 64 - 8; a > 0; a -= 8)
|
|
|
|
|
if (((x >> a) & 0xff) != 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
return __clz_tab[x >> a] + a - 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if (defined (L_popcountsi2) || defined (L_popcountdi2) || \
|
|
|
|
|
defined (L_paritysi2) || defined (L_paritydi2))
|
|
|
|
|
extern const UQItype __popcount_tab[];
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_popcount_tab
|
|
|
|
|
const UQItype __popcount_tab[] =
|
|
|
|
|
{
|
|
|
|
|
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
|
|
|
|
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
|
|
|
|
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
|
|
|
|
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
|
|
|
|
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
|
|
|
|
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
|
|
|
|
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
|
|
|
|
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_popcountsi2
|
|
|
|
|
Wtype
|
|
|
|
|
__popcountsi2 (USItype x)
|
|
|
|
|
{
|
|
|
|
|
return __popcount_tab[(x >> 0) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 8) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 16) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 24) & 0xff];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_popcountdi2
|
|
|
|
|
Wtype
|
|
|
|
|
__popcountdi2 (UDItype x)
|
|
|
|
|
{
|
|
|
|
|
return __popcount_tab[(x >> 0) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 8) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 16) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 24) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 32) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 40) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 48) & 0xff]
|
|
|
|
|
+ __popcount_tab[(x >> 56) & 0xff];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_paritysi2
|
|
|
|
|
Wtype
|
|
|
|
|
__paritysi2 (USItype x)
|
|
|
|
|
{
|
|
|
|
|
x ^= x >> 16;
|
|
|
|
|
x ^= x >> 8;
|
|
|
|
|
return __popcount_tab[x & 0xff] & 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_paritydi2
|
|
|
|
|
Wtype
|
|
|
|
|
__paritydi2 (UDItype x)
|
|
|
|
|
{
|
|
|
|
|
Wtype nx = x ^ (x >> 32);
|
|
|
|
|
nx ^= nx >> 16;
|
|
|
|
|
nx ^= nx >> 8;
|
|
|
|
|
return __popcount_tab[nx & 0xff] & 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2000-10-06 07:29:56 +02:00
|
|
|
|
|
|
|
|
|
#ifdef L_udivmoddi4
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1995-09-01 01:26:53 +02:00
|
|
|
|
#if (defined (L_udivdi3) || defined (L_divdi3) || \
|
|
|
|
|
defined (L_umoddi3) || defined (L_moddi3))
|
2002-10-23 12:47:24 +02:00
|
|
|
|
static inline __attribute__ ((__always_inline__))
|
1995-09-01 01:26:53 +02:00
|
|
|
|
#endif
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype
|
|
|
|
|
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion ww;
|
|
|
|
|
DWunion nn, dd;
|
|
|
|
|
DWunion rr;
|
|
|
|
|
UWtype d0, d1, n0, n1, n2;
|
|
|
|
|
UWtype q0, q1;
|
|
|
|
|
UWtype b, bm;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
nn.ll = n;
|
|
|
|
|
dd.ll = d;
|
|
|
|
|
|
|
|
|
|
d0 = dd.s.low;
|
|
|
|
|
d1 = dd.s.high;
|
|
|
|
|
n0 = nn.s.low;
|
|
|
|
|
n1 = nn.s.high;
|
|
|
|
|
|
|
|
|
|
#if !UDIV_NEEDS_NORMALIZATION
|
|
|
|
|
if (d1 == 0)
|
|
|
|
|
{
|
|
|
|
|
if (d0 > n1)
|
|
|
|
|
{
|
|
|
|
|
/* 0q = nn / 0D */
|
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
|
|
|
|
q1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Remainder in n0. */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* qq = NN / 0d */
|
|
|
|
|
|
|
|
|
|
if (d0 == 0)
|
|
|
|
|
d0 = 1 / d0; /* Divide intentionally by zero. */
|
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q1, n1, 0, n1, d0);
|
|
|
|
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
|
|
|
|
|
|
|
|
|
/* Remainder in n0. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rp != 0)
|
|
|
|
|
{
|
|
|
|
|
rr.s.low = n0;
|
|
|
|
|
rr.s.high = 0;
|
|
|
|
|
*rp = rr.ll;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else /* UDIV_NEEDS_NORMALIZATION */
|
|
|
|
|
|
|
|
|
|
if (d1 == 0)
|
|
|
|
|
{
|
|
|
|
|
if (d0 > n1)
|
|
|
|
|
{
|
|
|
|
|
/* 0q = nn / 0D */
|
|
|
|
|
|
|
|
|
|
count_leading_zeros (bm, d0);
|
|
|
|
|
|
|
|
|
|
if (bm != 0)
|
|
|
|
|
{
|
|
|
|
|
/* Normalize, i.e. make the most significant bit of the
|
|
|
|
|
denominator set. */
|
|
|
|
|
|
|
|
|
|
d0 = d0 << bm;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
|
1992-01-28 04:44:05 +01:00
|
|
|
|
n0 = n0 << bm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
|
|
|
|
q1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Remainder in n0 >> bm. */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* qq = NN / 0d */
|
|
|
|
|
|
|
|
|
|
if (d0 == 0)
|
|
|
|
|
d0 = 1 / d0; /* Divide intentionally by zero. */
|
|
|
|
|
|
|
|
|
|
count_leading_zeros (bm, d0);
|
|
|
|
|
|
|
|
|
|
if (bm == 0)
|
|
|
|
|
{
|
|
|
|
|
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
|
|
|
|
conclude (the most significant bit of n1 is set) /\ (the
|
|
|
|
|
leading quotient digit q1 = 1).
|
|
|
|
|
|
|
|
|
|
This special case is necessary, not an optimization.
|
1999-12-27 09:34:45 +01:00
|
|
|
|
(Shifts counts of W_TYPE_SIZE are undefined.) */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
n1 -= d0;
|
|
|
|
|
q1 = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Normalize. */
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
b = W_TYPE_SIZE - bm;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
d0 = d0 << bm;
|
|
|
|
|
n2 = n1 >> b;
|
|
|
|
|
n1 = (n1 << bm) | (n0 >> b);
|
|
|
|
|
n0 = n0 << bm;
|
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q1, n1, n2, n1, d0);
|
|
|
|
|
}
|
|
|
|
|
|
1996-07-04 00:07:53 +02:00
|
|
|
|
/* n1 != d0... */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
|
|
|
|
|
|
|
|
|
/* Remainder in n0 >> bm. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rp != 0)
|
|
|
|
|
{
|
|
|
|
|
rr.s.low = n0 >> bm;
|
|
|
|
|
rr.s.high = 0;
|
|
|
|
|
*rp = rr.ll;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif /* UDIV_NEEDS_NORMALIZATION */
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (d1 > n1)
|
|
|
|
|
{
|
|
|
|
|
/* 00 = nn / DD */
|
|
|
|
|
|
|
|
|
|
q0 = 0;
|
|
|
|
|
q1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Remainder in n1n0. */
|
|
|
|
|
if (rp != 0)
|
|
|
|
|
{
|
|
|
|
|
rr.s.low = n0;
|
|
|
|
|
rr.s.high = n1;
|
|
|
|
|
*rp = rr.ll;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* 0q = NN / dd */
|
|
|
|
|
|
|
|
|
|
count_leading_zeros (bm, d1);
|
|
|
|
|
if (bm == 0)
|
|
|
|
|
{
|
|
|
|
|
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
|
|
|
|
conclude (the most significant bit of n1 is set) /\ (the
|
|
|
|
|
quotient digit q0 = 0 or 1).
|
|
|
|
|
|
|
|
|
|
This special case is necessary, not an optimization. */
|
|
|
|
|
|
|
|
|
|
/* The condition on the next line takes advantage of that
|
|
|
|
|
n1 >= d1 (true due to program flow). */
|
|
|
|
|
if (n1 > d1 || n0 >= d0)
|
|
|
|
|
{
|
|
|
|
|
q0 = 1;
|
|
|
|
|
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
q0 = 0;
|
|
|
|
|
|
|
|
|
|
q1 = 0;
|
|
|
|
|
|
|
|
|
|
if (rp != 0)
|
|
|
|
|
{
|
|
|
|
|
rr.s.low = n0;
|
|
|
|
|
rr.s.high = n1;
|
|
|
|
|
*rp = rr.ll;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype m1, m0;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
/* Normalize. */
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
b = W_TYPE_SIZE - bm;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
d1 = (d1 << bm) | (d0 >> b);
|
|
|
|
|
d0 = d0 << bm;
|
|
|
|
|
n2 = n1 >> b;
|
|
|
|
|
n1 = (n1 << bm) | (n0 >> b);
|
|
|
|
|
n0 = n0 << bm;
|
|
|
|
|
|
|
|
|
|
udiv_qrnnd (q0, n1, n2, n1, d1);
|
|
|
|
|
umul_ppmm (m1, m0, q0, d0);
|
|
|
|
|
|
|
|
|
|
if (m1 > n1 || (m1 == n1 && m0 > n0))
|
|
|
|
|
{
|
|
|
|
|
q0--;
|
|
|
|
|
sub_ddmmss (m1, m0, m1, m0, d1, d0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
q1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Remainder in (n1n0 - m1m0) >> bm. */
|
|
|
|
|
if (rp != 0)
|
|
|
|
|
{
|
|
|
|
|
sub_ddmmss (n1, n0, n1, n0, m1, m0);
|
|
|
|
|
rr.s.low = (n1 << b) | (n0 >> bm);
|
|
|
|
|
rr.s.high = n1 >> bm;
|
|
|
|
|
*rp = rr.ll;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ww.s.low = q0;
|
|
|
|
|
ww.s.high = q1;
|
|
|
|
|
return ww.ll;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_divdi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__divdi3 (DWtype u, DWtype v)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1995-01-12 17:13:44 +01:00
|
|
|
|
word_type c = 0;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion uu, vv;
|
|
|
|
|
DWtype w;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
vv.ll = v;
|
|
|
|
|
|
|
|
|
|
if (uu.s.high < 0)
|
|
|
|
|
c = ~c,
|
2002-07-22 02:15:49 +02:00
|
|
|
|
uu.ll = -uu.ll;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (vv.s.high < 0)
|
|
|
|
|
c = ~c,
|
2002-07-22 02:15:49 +02:00
|
|
|
|
vv.ll = -vv.ll;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (c)
|
2002-07-22 02:15:49 +02:00
|
|
|
|
w = -w;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_moddi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
|
|
|
|
__moddi3 (DWtype u, DWtype v)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1995-01-12 17:13:44 +01:00
|
|
|
|
word_type c = 0;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion uu, vv;
|
|
|
|
|
DWtype w;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
uu.ll = u;
|
|
|
|
|
vv.ll = v;
|
|
|
|
|
|
|
|
|
|
if (uu.s.high < 0)
|
|
|
|
|
c = ~c,
|
2002-07-22 02:15:49 +02:00
|
|
|
|
uu.ll = -uu.ll;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (vv.s.high < 0)
|
2002-07-22 02:15:49 +02:00
|
|
|
|
vv.ll = -vv.ll;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
(void) __udivmoddi4 (uu.ll, vv.ll, &w);
|
|
|
|
|
if (c)
|
2002-07-22 02:15:49 +02:00
|
|
|
|
w = -w;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_umoddi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype
|
|
|
|
|
__umoddi3 (UDWtype u, UDWtype v)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype w;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
(void) __udivmoddi4 (u, v, &w);
|
|
|
|
|
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_udivdi3
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype
|
|
|
|
|
__udivdi3 (UDWtype n, UDWtype d)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
return __udivmoddi4 (n, d, (UDWtype *) 0);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_cmpdi2
|
1993-01-20 02:07:04 +01:00
|
|
|
|
word_type
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__cmpdi2 (DWtype a, DWtype b)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion au, bu;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
au.ll = a, bu.ll = b;
|
|
|
|
|
|
|
|
|
|
if (au.s.high < bu.s.high)
|
|
|
|
|
return 0;
|
|
|
|
|
else if (au.s.high > bu.s.high)
|
|
|
|
|
return 2;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if ((UWtype) au.s.low < (UWtype) bu.s.low)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 0;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
else if ((UWtype) au.s.low > (UWtype) bu.s.low)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 2;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_ucmpdi2
|
1993-01-20 02:07:04 +01:00
|
|
|
|
word_type
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__ucmpdi2 (DWtype a, DWtype b)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWunion au, bu;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
au.ll = a, bu.ll = b;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if ((UWtype) au.s.high < (UWtype) bu.s.high)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 0;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
else if ((UWtype) au.s.high > (UWtype) bu.s.high)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 2;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if ((UWtype) au.s.low < (UWtype) bu.s.low)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 0;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
else if ((UWtype) au.s.low > (UWtype) bu.s.low)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
return 2;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunstfDI (TFtype a)
|
1992-07-07 21:46:10 +02:00
|
|
|
|
{
|
|
|
|
|
TFtype b;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype v;
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
|
|
|
|
if (a < 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Compute high word of result, as a flonum. */
|
|
|
|
|
b = (a / HIGH_WORD_COEFF);
|
1999-12-27 09:34:45 +01:00
|
|
|
|
/* Convert that to fixed (but not to DWtype!),
|
1992-07-07 21:46:10 +02:00
|
|
|
|
and shift it into the high word. */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v = (UWtype) b;
|
1992-07-07 21:46:10 +02:00
|
|
|
|
v <<= WORD_SIZE;
|
|
|
|
|
/* Remove high part from the TFtype, leaving the low part as flonum. */
|
|
|
|
|
a -= (TFtype)v;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
/* Convert that to fixed (but not to DWtype!) and add it in.
|
1992-07-07 21:46:10 +02:00
|
|
|
|
Sometimes A comes out negative. This is significant, since
|
|
|
|
|
A has more bits than a long int does. */
|
|
|
|
|
if (a < 0)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v -= (UWtype) (- a);
|
1992-07-07 21:46:10 +02:00
|
|
|
|
else
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v += (UWtype) a;
|
1992-07-07 21:46:10 +02:00
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
(__negdi2, __lshrdi3, __ashldi3, __ashrdi3, __ffsdi2):
Use ANSI style definition with full prototype.
(__muldi3, __udiv_w_sdiv, __udivmoddi4, __divdi3, __moddi3) : Likewise.
(__udivmoddi4, __udivdi3, __cmpdi2, __ucmpdi2) : Likewise.
(__fixunstfdi, __fixtfdi, __fixunsxfdi, __fixxfdi) : Likewise.
(__fixunsdfdi, __fixdfdi, __floatdixf, __floatditf) : Likewise.
(__floatdidf, __floatdisf, __fixunsxfsi, __fixunsdfsi) : Likewise.
(__gcc_bcmp, __eprintf, gopen, gclose, __bb_init_file) : Likewise.
(__bb_init_trace_func, __clear_cache, mprotect) : Likewise.
(__enable_execute_stack, cacheflush, exit) : Likewise.
(find_exception_table, __find_first_exception_table_match) : Likewise.
From-SVN: r13658
1997-02-16 13:55:15 +01:00
|
|
|
|
__fixtfdi (TFtype a)
|
1992-07-07 21:46:10 +02:00
|
|
|
|
{
|
|
|
|
|
if (a < 0)
|
2000-04-15 18:34:38 +02:00
|
|
|
|
return - __fixunstfDI (-a);
|
|
|
|
|
return __fixunstfDI (a);
|
1992-07-07 21:46:10 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunsxfDI (XFtype a)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
{
|
|
|
|
|
XFtype b;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UDWtype v;
|
1993-04-04 09:18:03 +02:00
|
|
|
|
|
|
|
|
|
if (a < 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Compute high word of result, as a flonum. */
|
|
|
|
|
b = (a / HIGH_WORD_COEFF);
|
1999-12-27 09:34:45 +01:00
|
|
|
|
/* Convert that to fixed (but not to DWtype!),
|
1993-04-04 09:18:03 +02:00
|
|
|
|
and shift it into the high word. */
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v = (UWtype) b;
|
1993-04-04 09:18:03 +02:00
|
|
|
|
v <<= WORD_SIZE;
|
|
|
|
|
/* Remove high part from the XFtype, leaving the low part as flonum. */
|
|
|
|
|
a -= (XFtype)v;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
/* Convert that to fixed (but not to DWtype!) and add it in.
|
1993-04-04 09:18:03 +02:00
|
|
|
|
Sometimes A comes out negative. This is significant, since
|
|
|
|
|
A has more bits than a long int does. */
|
|
|
|
|
if (a < 0)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v -= (UWtype) (- a);
|
1993-04-04 09:18:03 +02:00
|
|
|
|
else
|
1999-12-27 09:34:45 +01:00
|
|
|
|
v += (UWtype) a;
|
1993-04-04 09:18:03 +02:00
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
(__negdi2, __lshrdi3, __ashldi3, __ashrdi3, __ffsdi2):
Use ANSI style definition with full prototype.
(__muldi3, __udiv_w_sdiv, __udivmoddi4, __divdi3, __moddi3) : Likewise.
(__udivmoddi4, __udivdi3, __cmpdi2, __ucmpdi2) : Likewise.
(__fixunstfdi, __fixtfdi, __fixunsxfdi, __fixxfdi) : Likewise.
(__fixunsdfdi, __fixdfdi, __floatdixf, __floatditf) : Likewise.
(__floatdidf, __floatdisf, __fixunsxfsi, __fixunsdfsi) : Likewise.
(__gcc_bcmp, __eprintf, gopen, gclose, __bb_init_file) : Likewise.
(__bb_init_trace_func, __clear_cache, mprotect) : Likewise.
(__enable_execute_stack, cacheflush, exit) : Likewise.
(find_exception_table, __find_first_exception_table_match) : Likewise.
From-SVN: r13658
1997-02-16 13:55:15 +01:00
|
|
|
|
__fixxfdi (XFtype a)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
{
|
|
|
|
|
if (a < 0)
|
2000-04-15 18:34:38 +02:00
|
|
|
|
return - __fixunsxfDI (-a);
|
|
|
|
|
return __fixunsxfDI (a);
|
1993-04-04 09:18:03 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L_fixunsdfdi
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunsdfDI (DFtype a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
2002-12-16 19:23:00 +01:00
|
|
|
|
UWtype hi, lo;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2002-12-16 19:23:00 +01:00
|
|
|
|
/* Get high part of result. The division here will just moves the radix
|
|
|
|
|
point and will not cause any rounding. Then the conversion to integral
|
|
|
|
|
type chops result as desired. */
|
|
|
|
|
hi = a / HIGH_WORD_COEFF;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2002-12-16 19:23:00 +01:00
|
|
|
|
/* Get low part of result. Convert `hi' to floating type and scale it back,
|
|
|
|
|
then subtract this from the number being converted. This leaves the low
|
|
|
|
|
part. Convert that to integral type. */
|
|
|
|
|
lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
|
|
|
|
|
|
|
|
|
|
/* Assemble result from the two parts. */
|
|
|
|
|
return ((UDWtype) hi << WORD_SIZE) | lo;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_fixdfdi
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
(__negdi2, __lshrdi3, __ashldi3, __ashrdi3, __ffsdi2):
Use ANSI style definition with full prototype.
(__muldi3, __udiv_w_sdiv, __udivmoddi4, __divdi3, __moddi3) : Likewise.
(__udivmoddi4, __udivdi3, __cmpdi2, __ucmpdi2) : Likewise.
(__fixunstfdi, __fixtfdi, __fixunsxfdi, __fixxfdi) : Likewise.
(__fixunsdfdi, __fixdfdi, __floatdixf, __floatditf) : Likewise.
(__floatdidf, __floatdisf, __fixunsxfsi, __fixunsdfsi) : Likewise.
(__gcc_bcmp, __eprintf, gopen, gclose, __bb_init_file) : Likewise.
(__bb_init_trace_func, __clear_cache, mprotect) : Likewise.
(__enable_execute_stack, cacheflush, exit) : Likewise.
(find_exception_table, __find_first_exception_table_match) : Likewise.
From-SVN: r13658
1997-02-16 13:55:15 +01:00
|
|
|
|
__fixdfdi (DFtype a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
|
|
|
|
if (a < 0)
|
2000-04-15 18:34:38 +02:00
|
|
|
|
return - __fixunsdfDI (-a);
|
|
|
|
|
return __fixunsdfDI (a);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_fixunssfdi
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunssfDI (SFtype original_a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1992-07-07 21:46:10 +02:00
|
|
|
|
/* Convert the SFtype to a DFtype, because that is surely not going
|
1992-01-28 04:44:05 +01:00
|
|
|
|
to lose any bits. Some day someone else can write a faster version
|
1992-07-07 21:46:10 +02:00
|
|
|
|
that avoids converting to DFtype, and verify it really works right. */
|
|
|
|
|
DFtype a = original_a;
|
2002-12-16 19:23:00 +01:00
|
|
|
|
UWtype hi, lo;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2002-12-16 19:23:00 +01:00
|
|
|
|
/* Get high part of result. The division here will just moves the radix
|
|
|
|
|
point and will not cause any rounding. Then the conversion to integral
|
|
|
|
|
type chops result as desired. */
|
|
|
|
|
hi = a / HIGH_WORD_COEFF;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2002-12-16 19:23:00 +01:00
|
|
|
|
/* Get low part of result. Convert `hi' to floating type and scale it back,
|
|
|
|
|
then subtract this from the number being converted. This leaves the low
|
|
|
|
|
part. Convert that to integral type. */
|
|
|
|
|
lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
|
|
|
|
|
|
|
|
|
|
/* Assemble result from the two parts. */
|
|
|
|
|
return ((UDWtype) hi << WORD_SIZE) | lo;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_fixsfdi
|
1999-12-27 09:34:45 +01:00
|
|
|
|
DWtype
|
1992-07-07 21:46:10 +02:00
|
|
|
|
__fixsfdi (SFtype a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
|
|
|
|
if (a < 0)
|
2000-04-15 18:34:38 +02:00
|
|
|
|
return - __fixunssfDI (-a);
|
|
|
|
|
return __fixunssfDI (a);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
|
|
|
|
|
XFtype
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__floatdixf (DWtype u)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
{
|
|
|
|
|
XFtype d;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d = (Wtype) (u >> WORD_SIZE);
|
1993-04-04 09:18:03 +02:00
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
1993-04-04 09:18:03 +02:00
|
|
|
|
|
1998-04-04 15:32:39 +02:00
|
|
|
|
return d;
|
1993-04-04 09:18:03 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
|
|
|
|
TFtype
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__floatditf (DWtype u)
|
1992-07-07 21:46:10 +02:00
|
|
|
|
{
|
|
|
|
|
TFtype d;
|
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d = (Wtype) (u >> WORD_SIZE);
|
1992-07-07 21:46:10 +02:00
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
1998-04-04 15:32:39 +02:00
|
|
|
|
return d;
|
1992-07-07 21:46:10 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L_floatdidf
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1992-07-07 21:46:10 +02:00
|
|
|
|
DFtype
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__floatdidf (DWtype u)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1992-07-07 21:46:10 +02:00
|
|
|
|
DFtype d;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d = (Wtype) (u >> WORD_SIZE);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
|
|
|
|
d *= HIGH_HALFWORD_COEFF;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1998-04-04 15:32:39 +02:00
|
|
|
|
return d;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_floatdisf
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
|
|
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
|
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
2001-07-16 11:16:04 +02:00
|
|
|
|
|
2002-03-25 21:52:28 +01:00
|
|
|
|
#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
|
real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE.
* real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE.
Always make REAL_VALUE_TYPE a struct containing an array of
HOST_WIDE_INT, not a double. Tidy up the code deciding how
big it is. Don't declare or use union real_extract.
* emit-rtl.c (init_emit_once), varasm.c (immed_real_const_1,
decode_rtx_const, output_constant_pool), config/a29k/a29k.c
(print_operand), config/arm/arm.c (output_move_double),
config/arm/arm.md (consttable_4, consttable_8),
config/romp/romp.c (output_fpops), config/s390/s390.h
(ASM_OUTPUT_SPECIAL_POOL_ENTRY), config/xtensa/xtensa.c
(xtensa_output_literal): Don't use union real_extract.
* config/dsp16xx/dsp16xx.c (print_operand), config/i860/i860.c
(sfmode_constant_to_ulong), config/ns32k/merlin.h
(PRINT_OPERAND), config/ns32k/ns32k.c (print_operand),
config/pdp11/pdp11.h (PRINT_OPERAND), config/we32k/we32k.h
(PRINT_OPERAND): Don't use local version of union
real_extract.
* config/convex/convex.c (check_float_value), config/vax/vax.c
(vax_float_literal), config/m88k/m88k.md (divdf3),
config/dsp16xx/dsp16xx.md (fixuns_trunchfhi2),
config/pdp11/pdp11.c (output_move_quad): Don't do host
arithmetic on target floating point quantities.
* config/a29k/a29k.md, config/dsp16xx/dsp16xx.c
(output_dsp16xx_float_const): Don't test HOST_FLOAT_FORMAT.
* fold-const.c (fold), simplify-rtx.c (simplify_binary_real):
Use MODE_HAS_INFINITIES rather than #ifdef REAL_INFINITY.
* real.c (earith): Test INFINITY rather than REAL_INFINITY;
NANS implies INFINITY, so can drop #ifdef NANS inside #ifndef
INFINITY.
* print-rtl.c (print_rtx): Disable code which needs
floating-point emulator.
* libgcc2.c: Include float.h and use DBL_MANT_DIG,
FLT_MANT_DIG, to define DF_SIZE and SF_SIZE, rather than
depending on HOST_FLOAT_FORMAT to be defined properly.
* ch/grant.c, cp/error.c: Always use REAL_VALUE_TO_DECIMAL;
don't test REAL_IS_NOT_DOUBLE.
* config/1750a/1750a.c (get_double, float_label): Delete.
(print_operand): Delete huge commented-out chunk. Use
REAL_VALUE_TO_DECIMAL.
* config/1750a/1750a-protos.h: Delete prototypes of deleted
functions.
* config/convex/convex.h: Always set TARGET_FLOAT_FORMAT to
IEEE_FLOAT_FORMAT.
* config/i370/i370.h (PRINT_OPERAND [TARGET_HLASM version]):
Use REAL_VALUE_TO_DECIMAL as ELF version does.
* config/m88k/m88k.c (real_power_of_2_operand,
legitimize_operand): Take the REAL_VALUE_TYPE and/or union
real_extract out of the union; run the input through
REAL_VALUE_TO_TARGET_DOUBLE, then plug the pair of longwords
from that into the union.
* config/pdp11/pdp11.c (output_move_double): Rearrange
parentheses to make automatic indenter happy.
* doc/tm.texi (Cross-compilation): Rename node to "Floating
Point" and rewrite to describe current situation. Also adjust
documentation of REAL_VALUE_TO_TARGET_SINGLE and friends to
match code.
* doc/rtl.texi: Adjust cross reference.
From-SVN: r51210
2002-03-23 02:10:56 +01:00
|
|
|
|
#define DF_SIZE DBL_MANT_DIG
|
|
|
|
|
#define SF_SIZE FLT_MANT_DIG
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1992-07-07 21:46:10 +02:00
|
|
|
|
SFtype
|
1999-12-27 09:34:45 +01:00
|
|
|
|
__floatdisf (DWtype u)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1993-05-11 06:42:22 +02:00
|
|
|
|
/* Do the calculation in DFmode
|
|
|
|
|
so that we don't lose any of the precision of the high word
|
|
|
|
|
while multiplying it. */
|
|
|
|
|
DFtype f;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1994-06-03 00:10:30 +02:00
|
|
|
|
/* Protect against double-rounding error.
|
|
|
|
|
Represent any low-order bits, that might be truncated in DFmode,
|
|
|
|
|
by a bit that won't be lost. The bit can go in anywhere below the
|
|
|
|
|
rounding position of the SFmode. A fixed mask and bit position
|
|
|
|
|
handles all usual configurations. It doesn't handle the case
|
|
|
|
|
of 128-bit DImode, however. */
|
|
|
|
|
if (DF_SIZE < DI_SIZE
|
|
|
|
|
&& DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
|
|
|
|
|
{
|
2000-04-15 18:34:38 +02:00
|
|
|
|
#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
|
1999-12-27 09:34:45 +01:00
|
|
|
|
if (! (- ((DWtype) 1 << DF_SIZE) < u
|
|
|
|
|
&& u < ((DWtype) 1 << DF_SIZE)))
|
1994-06-03 00:10:30 +02:00
|
|
|
|
{
|
2000-04-15 18:34:38 +02:00
|
|
|
|
if ((UDWtype) u & (REP_BIT - 1))
|
2002-10-09 01:50:56 +02:00
|
|
|
|
{
|
|
|
|
|
u &= ~ (REP_BIT - 1);
|
|
|
|
|
u |= REP_BIT;
|
|
|
|
|
}
|
1994-06-03 00:10:30 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-27 09:34:45 +01:00
|
|
|
|
f = (Wtype) (u >> WORD_SIZE);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
f *= HIGH_HALFWORD_COEFF;
|
|
|
|
|
f *= HIGH_HALFWORD_COEFF;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1998-04-04 15:32:39 +02:00
|
|
|
|
return (SFtype) f;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-01-19 13:03:01 +01:00
|
|
|
|
#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
|
1995-02-12 00:26:09 +01:00
|
|
|
|
/* Reenable the normal types, in case limits.h needs them. */
|
|
|
|
|
#undef char
|
|
|
|
|
#undef short
|
|
|
|
|
#undef int
|
|
|
|
|
#undef long
|
|
|
|
|
#undef unsigned
|
|
|
|
|
#undef float
|
|
|
|
|
#undef double
|
1995-10-22 13:01:32 +01:00
|
|
|
|
#undef MIN
|
|
|
|
|
#undef MAX
|
1995-01-31 19:28:04 +01:00
|
|
|
|
#include <limits.h>
|
1993-04-04 09:18:03 +02:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunsxfSI (XFtype a)
|
1993-04-04 09:18:03 +02:00
|
|
|
|
{
|
2001-01-31 04:53:32 +01:00
|
|
|
|
if (a >= - (DFtype) Wtype_MIN)
|
|
|
|
|
return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
return (Wtype) a;
|
1993-04-04 09:18:03 +02:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L_fixunsdfsi
|
1995-02-12 00:26:09 +01:00
|
|
|
|
/* Reenable the normal types, in case limits.h needs them. */
|
|
|
|
|
#undef char
|
|
|
|
|
#undef short
|
|
|
|
|
#undef int
|
|
|
|
|
#undef long
|
|
|
|
|
#undef unsigned
|
|
|
|
|
#undef float
|
|
|
|
|
#undef double
|
1995-10-22 13:01:32 +01:00
|
|
|
|
#undef MIN
|
|
|
|
|
#undef MAX
|
1995-01-31 19:28:04 +01:00
|
|
|
|
#include <limits.h>
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunsdfSI (DFtype a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
2001-01-31 04:53:32 +01:00
|
|
|
|
if (a >= - (DFtype) Wtype_MIN)
|
|
|
|
|
return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
return (Wtype) a;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef L_fixunssfsi
|
1995-02-12 00:26:09 +01:00
|
|
|
|
/* Reenable the normal types, in case limits.h needs them. */
|
|
|
|
|
#undef char
|
|
|
|
|
#undef short
|
|
|
|
|
#undef int
|
|
|
|
|
#undef long
|
|
|
|
|
#undef unsigned
|
|
|
|
|
#undef float
|
|
|
|
|
#undef double
|
1995-10-22 13:01:32 +01:00
|
|
|
|
#undef MIN
|
|
|
|
|
#undef MAX
|
1995-01-31 19:28:04 +01:00
|
|
|
|
#include <limits.h>
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1999-12-27 09:34:45 +01:00
|
|
|
|
UWtype
|
2000-04-15 18:34:38 +02:00
|
|
|
|
__fixunssfSI (SFtype a)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
2001-01-31 04:53:32 +01:00
|
|
|
|
if (a >= - (SFtype) Wtype_MIN)
|
|
|
|
|
return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
|
1999-12-27 09:34:45 +01:00
|
|
|
|
return (Wtype) a;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-07-07 21:46:10 +02:00
|
|
|
|
/* From here on down, the routines use normal data types. */
|
|
|
|
|
|
|
|
|
|
#define SItype bogus_type
|
|
|
|
|
#define USItype bogus_type
|
|
|
|
|
#define DItype bogus_type
|
|
|
|
|
#define UDItype bogus_type
|
|
|
|
|
#define SFtype bogus_type
|
|
|
|
|
#define DFtype bogus_type
|
1999-12-27 09:34:45 +01:00
|
|
|
|
#undef Wtype
|
|
|
|
|
#undef UWtype
|
|
|
|
|
#undef HWtype
|
|
|
|
|
#undef UHWtype
|
|
|
|
|
#undef DWtype
|
|
|
|
|
#undef UDWtype
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
|
|
|
|
#undef char
|
|
|
|
|
#undef short
|
|
|
|
|
#undef int
|
|
|
|
|
#undef long
|
|
|
|
|
#undef unsigned
|
|
|
|
|
#undef float
|
|
|
|
|
#undef double
|
1992-09-12 10:45:46 +02:00
|
|
|
|
|
|
|
|
|
#ifdef L__gcc_bcmp
|
|
|
|
|
|
|
|
|
|
/* Like bcmp except the sign is meaningful.
|
1995-05-16 14:39:54 +02:00
|
|
|
|
Result is negative if S1 is less than S2,
|
1992-09-12 10:45:46 +02:00
|
|
|
|
positive if S1 is greater, 0 if S1 and S2 are equal. */
|
|
|
|
|
|
|
|
|
|
int
|
2000-03-09 04:39:09 +01:00
|
|
|
|
__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
|
1992-09-12 10:45:46 +02:00
|
|
|
|
{
|
|
|
|
|
while (size > 0)
|
|
|
|
|
{
|
1992-10-15 06:04:48 +01:00
|
|
|
|
unsigned char c1 = *s1++, c2 = *s2++;
|
1992-09-12 10:45:46 +02:00
|
|
|
|
if (c1 != c2)
|
|
|
|
|
return c1 - c2;
|
|
|
|
|
size--;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1992-07-07 21:46:10 +02:00
|
|
|
|
|
2001-05-14 04:46:22 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* __eprintf used to be used by GCC's private version of <assert.h>.
|
|
|
|
|
We no longer provide that header, but this routine remains in libgcc.a
|
|
|
|
|
for binary backward compatibility. Note that it is not included in
|
|
|
|
|
the shared version of libgcc. */
|
|
|
|
|
#ifdef L_eprintf
|
|
|
|
|
#ifndef inhibit_libc
|
|
|
|
|
|
|
|
|
|
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
__eprintf (const char *string, const char *expression,
|
|
|
|
|
unsigned int line, const char *filename)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, string, expression, line, filename);
|
|
|
|
|
fflush (stderr);
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef L_clear_cache
|
|
|
|
|
/* Clear part of an instruction cache. */
|
|
|
|
|
|
|
|
|
|
#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
|
|
|
|
|
|
|
|
|
|
void
|
1999-10-05 21:48:55 +02:00
|
|
|
|
__clear_cache (char *beg __attribute__((__unused__)),
|
|
|
|
|
char *end __attribute__((__unused__)))
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
2001-07-16 11:16:04 +02:00
|
|
|
|
#ifdef CLEAR_INSN_CACHE
|
1993-09-22 19:43:00 +02:00
|
|
|
|
CLEAR_INSN_CACHE (beg, end);
|
|
|
|
|
#else
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef INSN_CACHE_SIZE
|
|
|
|
|
static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
|
1995-03-31 01:51:30 +02:00
|
|
|
|
static int initialized;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
int offset;
|
1992-05-05 03:46:51 +02:00
|
|
|
|
void *start_addr
|
|
|
|
|
void *end_addr;
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
typedef (*function_ptr) (void);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
|
|
|
|
|
/* It's cheaper to clear the whole cache.
|
|
|
|
|
Put in a series of jump instructions so that calling the beginning
|
|
|
|
|
of the cache will clear the whole thing. */
|
|
|
|
|
|
|
|
|
|
if (! initialized)
|
|
|
|
|
{
|
|
|
|
|
int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
|
|
|
|
|
& -INSN_CACHE_LINE_WIDTH);
|
|
|
|
|
int end_ptr = ptr + INSN_CACHE_SIZE;
|
|
|
|
|
|
|
|
|
|
while (ptr < end_ptr)
|
|
|
|
|
{
|
|
|
|
|
*(INSTRUCTION_TYPE *)ptr
|
|
|
|
|
= JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
|
|
|
|
|
ptr += INSN_CACHE_LINE_WIDTH;
|
|
|
|
|
}
|
1996-07-04 00:07:53 +02:00
|
|
|
|
*(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
initialized = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Call the beginning of the sequence. */
|
|
|
|
|
(((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
|
|
|
|
|
& -INSN_CACHE_LINE_WIDTH))
|
|
|
|
|
());
|
|
|
|
|
|
|
|
|
|
#else /* Cache is large. */
|
|
|
|
|
|
|
|
|
|
if (! initialized)
|
|
|
|
|
{
|
|
|
|
|
int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
|
|
|
|
|
& -INSN_CACHE_LINE_WIDTH);
|
|
|
|
|
|
|
|
|
|
while (ptr < (int) array + sizeof array)
|
|
|
|
|
{
|
|
|
|
|
*(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
|
|
|
|
|
ptr += INSN_CACHE_LINE_WIDTH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initialized = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find the location in array that occupies the same cache line as BEG. */
|
|
|
|
|
|
|
|
|
|
offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
|
|
|
|
|
start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
|
|
|
|
|
& -INSN_CACHE_PLANE_SIZE)
|
|
|
|
|
+ offset);
|
|
|
|
|
|
|
|
|
|
/* Compute the cache alignment of the place to stop clearing. */
|
|
|
|
|
#if 0 /* This is not needed for gcc's purposes. */
|
|
|
|
|
/* If the block to clear is bigger than a cache plane,
|
2001-07-16 11:16:04 +02:00
|
|
|
|
we clear the entire cache, and OFFSET is already correct. */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (end < beg + INSN_CACHE_PLANE_SIZE)
|
|
|
|
|
#endif
|
|
|
|
|
offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
|
|
|
|
|
& -INSN_CACHE_LINE_WIDTH)
|
|
|
|
|
& (INSN_CACHE_PLANE_SIZE - 1));
|
|
|
|
|
|
|
|
|
|
#if INSN_CACHE_DEPTH > 1
|
|
|
|
|
end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
|
|
|
|
|
if (end_addr <= start_addr)
|
|
|
|
|
end_addr += INSN_CACHE_PLANE_SIZE;
|
|
|
|
|
|
|
|
|
|
for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
|
|
|
|
|
{
|
|
|
|
|
int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
|
|
|
|
|
int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
|
|
|
|
|
|
|
|
|
|
while (addr != stop)
|
|
|
|
|
{
|
|
|
|
|
/* Call the return instruction at ADDR. */
|
|
|
|
|
((function_ptr) addr) ();
|
|
|
|
|
|
|
|
|
|
addr += INSN_CACHE_LINE_WIDTH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else /* just one plane */
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
/* Call the return instruction at START_ADDR. */
|
|
|
|
|
((function_ptr) start_addr) ();
|
|
|
|
|
|
|
|
|
|
start_addr += INSN_CACHE_LINE_WIDTH;
|
|
|
|
|
}
|
|
|
|
|
while ((start_addr % INSN_CACHE_SIZE) != offset);
|
|
|
|
|
#endif /* just one plane */
|
|
|
|
|
#endif /* Cache is large */
|
|
|
|
|
#endif /* Cache exists */
|
1993-09-22 19:43:00 +02:00
|
|
|
|
#endif /* CLEAR_INSN_CACHE */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* L_clear_cache */
|
|
|
|
|
|
|
|
|
|
#ifdef L_trampoline
|
|
|
|
|
|
|
|
|
|
/* Jump to a trampoline, loading the static chain address. */
|
|
|
|
|
|
1999-03-11 01:58:01 +01:00
|
|
|
|
#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
|
1997-08-01 01:39:26 +02:00
|
|
|
|
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
long
|
|
|
|
|
getpagesize (void)
|
1995-11-26 20:41:43 +01:00
|
|
|
|
{
|
|
|
|
|
#ifdef _ALPHA_
|
|
|
|
|
return 8192;
|
|
|
|
|
#else
|
|
|
|
|
return 4096;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
1999-11-23 07:09:34 +01:00
|
|
|
|
#ifdef __i386__
|
1997-07-02 12:38:04 +02:00
|
|
|
|
extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
|
|
|
|
|
#endif
|
|
|
|
|
|
1997-08-03 00:27:33 +02:00
|
|
|
|
int
|
|
|
|
|
mprotect (char *addr, int len, int prot)
|
1995-11-26 20:41:43 +01:00
|
|
|
|
{
|
|
|
|
|
int np, op;
|
|
|
|
|
|
1997-08-03 00:27:33 +02:00
|
|
|
|
if (prot == 7)
|
|
|
|
|
np = 0x40;
|
|
|
|
|
else if (prot == 5)
|
|
|
|
|
np = 0x20;
|
|
|
|
|
else if (prot == 4)
|
|
|
|
|
np = 0x10;
|
|
|
|
|
else if (prot == 3)
|
|
|
|
|
np = 0x04;
|
|
|
|
|
else if (prot == 1)
|
|
|
|
|
np = 0x02;
|
|
|
|
|
else if (prot == 0)
|
|
|
|
|
np = 0x01;
|
1995-11-26 20:41:43 +01:00
|
|
|
|
|
|
|
|
|
if (VirtualProtect (addr, len, np, &op))
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-11 01:58:01 +01:00
|
|
|
|
#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
|
1995-11-26 20:41:43 +01:00
|
|
|
|
|
2001-07-16 11:16:04 +02:00
|
|
|
|
#ifdef TRANSFER_FROM_TRAMPOLINE
|
|
|
|
|
TRANSFER_FROM_TRAMPOLINE
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
1998-01-14 21:57:58 +01:00
|
|
|
|
#ifdef __sysV68__
|
|
|
|
|
|
|
|
|
|
#include <sys/signal.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
/* Motorola forgot to put memctl.o in the libp version of libc881.a,
|
|
|
|
|
so define it here, because we need it in __clear_insn_cache below */
|
1998-01-26 23:54:52 +01:00
|
|
|
|
/* On older versions of this OS, no memctl or MCT_TEXT are defined;
|
|
|
|
|
hence we enable this stuff only if MCT_TEXT is #define'd. */
|
1998-01-14 21:57:58 +01:00
|
|
|
|
|
1998-01-26 23:54:52 +01:00
|
|
|
|
#ifdef MCT_TEXT
|
1998-01-14 21:57:58 +01:00
|
|
|
|
asm("\n\
|
|
|
|
|
global memctl\n\
|
|
|
|
|
memctl:\n\
|
|
|
|
|
movq &75,%d0\n\
|
|
|
|
|
trap &0\n\
|
|
|
|
|
bcc.b noerror\n\
|
|
|
|
|
jmp cerror%\n\
|
|
|
|
|
noerror:\n\
|
|
|
|
|
movq &0,%d0\n\
|
|
|
|
|
rts");
|
1998-01-26 23:54:52 +01:00
|
|
|
|
#endif
|
1998-01-14 21:57:58 +01:00
|
|
|
|
|
|
|
|
|
/* Clear instruction cache so we can call trampolines on stack.
|
|
|
|
|
This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
|
|
|
|
|
|
|
|
|
|
void
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
__clear_insn_cache (void)
|
1998-01-14 21:57:58 +01:00
|
|
|
|
{
|
1998-01-26 23:54:52 +01:00
|
|
|
|
#ifdef MCT_TEXT
|
1998-01-14 21:57:58 +01:00
|
|
|
|
int save_errno;
|
|
|
|
|
|
|
|
|
|
/* Preserve errno, because users would be surprised to have
|
2001-08-13 01:40:53 +02:00
|
|
|
|
errno changing without explicitly calling any system-call. */
|
1998-01-14 21:57:58 +01:00
|
|
|
|
save_errno = errno;
|
|
|
|
|
|
2001-07-16 11:16:04 +02:00
|
|
|
|
/* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
|
2001-08-13 01:40:53 +02:00
|
|
|
|
No need to use an address derived from _start or %sp, as 0 works also. */
|
1998-01-14 21:57:58 +01:00
|
|
|
|
memctl(0, 4096, MCT_TEXT);
|
|
|
|
|
errno = save_errno;
|
1998-01-26 23:54:52 +01:00
|
|
|
|
#endif
|
1998-01-14 21:57:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* __sysV68__ */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#endif /* L_trampoline */
|
|
|
|
|
|
1998-11-12 20:37:47 +01:00
|
|
|
|
#ifndef __CYGWIN__
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef L__main
|
|
|
|
|
|
|
|
|
|
#include "gbl-ctors.h"
|
1993-07-26 23:00:16 +02:00
|
|
|
|
/* Some systems use __main in a way incompatible with its use in gcc, in these
|
|
|
|
|
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
|
|
|
|
|
give the same symbol without quotes for an alternative entry point. You
|
1996-07-04 00:07:53 +02:00
|
|
|
|
must define both, or neither. */
|
1993-07-26 23:00:16 +02:00
|
|
|
|
#ifndef NAME__MAIN
|
|
|
|
|
#define NAME__MAIN "__main"
|
|
|
|
|
#define SYMBOL__MAIN __main
|
|
|
|
|
#endif
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1996-10-16 22:25:25 +02:00
|
|
|
|
#ifdef INIT_SECTION_ASM_OP
|
|
|
|
|
#undef HAS_INIT_SECTION
|
|
|
|
|
#define HAS_INIT_SECTION
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
|
1999-09-09 23:36:20 +02:00
|
|
|
|
|
|
|
|
|
/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
|
|
|
|
|
code to run constructors. In that case, we need to handle EH here, too. */
|
|
|
|
|
|
2001-08-14 16:06:10 +02:00
|
|
|
|
#ifdef EH_FRAME_SECTION_NAME
|
2001-03-29 23:11:23 +02:00
|
|
|
|
#include "unwind-dw2-fde.h"
|
1999-09-09 23:36:20 +02:00
|
|
|
|
extern unsigned char __EH_FRAME_BEGIN__[];
|
|
|
|
|
#endif
|
|
|
|
|
|
1992-01-28 04:44:05 +01:00
|
|
|
|
/* Run all the global destructors on exit from the program. */
|
|
|
|
|
|
|
|
|
|
void
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
__do_global_dtors (void)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1992-02-12 18:47:31 +01:00
|
|
|
|
#ifdef DO_GLOBAL_DTORS_BODY
|
|
|
|
|
DO_GLOBAL_DTORS_BODY;
|
|
|
|
|
#else
|
1996-10-24 03:23:43 +02:00
|
|
|
|
static func_ptr *p = __DTOR_LIST__ + 1;
|
|
|
|
|
while (*p)
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
(*(p-1)) ();
|
|
|
|
|
}
|
1992-02-12 18:47:31 +01:00
|
|
|
|
#endif
|
2001-08-14 16:06:10 +02:00
|
|
|
|
#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
|
1999-10-14 15:38:01 +02:00
|
|
|
|
{
|
|
|
|
|
static int completed = 0;
|
|
|
|
|
if (! completed)
|
|
|
|
|
{
|
|
|
|
|
completed = 1;
|
|
|
|
|
__deregister_frame_info (__EH_FRAME_BEGIN__);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-09 23:36:20 +02:00
|
|
|
|
#endif
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
1994-11-19 05:09:58 +01:00
|
|
|
|
#endif
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1996-10-16 22:25:25 +02:00
|
|
|
|
#ifndef HAS_INIT_SECTION
|
1992-01-28 04:44:05 +01:00
|
|
|
|
/* Run all the global constructors on entry to the program. */
|
|
|
|
|
|
|
|
|
|
void
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
__do_global_ctors (void)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
2001-08-14 16:06:10 +02:00
|
|
|
|
#ifdef EH_FRAME_SECTION_NAME
|
1999-09-09 23:36:20 +02:00
|
|
|
|
{
|
|
|
|
|
static struct object object;
|
|
|
|
|
__register_frame_info (__EH_FRAME_BEGIN__, &object);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
1992-01-28 04:44:05 +01:00
|
|
|
|
DO_GLOBAL_CTORS_BODY;
|
1999-09-17 00:51:47 +02:00
|
|
|
|
atexit (__do_global_dtors);
|
1992-01-28 04:44:05 +01:00
|
|
|
|
}
|
1996-10-16 22:25:25 +02:00
|
|
|
|
#endif /* no HAS_INIT_SECTION */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1996-10-16 22:25:25 +02:00
|
|
|
|
#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
/* Subroutine called automatically by `main'.
|
|
|
|
|
Compiling a global function named `main'
|
|
|
|
|
produces an automatic call to this function at the beginning.
|
|
|
|
|
|
|
|
|
|
For many systems, this routine calls __do_global_ctors.
|
|
|
|
|
For systems which support a .init section we use the .init section
|
|
|
|
|
to run __do_global_ctors, so we need not do anything here. */
|
|
|
|
|
|
|
|
|
|
void
|
1993-07-26 23:00:16 +02:00
|
|
|
|
SYMBOL__MAIN ()
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
|
|
|
|
/* Support recursive calls to `main': run initializers just once. */
|
1995-03-31 01:51:30 +02:00
|
|
|
|
static int initialized;
|
1992-01-28 04:44:05 +01:00
|
|
|
|
if (! initialized)
|
|
|
|
|
{
|
|
|
|
|
initialized = 1;
|
|
|
|
|
__do_global_ctors ();
|
|
|
|
|
}
|
|
|
|
|
}
|
1996-10-16 22:25:25 +02:00
|
|
|
|
#endif /* no HAS_INIT_SECTION or INVOKE__main */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
#endif /* L__main */
|
1998-11-12 20:37:47 +01:00
|
|
|
|
#endif /* __CYGWIN__ */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1992-09-19 06:47:11 +02:00
|
|
|
|
#ifdef L_ctors
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
#include "gbl-ctors.h"
|
|
|
|
|
|
|
|
|
|
/* Provide default definitions for the lists of constructors and
|
1999-06-11 05:12:22 +02:00
|
|
|
|
destructors, so that we don't get linker errors. These symbols are
|
|
|
|
|
intentionally bss symbols, so that gld and/or collect will provide
|
|
|
|
|
the right values. */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
/* We declare the lists here with two elements each,
|
1999-06-11 05:12:22 +02:00
|
|
|
|
so that they are valid empty lists if no other definition is loaded.
|
|
|
|
|
|
|
|
|
|
If we are using the old "set" extensions to have the gnu linker
|
|
|
|
|
collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
|
|
|
|
|
must be in the bss/common section.
|
|
|
|
|
|
|
|
|
|
Long term no port should use those extensions. But many still do. */
|
1992-03-19 21:41:45 +01:00
|
|
|
|
#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
|
2001-11-19 12:28:52 +01:00
|
|
|
|
#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
|
1992-10-15 09:25:16 +01:00
|
|
|
|
func_ptr __CTOR_LIST__[2] = {0, 0};
|
|
|
|
|
func_ptr __DTOR_LIST__[2] = {0, 0};
|
1999-06-11 05:12:22 +02:00
|
|
|
|
#else
|
|
|
|
|
func_ptr __CTOR_LIST__[2];
|
|
|
|
|
func_ptr __DTOR_LIST__[2];
|
|
|
|
|
#endif
|
1992-03-19 21:41:45 +01:00
|
|
|
|
#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
|
1992-09-19 06:47:11 +02:00
|
|
|
|
#endif /* L_ctors */
|
|
|
|
|
|
|
|
|
|
#ifdef L_exit
|
|
|
|
|
|
|
|
|
|
#include "gbl-ctors.h"
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1996-03-05 00:46:29 +01:00
|
|
|
|
#ifdef NEED_ATEXIT
|
|
|
|
|
|
1999-09-17 20:37:48 +02:00
|
|
|
|
#ifndef ON_EXIT
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
1996-03-05 00:46:29 +01:00
|
|
|
|
# include <errno.h>
|
|
|
|
|
|
1997-04-13 20:12:05 +02:00
|
|
|
|
static func_ptr *atexit_chain = 0;
|
1996-03-05 00:46:29 +01:00
|
|
|
|
static long atexit_chain_length = 0;
|
|
|
|
|
static volatile long last_atexit_chain_slot = -1;
|
|
|
|
|
|
1999-09-15 23:41:16 +02:00
|
|
|
|
int
|
|
|
|
|
atexit (func_ptr func)
|
1996-03-05 00:46:29 +01:00
|
|
|
|
{
|
|
|
|
|
if (++last_atexit_chain_slot == atexit_chain_length)
|
|
|
|
|
{
|
|
|
|
|
atexit_chain_length += 32;
|
|
|
|
|
if (atexit_chain)
|
1997-05-18 13:26:38 +02:00
|
|
|
|
atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
|
|
|
|
|
* sizeof (func_ptr));
|
1996-03-05 00:46:29 +01:00
|
|
|
|
else
|
1997-05-18 13:26:38 +02:00
|
|
|
|
atexit_chain = (func_ptr *) malloc (atexit_chain_length
|
|
|
|
|
* sizeof (func_ptr));
|
1996-03-05 00:46:29 +01:00
|
|
|
|
if (! atexit_chain)
|
|
|
|
|
{
|
|
|
|
|
atexit_chain_length = 0;
|
|
|
|
|
last_atexit_chain_slot = -1;
|
|
|
|
|
errno = ENOMEM;
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
atexit_chain[last_atexit_chain_slot] = func;
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
gthr-single.h (__gthread_active_p): Add prototype arguments.
* gthr-single.h (__gthread_active_p): Add prototype arguments.
* libgcc2.c (__udivmoddi4): Remove unnecessary decls.
(__dummy, __builtin_saveregs, __bb_exit_trace_func, __bb_init_prg,
__bb_trace_func, __bb_trace_func_ret, __bb_trace_ret,
function_ptr, getpagesize, __enable_execute_stack,
__enable_execute_stack, __clear_insn_cache,
__enable_execute_stack, __do_global_dtors, __do_global_ctors,
_cleanup, _exit, __default_terminate, __terminate_func,
__terminate, __empty, __throw, new_eh_context,
eh_context_initialize, eh_context_static, eh_context_specific,
get_eh_context, __get_eh_context, __get_eh_info,
init_reg_size_table, eh_threads_initialize,
__get_dynamic_handler_chain, __sjthrow, __sjpopnthrow,
__unwinding_cleanup, throw_helper, __throw, __rethrow,
__pure_virtual): Add prototype arguments.
(__bb_exit_func): Cast a sizeof to long when comparing against one.
Cast a signed value to unsigned long when comparing against one.
(new_eh_context): Wrap in _GTHREADS macro.
(__sjthrow, __sjpopnthrow): Initialize variable `cleanup' at
declaration.
(in_reg_window): Mark parameters with __attribute__ ((__unused__)).
(throw_helper): Initialize variables `handler_p' and `pc_p'.
From-SVN: r30872
1999-12-12 16:34:09 +01:00
|
|
|
|
extern void _cleanup (void);
|
|
|
|
|
extern void _exit (int) __attribute__ ((__noreturn__));
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
2001-07-16 11:16:04 +02:00
|
|
|
|
void
|
(__negdi2, __lshrdi3, __ashldi3, __ashrdi3, __ffsdi2):
Use ANSI style definition with full prototype.
(__muldi3, __udiv_w_sdiv, __udivmoddi4, __divdi3, __moddi3) : Likewise.
(__udivmoddi4, __udivdi3, __cmpdi2, __ucmpdi2) : Likewise.
(__fixunstfdi, __fixtfdi, __fixunsxfdi, __fixxfdi) : Likewise.
(__fixunsdfdi, __fixdfdi, __floatdixf, __floatditf) : Likewise.
(__floatdidf, __floatdisf, __fixunsxfsi, __fixunsdfsi) : Likewise.
(__gcc_bcmp, __eprintf, gopen, gclose, __bb_init_file) : Likewise.
(__bb_init_trace_func, __clear_cache, mprotect) : Likewise.
(__enable_execute_stack, cacheflush, exit) : Likewise.
(find_exception_table, __find_first_exception_table_match) : Likewise.
From-SVN: r13658
1997-02-16 13:55:15 +01:00
|
|
|
|
exit (int status)
|
1992-01-28 04:44:05 +01:00
|
|
|
|
{
|
1996-03-05 00:46:29 +01:00
|
|
|
|
if (atexit_chain)
|
|
|
|
|
{
|
|
|
|
|
for ( ; last_atexit_chain_slot-- >= 0; )
|
|
|
|
|
{
|
|
|
|
|
(*atexit_chain[last_atexit_chain_slot + 1]) ();
|
1997-04-13 20:12:05 +02:00
|
|
|
|
atexit_chain[last_atexit_chain_slot + 1] = 0;
|
1996-03-05 00:46:29 +01:00
|
|
|
|
}
|
|
|
|
|
free (atexit_chain);
|
1997-04-13 20:12:05 +02:00
|
|
|
|
atexit_chain = 0;
|
1996-03-05 00:46:29 +01:00
|
|
|
|
}
|
1992-01-28 04:44:05 +01:00
|
|
|
|
#ifdef EXIT_BODY
|
|
|
|
|
EXIT_BODY;
|
|
|
|
|
#else
|
|
|
|
|
_cleanup ();
|
|
|
|
|
#endif
|
|
|
|
|
_exit (status);
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-17 20:37:48 +02:00
|
|
|
|
#else /* ON_EXIT */
|
1998-07-07 01:52:21 +02:00
|
|
|
|
|
1999-09-15 23:41:16 +02:00
|
|
|
|
/* Simple; we just need a wrapper for ON_EXIT. */
|
|
|
|
|
int
|
|
|
|
|
atexit (func_ptr func)
|
1998-07-07 01:52:21 +02:00
|
|
|
|
{
|
1999-09-15 23:41:16 +02:00
|
|
|
|
return ON_EXIT (func);
|
1998-07-07 01:52:21 +02:00
|
|
|
|
}
|
1999-09-15 23:41:16 +02:00
|
|
|
|
|
1999-09-17 20:37:48 +02:00
|
|
|
|
#endif /* ON_EXIT */
|
1999-09-15 23:41:16 +02:00
|
|
|
|
#endif /* NEED_ATEXIT */
|
1992-01-28 04:44:05 +01:00
|
|
|
|
|
|
|
|
|
#endif /* L_exit */
|