libgfortran (liblfortran) with MCST patches
This commit is contained in:
parent
791447f986
commit
ba4cc64fdf
|
@ -3,71 +3,36 @@
|
|||
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
|
||||
## May be used by toolexeclibdir.
|
||||
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
|
||||
|
||||
## Symbol versioning (copied from libssp).
|
||||
if LIBGFOR_USE_SYMVER
|
||||
if LIBGFOR_USE_SYMVER_GNU
|
||||
version_arg = -Wl,--version-script=$(srcdir)/gfortran.map
|
||||
version_dep = $(srcdir)/gfortran.map
|
||||
endif
|
||||
if LIBGFOR_USE_SYMVER_SUN
|
||||
version_arg = -Wl,-M,gfortran.map-sun
|
||||
version_dep = gfortran.map-sun
|
||||
gfortran.map-sun : $(srcdir)/gfortran.map \
|
||||
$(top_srcdir)/../contrib/make_sunver.pl \
|
||||
$(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD)
|
||||
perl $(top_srcdir)/../contrib/make_sunver.pl \
|
||||
$(srcdir)/gfortran.map \
|
||||
$(libgfortran_la_OBJECTS:%.lo=.libs/%.o) \
|
||||
`echo $(libgfortran_la_LIBADD) | \
|
||||
sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
|
||||
> $@ || (rm -f $@ ; exit 1)
|
||||
endif
|
||||
else
|
||||
version_arg =
|
||||
version_dep =
|
||||
endif
|
||||
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
|
||||
$(lt_host_flags)
|
||||
|
||||
toolexeclib_LTLIBRARIES = libgfortran.la
|
||||
toolexeclib_DATA = libgfortran.spec
|
||||
libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS)
|
||||
libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
|
||||
$(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \
|
||||
$(HWCAP_LDFLAGS) \
|
||||
-lm $(extra_ldflags_libgfortran) \
|
||||
$(version_arg) -Wc,-shared-libgcc
|
||||
libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
|
||||
toolexeclib_LTLIBRARIES = liblfortran.la
|
||||
toolexeclib_DATA = liblfortran.spec
|
||||
libglortran_la_LINK = $(LINK) $(liblfortran_la_LDFLAGS)
|
||||
liblfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
|
||||
$(LTLDFLAGS) $(LIBQUADLIB) \
|
||||
$(HWCAP_LDFLAGS) -lm
|
||||
liblfortran_la_DEPENDENCIES = $(version_dep) liblfortran.spec $(LIBQUADLIB_DEP)
|
||||
|
||||
cafexeclib_LTLIBRARIES = libcaf_single.la
|
||||
cafexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
|
||||
cafexeclibdir = $(libdir)
|
||||
libcaf_single_la_SOURCES = caf/single.c
|
||||
libcaf_single_la_LDFLAGS = -static
|
||||
libcaf_single_la_DEPENDENCIES = caf/libcaf.h
|
||||
libcaf_single_la_LINK = $(LINK) $(libcaf_single_la_LDFLAGS)
|
||||
|
||||
if IEEE_SUPPORT
|
||||
fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/finclude
|
||||
nodist_finclude_HEADERS = ieee_arithmetic.mod ieee_exceptions.mod ieee_features.mod
|
||||
fincludedir = $(includedir)
|
||||
nodist_finclude_HEADERS = ieee_arithmetic.mod ieee_exceptions.mod ieee_features.mod $(srcdir)/omp_lib.h $(srcdir)/omp_lib.mod $(srcdir)/omp_lib_kinds.mod
|
||||
endif
|
||||
|
||||
## io.h conflicts with a system header on some platforms, so
|
||||
## use -iquote
|
||||
AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../gcc/config $(LIBQUADINCLUDE) \
|
||||
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../libgcc \
|
||||
-I$(MULTIBUILDTOP)../libgcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../libbacktrace \
|
||||
-I$(MULTIBUILDTOP)../libbacktrace \
|
||||
-I../libbacktrace
|
||||
|
||||
# Fortran rules for complex multiplication and division
|
||||
AM_CFLAGS += -fcx-fortran-rules
|
||||
AM_CPPFLAGS =
|
||||
|
||||
# Use -ffunction-sections -fdata-sections if supported by the compiler
|
||||
AM_CFLAGS += $(SECTION_FLAGS)
|
||||
|
@ -139,8 +104,6 @@ intrinsics/unpack_generic.c \
|
|||
runtime/in_pack_generic.c \
|
||||
runtime/in_unpack_generic.c
|
||||
|
||||
if !LIBGFOR_MINIMAL
|
||||
|
||||
gfor_helper_src+= \
|
||||
intrinsics/access.c \
|
||||
intrinsics/c99_functions.c \
|
||||
|
@ -172,11 +135,9 @@ intrinsics/symlnk.c \
|
|||
intrinsics/system_clock.c \
|
||||
intrinsics/time.c \
|
||||
intrinsics/umask.c \
|
||||
intrinsics/unlink.c
|
||||
|
||||
endif
|
||||
|
||||
if IEEE_SUPPORT
|
||||
intrinsics/unlink.c \
|
||||
generated/index.c \
|
||||
generated/dprod.c
|
||||
|
||||
gfor_helper_src+=ieee/ieee_helper.c
|
||||
|
||||
|
@ -185,12 +146,6 @@ ieee/ieee_arithmetic.F90 \
|
|||
ieee/ieee_exceptions.F90 \
|
||||
ieee/ieee_features.F90
|
||||
|
||||
else
|
||||
|
||||
gfor_ieee_src=
|
||||
|
||||
endif
|
||||
|
||||
gfor_src= \
|
||||
runtime/bounds.c \
|
||||
runtime/compile_options.c \
|
||||
|
@ -642,8 +597,8 @@ gfor_built_src= $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \
|
|||
$(i_matmul_c) $(i_matmull_c) $(i_shape_c) $(i_eoshift1_c) \
|
||||
$(i_eoshift3_c) $(i_cshift1_c) $(i_reshape_c) $(in_pack_c) $(in_unpack_c) \
|
||||
$(i_pow_c) $(i_pack_c) $(i_unpack_c) \
|
||||
$(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \
|
||||
$(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc
|
||||
$(i_spread_c) selected_real_kind.inc \
|
||||
$(i_cshift0_c) c99_protos.inc fpu-target.inc
|
||||
|
||||
# Machine generated specifics
|
||||
gfor_built_specific_src= \
|
||||
|
@ -792,21 +747,19 @@ gfor_specific_src= \
|
|||
$(gfor_built_specific_src) \
|
||||
$(gfor_built_specific2_src) \
|
||||
$(gfor_misc_specifics) \
|
||||
intrinsics/dprod_r8.f90 \
|
||||
intrinsics/f2c_specifics.F90
|
||||
intrinsics/dprod_r8.f90
|
||||
|
||||
# Turn on vectorization and loop unrolling for matmul.
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmul_c))): AM_CFLAGS += -ffast-math -ftree-vectorize -funroll-loops --param max-unroll-times=4
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmul_c))): AM_CFLAGS += -ffast-math -fno-associative-math -funroll-loops --param max-unroll-times=4
|
||||
# Logical matmul doesn't vectorize.
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmull_c))): AM_CFLAGS += -funroll-loops
|
||||
|
||||
# Add the -fallow-leading-underscore option when needed
|
||||
$(patsubst %.F90,%.lo,$(patsubst %.f90,%.lo,$(notdir $(gfor_specific_src)))): AM_FCFLAGS += -fallow-leading-underscore
|
||||
selected_real_kind.lo selected_int_kind.lo: AM_FCFLAGS += -fallow-leading-underscore
|
||||
$(patsubst %.F90,%.lo,$(patsubst %.f90,%.lo,$(notdir $(gfor_specific_src)))):
|
||||
selected_real_kind.lo selected_int_kind.lo:
|
||||
|
||||
if IEEE_SUPPORT
|
||||
# Add flags for IEEE modules
|
||||
$(patsubst %.F90,%.lo,$(notdir $(gfor_ieee_src))): AM_FCFLAGS += -Wno-unused-dummy-argument -Wno-c-binding-type -ffree-line-length-0 -fallow-leading-underscore
|
||||
$(patsubst %.F90,%.lo,$(notdir $(gfor_ieee_src))): AM_FCFLAGS += -ffree-line-length-0
|
||||
endif
|
||||
|
||||
# Dependencies between IEEE_ARITHMETIC and IEEE_EXCEPTIONS
|
||||
|
@ -828,32 +781,32 @@ prereq_SRC = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \
|
|||
|
||||
if onestep
|
||||
# dummy sources for libtool
|
||||
BUILT_SOURCES+=libgfortran_c.c libgfortran_f.f90
|
||||
libgfortran_c.c libgfortran_f.f90 libgfortran_F.F90:
|
||||
BUILT_SOURCES+=liblfortran_c.c liblfortran_f.f90
|
||||
liblfortran_c.c liblfortran_f.f90 liblfortran_F.F90:
|
||||
echo > $@
|
||||
# overrides for libtool perusing the dummy sources
|
||||
libgfortran_c.o: $(filter %.c,$(prereq_SRC))
|
||||
liblfortran_c.o: $(filter %.c,$(prereq_SRC))
|
||||
$(COMPILE) -c $^ -o $@ -combine
|
||||
|
||||
libgfortran_c.lo: $(filter %.c,$(prereq_SRC))
|
||||
liblfortran_c.lo: $(filter %.c,$(prereq_SRC))
|
||||
$(LTCOMPILE) -c -o $@ $^ -combine
|
||||
|
||||
#libgfortran_f.o: $(filter %.f %.f90,$(prereq_SRC))
|
||||
#liblfortran_f.o: $(filter %.f %.f90,$(prereq_SRC))
|
||||
# $(FCCOMPILE) -c $^ -o $@ -combine
|
||||
|
||||
#libgfortran_f.lo: $(filter %.f %.f90,$(prereq_SRC))
|
||||
#liblfortran_f.lo: $(filter %.f %.f90,$(prereq_SRC))
|
||||
# $(LTFCCOMPILE) -c -o $@ $^ -combine
|
||||
# not currently used:
|
||||
#libgfortran_F.o: $(filter %.F %.F90,$(prereq_SRC))
|
||||
#liblfortran_F.o: $(filter %.F %.F90,$(prereq_SRC))
|
||||
# $(PPFCCOMPILE) -c $^ -o $@ -combine
|
||||
#
|
||||
#libgfortran_F.lo:
|
||||
#liblfortran_F.lo:
|
||||
# $(LTPPFCCOMPILE) -c -o $@ $^ -combine
|
||||
|
||||
libgfortran_la_SOURCES = libgfortran_c.c $(filter-out %.c,$(prereq_SRC))
|
||||
liblfortran_la_SOURCES = liblfortran_c.c $(filter-out %.c,$(prereq_SRC))
|
||||
|
||||
else
|
||||
libgfortran_la_SOURCES = $(prereq_SRC)
|
||||
liblfortran_la_SOURCES = $(prereq_SRC)
|
||||
|
||||
endif
|
||||
|
||||
|
@ -862,27 +815,23 @@ I_M4_DEPS0=$(I_M4_DEPS) m4/iforeach.m4
|
|||
I_M4_DEPS1=$(I_M4_DEPS) m4/ifunction.m4
|
||||
I_M4_DEPS2=$(I_M4_DEPS) m4/ifunction_logical.m4
|
||||
|
||||
kinds.h: $(srcdir)/mk-kinds-h.sh
|
||||
$(SHELL) $(srcdir)/mk-kinds-h.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
# kinds.h: $(srcdir)/mk-kinds-h.sh
|
||||
# $(SHELL) $(srcdir)/mk-kinds-h.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
|
||||
kinds.inc: kinds.h
|
||||
grep '^#' < kinds.h > $@
|
||||
# kinds.inc: kinds.h
|
||||
# grep '^#' < kinds.h > $@
|
||||
|
||||
c99_protos.inc: $(srcdir)/c99_protos.h
|
||||
grep '^#' < $(srcdir)/c99_protos.h > $@
|
||||
|
||||
selected_int_kind.inc: $(srcdir)/mk-sik-inc.sh
|
||||
$(SHELL) $(srcdir)/mk-sik-inc.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
|
||||
selected_real_kind.inc: $(srcdir)/mk-srk-inc.sh
|
||||
$(SHELL) $(srcdir)/mk-srk-inc.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
|
||||
fpu-target.h: $(srcdir)/$(FPU_HOST_HEADER)
|
||||
cp $(srcdir)/$(FPU_HOST_HEADER) $@
|
||||
|
||||
fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h
|
||||
grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true
|
||||
grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true
|
||||
fpu-target.inc: fpu-target.h
|
||||
grep '^#define GFC_FPE_' < $(srcdir)/commonLibFortran.h > $@ || true
|
||||
|
||||
## A 'normal' build shouldn't need to regenerate these
|
||||
## so we only include them in maintainer mode
|
||||
|
|
|
@ -72,42 +72,8 @@ target_triplet = @target@
|
|||
@LIBGFOR_MINIMAL_FALSE@io/write.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@io/fbuf.c
|
||||
|
||||
@LIBGFOR_MINIMAL_FALSE@am__append_3 = \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/access.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/c99_functions.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/chdir.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/chmod.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/clock.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/cpu_time.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/ctime.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/date_and_time.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/dtime.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/env.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/etime.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/execute_command_line.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/exit.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/gerror.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/getcwd.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/getlog.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/getXid.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/hostnm.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/kill.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/link.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/perror.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/signal.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/sleep.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/system.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/rename.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/stat.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/symlnk.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/system_clock.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/time.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/umask.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@intrinsics/unlink.c
|
||||
|
||||
@IEEE_SUPPORT_TRUE@am__append_4 = ieee/ieee_helper.c
|
||||
@LIBGFOR_MINIMAL_TRUE@am__append_5 = runtime/minimal.c
|
||||
@LIBGFOR_MINIMAL_FALSE@am__append_6 = \
|
||||
@LIBGFOR_MINIMAL_TRUE@am__append_3 = runtime/minimal.c
|
||||
@LIBGFOR_MINIMAL_FALSE@am__append_4 = \
|
||||
@LIBGFOR_MINIMAL_FALSE@runtime/backtrace.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@runtime/convert_char.c \
|
||||
@LIBGFOR_MINIMAL_FALSE@runtime/environ.c \
|
||||
|
@ -119,18 +85,15 @@ target_triplet = @target@
|
|||
|
||||
|
||||
# dummy sources for libtool
|
||||
@onestep_TRUE@am__append_7 = libgfortran_c.c libgfortran_f.f90
|
||||
@onestep_TRUE@am__append_5 = liblfortran_c.c liblfortran_f.f90
|
||||
subdir = .
|
||||
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(top_srcdir)/configure $(am__configure_deps) \
|
||||
$(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
|
||||
$(srcdir)/libgfortran.spec.in $(srcdir)/../depcomp
|
||||
$(srcdir)/liblfortran.spec.in $(srcdir)/../depcomp
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
|
||||
$(top_srcdir)/../config/hwcaps.m4 \
|
||||
$(top_srcdir)/../config/lead-dot.m4 \
|
||||
$(top_srcdir)/../config/lthostflags.m4 \
|
||||
$(top_srcdir)/../config/multi.m4 \
|
||||
$(top_srcdir)/../config/override.m4 \
|
||||
$(top_srcdir)/../config/stdint.m4 \
|
||||
$(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
|
||||
|
@ -146,7 +109,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
|||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES = libgfortran.spec
|
||||
CONFIG_CLEAN_FILES = liblfortran.spec
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
|
@ -182,7 +145,7 @@ LTLIBRARIES = $(cafexeclib_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
|
|||
libcaf_single_la_LIBADD =
|
||||
am_libcaf_single_la_OBJECTS = single.lo
|
||||
libcaf_single_la_OBJECTS = $(am_libcaf_single_la_OBJECTS)
|
||||
libgfortran_la_LIBADD =
|
||||
liblfortran_la_LIBADD =
|
||||
@LIBGFOR_MINIMAL_TRUE@am__objects_1 = minimal.lo
|
||||
@LIBGFOR_MINIMAL_FALSE@am__objects_2 = backtrace.lo convert_char.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ environ.lo error.lo fpu.lo main.lo \
|
||||
|
@ -314,29 +277,24 @@ am__objects_35 = $(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
|||
@LIBGFOR_MINIMAL_FALSE@ transfer128.lo unit.lo unix.lo write.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ fbuf.lo
|
||||
am__objects_37 = size_from_kind.lo $(am__objects_36)
|
||||
@LIBGFOR_MINIMAL_FALSE@am__objects_38 = access.lo c99_functions.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ chdir.lo chmod.lo clock.lo cpu_time.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ ctime.lo date_and_time.lo dtime.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ env.lo etime.lo execute_command_line.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ exit.lo gerror.lo getcwd.lo getlog.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ getXid.lo hostnm.lo kill.lo link.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ perror.lo signal.lo sleep.lo system.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ rename.lo stat.lo symlnk.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ system_clock.lo time.lo umask.lo \
|
||||
@LIBGFOR_MINIMAL_FALSE@ unlink.lo
|
||||
@IEEE_SUPPORT_TRUE@am__objects_39 = ieee_helper.lo
|
||||
am__objects_40 = associated.lo abort.lo args.lo cshift0.lo eoshift0.lo \
|
||||
am__objects_38 = associated.lo abort.lo args.lo cshift0.lo \
|
||||
copy_psp.lo eoshift0.lo \
|
||||
eoshift2.lo erfc_scaled.lo extends_type_of.lo fnum.lo \
|
||||
ierrno.lo ishftc.lo mvbits.lo move_alloc.lo pack_generic.lo \
|
||||
selected_char_kind.lo size.lo spread_generic.lo \
|
||||
string_intrinsics.lo rand.lo random.lo reshape_generic.lo \
|
||||
reshape_packed.lo selected_int_kind.lo selected_real_kind.lo \
|
||||
unpack_generic.lo in_pack_generic.lo in_unpack_generic.lo \
|
||||
$(am__objects_38) $(am__objects_39)
|
||||
@IEEE_SUPPORT_TRUE@am__objects_41 = ieee_arithmetic.lo \
|
||||
@IEEE_SUPPORT_TRUE@ ieee_exceptions.lo ieee_features.lo
|
||||
am__objects_42 =
|
||||
am__objects_43 = _abs_c4.lo _abs_c8.lo _abs_c10.lo _abs_c16.lo \
|
||||
access.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
|
||||
cpu_time.lo ctime.lo date_and_time.lo dtime.lo env.lo etime.lo \
|
||||
execute_command_line.lo exit.lo gerror.lo getcwd.lo getlog.lo \
|
||||
getXid.lo hostnm.lo kill.lo link.lo perror.lo signal.lo \
|
||||
sleep.lo system.lo rename.lo stat.lo symlnk.lo system_clock.lo \
|
||||
time.lo umask.lo unlink.lo index.lo dprod.lo ieee_helper.lo
|
||||
am__objects_39 = ieee_arithmetic.lo ieee_exceptions.lo \
|
||||
ieee_features.lo
|
||||
am__objects_40 =
|
||||
am__objects_41 = _abs_c4.lo _abs_c8.lo _abs_c10.lo _abs_c16.lo \
|
||||
_abs_i4.lo _abs_i8.lo _abs_i16.lo _abs_r4.lo _abs_r8.lo \
|
||||
_abs_r10.lo _abs_r16.lo _aimag_c4.lo _aimag_c8.lo \
|
||||
_aimag_c10.lo _aimag_c16.lo _exp_r4.lo _exp_r8.lo _exp_r10.lo \
|
||||
|
@ -360,21 +318,24 @@ am__objects_43 = _abs_c4.lo _abs_c8.lo _abs_c10.lo _abs_c16.lo \
|
|||
_conjg_c4.lo _conjg_c8.lo _conjg_c10.lo _conjg_c16.lo \
|
||||
_aint_r4.lo _aint_r8.lo _aint_r10.lo _aint_r16.lo _anint_r4.lo \
|
||||
_anint_r8.lo _anint_r10.lo _anint_r16.lo
|
||||
am__objects_44 = _sign_i4.lo _sign_i8.lo _sign_i16.lo _sign_r4.lo \
|
||||
am__objects_42 = _sign_i4.lo _sign_i8.lo _sign_i16.lo _sign_r4.lo \
|
||||
_sign_r8.lo _sign_r10.lo _sign_r16.lo _dim_i4.lo _dim_i8.lo \
|
||||
_dim_i16.lo _dim_r4.lo _dim_r8.lo _dim_r10.lo _dim_r16.lo \
|
||||
_atan2_r4.lo _atan2_r8.lo _atan2_r10.lo _atan2_r16.lo \
|
||||
_mod_i4.lo _mod_i8.lo _mod_i16.lo _mod_r4.lo _mod_r8.lo \
|
||||
_mod_r10.lo _mod_r16.lo
|
||||
am__objects_45 = misc_specifics.lo
|
||||
am__objects_46 = $(am__objects_43) $(am__objects_44) $(am__objects_45) \
|
||||
dprod_r8.lo f2c_specifics.lo
|
||||
am__objects_47 = $(am__objects_3) $(am__objects_35) $(am__objects_37) \
|
||||
$(am__objects_40) $(am__objects_41) $(am__objects_42) \
|
||||
$(am__objects_46)
|
||||
@onestep_FALSE@am_libgfortran_la_OBJECTS = $(am__objects_47)
|
||||
@onestep_TRUE@am_libgfortran_la_OBJECTS = libgfortran_c.lo
|
||||
libgfortran_la_OBJECTS = $(am_libgfortran_la_OBJECTS)
|
||||
am__objects_43 = misc_specifics.lo
|
||||
am__objects_44 = $(am__objects_41) $(am__objects_42) $(am__objects_43) \
|
||||
dprod_r8.lo
|
||||
am__objects_45 = $(am__objects_3) $(am__objects_35) $(am__objects_37) \
|
||||
$(am__objects_38) $(am__objects_39) $(am__objects_40) \
|
||||
$(am__objects_44)
|
||||
@onestep_FALSE@am_liblfortran_la_OBJECTS = $(am__objects_45)
|
||||
@onestep_TRUE@am_liblfortran_la_OBJECTS = liblfortran_c.lo
|
||||
liblfortran_la_OBJECTS = $(am_liblfortran_la_OBJECTS)
|
||||
liblfortran_la_LINK = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(FCLD) $(AM_FCFLAGS) $(FCFLAGS) \
|
||||
$(liblfortran_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
|
@ -400,13 +361,7 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
|||
FCCOMPILE = $(FC) $(AM_FCFLAGS) $(FCFLAGS)
|
||||
LTFCCOMPILE = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(FC) $(AM_FCFLAGS) $(FCFLAGS)
|
||||
SOURCES = $(libcaf_single_la_SOURCES) $(libgfortran_la_SOURCES)
|
||||
MULTISRCTOP =
|
||||
MULTIBUILDTOP =
|
||||
MULTIDIRS =
|
||||
MULTISUBDIR =
|
||||
MULTIDO = true
|
||||
MULTICLEAN = true
|
||||
SOURCES = $(libcaf_single_la_SOURCES) $(liblfortran_la_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
|
@ -419,13 +374,10 @@ CTAGS = ctags
|
|||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
|
||||
# Fortran rules for complex multiplication and division
|
||||
|
||||
# Use -ffunction-sections -fdata-sections if supported by the compiler
|
||||
|
||||
# Some targets require additional compiler options for IEEE compatibility.
|
||||
AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) \
|
||||
$(IEEE_FLAGS) $(am__append_1)
|
||||
AM_CFLAGS = @AM_CFLAGS@ $(SECTION_FLAGS) $(IEEE_FLAGS) $(am__append_1)
|
||||
AM_FCFLAGS = @AM_FCFLAGS@ $(IEEE_FLAGS)
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
|
@ -453,7 +405,6 @@ FCFLAGS = @FCFLAGS@
|
|||
FGREP = @FGREP@
|
||||
FPU_HOST_HEADER = @FPU_HOST_HEADER@
|
||||
GREP = @GREP@
|
||||
HWCAP_LDFLAGS = @HWCAP_LDFLAGS@
|
||||
IEEE_FLAGS = @IEEE_FLAGS@
|
||||
IEEE_SUPPORT = @IEEE_SUPPORT@
|
||||
INSTALL = @INSTALL@
|
||||
|
@ -525,7 +476,6 @@ dvidir = @dvidir@
|
|||
enable_shared = @enable_shared@
|
||||
enable_static = @enable_static@
|
||||
exec_prefix = @exec_prefix@
|
||||
extra_ldflags_libgfortran = @extra_ldflags_libgfortran@
|
||||
get_gcc_base_ver = @get_gcc_base_ver@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
|
@ -541,10 +491,8 @@ libdir = @libdir@
|
|||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_host_flags = @lt_host_flags@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
multi_basedir = @multi_basedir@
|
||||
oldincludedir = @oldincludedir@
|
||||
onestep = @onestep@
|
||||
pdfdir = @pdfdir@
|
||||
|
@ -568,43 +516,28 @@ top_build_prefix = @top_build_prefix@
|
|||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
|
||||
@LIBGFOR_USE_SYMVER_FALSE@version_arg =
|
||||
@LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/gfortran.map
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_arg = -Wl,-M,gfortran.map-sun
|
||||
@LIBGFOR_USE_SYMVER_FALSE@version_dep =
|
||||
@LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = $(srcdir)/gfortran.map
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.map-sun
|
||||
version_arg =
|
||||
version_dep =
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \
|
||||
$(lt_host_flags)
|
||||
|
||||
toolexeclib_LTLIBRARIES = libgfortran.la
|
||||
toolexeclib_DATA = libgfortran.spec
|
||||
libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS)
|
||||
libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
|
||||
$(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \
|
||||
$(HWCAP_LDFLAGS) \
|
||||
-lm $(extra_ldflags_libgfortran) \
|
||||
$(version_arg) -Wc,-shared-libgcc
|
||||
toolexeclib_LTLIBRARIES = liblfortran.la
|
||||
toolexeclib_DATA = liblfortran.spec
|
||||
libglortran_la_LINK = $(LINK) $(liblfortran_la_LDFLAGS)
|
||||
liblfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
|
||||
$(LTLDFLAGS) $(LIBQUADLIB) \
|
||||
$(HWCAP_LDFLAGS) -lm
|
||||
|
||||
libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
|
||||
liblfortran_la_DEPENDENCIES = $(version_dep) liblfortran.spec $(LIBQUADLIB_DEP)
|
||||
cafexeclib_LTLIBRARIES = libcaf_single.la
|
||||
cafexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
|
||||
cafexeclibdir = $(libdir)
|
||||
libcaf_single_la_SOURCES = caf/single.c
|
||||
libcaf_single_la_LDFLAGS = -static
|
||||
libcaf_single_la_DEPENDENCIES = caf/libcaf.h
|
||||
libcaf_single_la_LINK = $(LINK) $(libcaf_single_la_LDFLAGS)
|
||||
@IEEE_SUPPORT_TRUE@fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/finclude
|
||||
@IEEE_SUPPORT_TRUE@nodist_finclude_HEADERS = ieee_arithmetic.mod ieee_exceptions.mod ieee_features.mod
|
||||
AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../gcc/config $(LIBQUADINCLUDE) \
|
||||
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../libgcc \
|
||||
-I$(MULTIBUILDTOP)../libgcc \
|
||||
-I$(srcdir)/$(MULTISRCTOP)../libbacktrace \
|
||||
-I$(MULTIBUILDTOP)../libbacktrace \
|
||||
-I../libbacktrace
|
||||
|
||||
@IEEE_SUPPORT_TRUE@fincludedir = $(includedir)
|
||||
@IEEE_SUPPORT_TRUE@nodist_finclude_HEADERS = ieee_arithmetic.mod ieee_exceptions.mod ieee_features.mod $(srcdir)/omp_lib.h $(srcdir)/omp_lib.mod $(srcdir)/omp_lib_kinds.mod
|
||||
AM_CPPFLAGS =
|
||||
gfor_io_src = io/size_from_kind.c $(am__append_2)
|
||||
gfor_io_headers = \
|
||||
io/io.h \
|
||||
|
@ -625,16 +558,28 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \
|
|||
intrinsics/selected_int_kind.f90 \
|
||||
intrinsics/selected_real_kind.f90 intrinsics/unpack_generic.c \
|
||||
runtime/in_pack_generic.c runtime/in_unpack_generic.c \
|
||||
$(am__append_3) $(am__append_4)
|
||||
@IEEE_SUPPORT_FALSE@gfor_ieee_src =
|
||||
@IEEE_SUPPORT_TRUE@gfor_ieee_src = \
|
||||
@IEEE_SUPPORT_TRUE@ieee/ieee_arithmetic.F90 \
|
||||
@IEEE_SUPPORT_TRUE@ieee/ieee_exceptions.F90 \
|
||||
@IEEE_SUPPORT_TRUE@ieee/ieee_features.F90
|
||||
runtime/copy_psp.c \
|
||||
intrinsics/access.c intrinsics/c99_functions.c \
|
||||
intrinsics/chdir.c intrinsics/chmod.c intrinsics/clock.c \
|
||||
intrinsics/cpu_time.c intrinsics/ctime.c \
|
||||
intrinsics/date_and_time.c intrinsics/dtime.c intrinsics/env.c \
|
||||
intrinsics/etime.c intrinsics/execute_command_line.c \
|
||||
intrinsics/exit.c intrinsics/gerror.c intrinsics/getcwd.c \
|
||||
intrinsics/getlog.c intrinsics/getXid.c intrinsics/hostnm.c \
|
||||
intrinsics/kill.c intrinsics/link.c intrinsics/perror.c \
|
||||
intrinsics/signal.c intrinsics/sleep.c intrinsics/system.c \
|
||||
intrinsics/rename.c intrinsics/stat.c intrinsics/symlnk.c \
|
||||
intrinsics/system_clock.c intrinsics/time.c intrinsics/umask.c \
|
||||
intrinsics/unlink.c generated/index.c generated/dprod.c \
|
||||
ieee/ieee_helper.c
|
||||
gfor_ieee_src = \
|
||||
ieee/ieee_arithmetic.F90 \
|
||||
ieee/ieee_exceptions.F90 \
|
||||
ieee/ieee_features.F90
|
||||
|
||||
gfor_src = runtime/bounds.c runtime/compile_options.c runtime/memory.c \
|
||||
runtime/string.c runtime/select.c $(am__append_5) \
|
||||
$(am__append_6)
|
||||
runtime/string.c runtime/select.c $(am__append_3) \
|
||||
$(am__append_4)
|
||||
i_all_c = \
|
||||
$(srcdir)/generated/all_l1.c \
|
||||
$(srcdir)/generated/all_l2.c \
|
||||
|
@ -1210,29 +1155,28 @@ gfor_specific_src = \
|
|||
$(gfor_built_specific_src) \
|
||||
$(gfor_built_specific2_src) \
|
||||
$(gfor_misc_specifics) \
|
||||
intrinsics/dprod_r8.f90 \
|
||||
intrinsics/f2c_specifics.F90
|
||||
intrinsics/dprod_r8.f90
|
||||
|
||||
BUILT_SOURCES = $(gfor_built_src) $(gfor_built_specific_src) \
|
||||
$(gfor_built_specific2_src) $(gfor_misc_specifics) \
|
||||
$(am__append_7)
|
||||
$(am__append_5)
|
||||
prereq_SRC = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \
|
||||
$(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src)
|
||||
|
||||
@onestep_FALSE@libgfortran_la_SOURCES = $(prereq_SRC)
|
||||
@onestep_FALSE@liblfortran_la_SOURCES = $(prereq_SRC)
|
||||
|
||||
#libgfortran_f.o: $(filter %.f %.f90,$(prereq_SRC))
|
||||
#liblfortran_f.o: $(filter %.f %.f90,$(prereq_SRC))
|
||||
# $(FCCOMPILE) -c $^ -o $@ -combine
|
||||
|
||||
#libgfortran_f.lo: $(filter %.f %.f90,$(prereq_SRC))
|
||||
#liblfortran_f.lo: $(filter %.f %.f90,$(prereq_SRC))
|
||||
# $(LTFCCOMPILE) -c -o $@ $^ -combine
|
||||
# not currently used:
|
||||
#libgfortran_F.o: $(filter %.F %.F90,$(prereq_SRC))
|
||||
#liblfortran_F.o: $(filter %.F %.F90,$(prereq_SRC))
|
||||
# $(PPFCCOMPILE) -c $^ -o $@ -combine
|
||||
#
|
||||
#libgfortran_F.lo:
|
||||
#liblfortran_F.lo:
|
||||
# $(LTPPFCCOMPILE) -c -o $@ $^ -combine
|
||||
@onestep_TRUE@libgfortran_la_SOURCES = libgfortran_c.c $(filter-out %.c,$(prereq_SRC))
|
||||
@onestep_TRUE@liblfortran_la_SOURCES = liblfortran_c.c $(filter-out %.c,$(prereq_SRC))
|
||||
I_M4_DEPS = m4/iparm.m4
|
||||
I_M4_DEPS0 = $(I_M4_DEPS) m4/iforeach.m4
|
||||
I_M4_DEPS1 = $(I_M4_DEPS) m4/ifunction.m4
|
||||
|
@ -1292,7 +1236,7 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|||
|
||||
distclean-hdr:
|
||||
-rm -f config.h stamp-h1
|
||||
libgfortran.spec: $(top_builddir)/config.status $(srcdir)/libgfortran.spec.in
|
||||
liblfortran.spec: $(top_builddir)/config.status $(srcdir)/liblfortran.spec.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
install-cafexeclibLTLIBRARIES: $(cafexeclib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
|
@ -1360,8 +1304,8 @@ clean-toolexeclibLTLIBRARIES:
|
|||
done
|
||||
libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES) $(EXTRA_libcaf_single_la_DEPENDENCIES)
|
||||
$(libcaf_single_la_LINK) -rpath $(cafexeclibdir) $(libcaf_single_la_OBJECTS) $(libcaf_single_la_LIBADD) $(LIBS)
|
||||
libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES) $(EXTRA_libgfortran_la_DEPENDENCIES)
|
||||
$(libgfortran_la_LINK) -rpath $(toolexeclibdir) $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD) $(LIBS)
|
||||
liblfortran.la: $(liblfortran_la_OBJECTS) $(liblfortran_la_DEPENDENCIES) $(EXTRA_liblfortran_la_DEPENDENCIES)
|
||||
$(liblfortran_la_LINK) -rpath $(toolexeclibdir) $(liblfortran_la_OBJECTS) $(liblfortran_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
@ -1396,6 +1340,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compile_options.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert_char.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_psp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_16_l.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_1_l.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_2_l.Plo@am__quote@
|
||||
|
@ -1421,6 +1366,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cshift1_8.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctime.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/date_and_time.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dprod.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtime.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Plo@am__quote@
|
||||
|
@ -1488,6 +1434,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_r16.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_r4.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_r8.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/index.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inquire.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intrinsics.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iparity_i1.Plo@am__quote@
|
||||
|
@ -1497,7 +1444,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iparity_i8.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ishftc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kill.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgfortran_c.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblfortran_c.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list_read.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock.Plo@am__quote@
|
||||
|
@ -2229,9 +2176,6 @@ _mod_r16.lo: $(srcdir)/generated/_mod_r16.F90
|
|||
misc_specifics.lo: $(srcdir)/generated/misc_specifics.F90
|
||||
$(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(FC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FCFLAGS) $(FCFLAGS) -c -o misc_specifics.lo `test -f '$(srcdir)/generated/misc_specifics.F90' || echo '$(srcdir)/'`$(srcdir)/generated/misc_specifics.F90
|
||||
|
||||
f2c_specifics.lo: intrinsics/f2c_specifics.F90
|
||||
$(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(FC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FCFLAGS) $(FCFLAGS) -c -o f2c_specifics.lo `test -f 'intrinsics/f2c_specifics.F90' || echo '$(srcdir)/'`intrinsics/f2c_specifics.F90
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
|
@ -5039,6 +4983,13 @@ unpack_generic.lo: intrinsics/unpack_generic.c
|
|||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unpack_generic.lo `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c
|
||||
|
||||
copy_psp.lo: runtime/copy_psp.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT copy_psp.lo -MD -MP -MF $(DEPDIR)/copy_psp.Tpo -c -o copy_psp.lo `test -f 'runtime/copy_psp.c' || echo '$(srcdir)/'`runtime/copy_psp.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/copy_psp.Tpo $(DEPDIR)/copy_psp.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/copy_psp.c' object='copy_psp.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o copy_psp.lo `test -f 'runtime/copy_psp.c' || echo '$(srcdir)/'`runtime/copy_psp.c
|
||||
|
||||
in_pack_generic.lo: runtime/in_pack_generic.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_generic.lo -MD -MP -MF $(DEPDIR)/in_pack_generic.Tpo -c -o in_pack_generic.lo `test -f 'runtime/in_pack_generic.c' || echo '$(srcdir)/'`runtime/in_pack_generic.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/in_pack_generic.Tpo $(DEPDIR)/in_pack_generic.Plo
|
||||
|
@ -5270,6 +5221,20 @@ unlink.lo: intrinsics/unlink.c
|
|||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unlink.lo `test -f 'intrinsics/unlink.c' || echo '$(srcdir)/'`intrinsics/unlink.c
|
||||
|
||||
index.lo: generated/index.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT index.lo -MD -MP -MF $(DEPDIR)/index.Tpo -c -o index.lo `test -f 'generated/index.c' || echo '$(srcdir)/'`generated/index.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/index.Tpo $(DEPDIR)/index.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/index.c' object='index.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o index.lo `test -f 'generated/index.c' || echo '$(srcdir)/'`generated/index.c
|
||||
|
||||
dprod.lo: generated/dprod.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dprod.lo -MD -MP -MF $(DEPDIR)/dprod.Tpo -c -o dprod.lo `test -f 'generated/dprod.c' || echo '$(srcdir)/'`generated/dprod.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dprod.Tpo $(DEPDIR)/dprod.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dprod.c' object='dprod.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dprod.lo `test -f 'generated/dprod.c' || echo '$(srcdir)/'`generated/dprod.c
|
||||
|
||||
ieee_helper.lo: ieee/ieee_helper.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ieee_helper.lo -MD -MP -MF $(DEPDIR)/ieee_helper.Tpo -c -o ieee_helper.lo `test -f 'ieee/ieee_helper.c' || echo '$(srcdir)/'`ieee/ieee_helper.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ieee_helper.Tpo $(DEPDIR)/ieee_helper.Plo
|
||||
|
@ -5303,23 +5268,6 @@ clean-libtool:
|
|||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
|
||||
# GNU Make needs to see an explicit $(MAKE) variable in the command it
|
||||
# runs to enable its job server during parallel builds. Hence the
|
||||
# comments below.
|
||||
all-multi:
|
||||
$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
|
||||
install-multi:
|
||||
$(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
|
||||
|
||||
mostlyclean-multi:
|
||||
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
|
||||
clean-multi:
|
||||
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
|
||||
distclean-multi:
|
||||
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
|
||||
maintainer-clean-multi:
|
||||
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
|
||||
install-toolexeclibDATA: $(toolexeclib_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
|
||||
|
@ -5417,7 +5365,7 @@ distclean-tags:
|
|||
check-am: all-am
|
||||
check: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-am
|
||||
all-am: Makefile $(LTLIBRARIES) all-multi $(DATA) $(HEADERS) config.h
|
||||
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) config.h
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(cafexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(fincludedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
|
@ -5454,12 +5402,12 @@ maintainer-clean-generic:
|
|||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
clean: clean-am clean-multi
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-cafexeclibLTLIBRARIES clean-generic clean-libtool \
|
||||
clean-toolexeclibLTLIBRARIES mostlyclean-am
|
||||
|
||||
distclean: distclean-am distclean-multi
|
||||
distclean: distclean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
|
@ -5484,8 +5432,8 @@ install-dvi: install-dvi-am
|
|||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-cafexeclibLTLIBRARIES install-multi \
|
||||
install-toolexeclibDATA install-toolexeclibLTLIBRARIES
|
||||
install-exec-am: install-cafexeclibLTLIBRARIES install-toolexeclibDATA \
|
||||
install-toolexeclibLTLIBRARIES
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
|
@ -5507,14 +5455,14 @@ install-ps-am:
|
|||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am maintainer-clean-multi
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am mostlyclean-multi
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
@ -5531,52 +5479,38 @@ uninstall-am: uninstall-cafexeclibLTLIBRARIES \
|
|||
uninstall-nodist_fincludeHEADERS uninstall-toolexeclibDATA \
|
||||
uninstall-toolexeclibLTLIBRARIES
|
||||
|
||||
.MAKE: all all-multi check clean-multi distclean-multi install \
|
||||
install-am install-multi install-strip maintainer-clean-multi \
|
||||
mostlyclean-multi
|
||||
.MAKE: all check install install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am all-multi am--refresh check check-am \
|
||||
clean clean-cafexeclibLTLIBRARIES clean-generic clean-libtool \
|
||||
clean-multi clean-toolexeclibLTLIBRARIES ctags distclean \
|
||||
distclean-compile distclean-generic distclean-hdr \
|
||||
distclean-libtool distclean-multi distclean-tags dvi dvi-am \
|
||||
html html-am info info-am install install-am \
|
||||
install-cafexeclibLTLIBRARIES install-data install-data-am \
|
||||
install-dvi install-dvi-am install-exec install-exec-am \
|
||||
install-html install-html-am install-info install-info-am \
|
||||
install-man install-multi install-nodist_fincludeHEADERS \
|
||||
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
|
||||
clean-cafexeclibLTLIBRARIES clean-generic clean-libtool \
|
||||
clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags dvi dvi-am html html-am info info-am install \
|
||||
install-am install-cafexeclibLTLIBRARIES install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-nodist_fincludeHEADERS \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip install-toolexeclibDATA \
|
||||
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
maintainer-clean-multi mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \
|
||||
pdf-am ps ps-am tags uninstall uninstall-am \
|
||||
uninstall-cafexeclibLTLIBRARIES \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-cafexeclibLTLIBRARIES \
|
||||
uninstall-nodist_fincludeHEADERS uninstall-toolexeclibDATA \
|
||||
uninstall-toolexeclibLTLIBRARIES
|
||||
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@gfortran.map-sun : $(srcdir)/gfortran.map \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD)
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ $(srcdir)/gfortran.map \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ $(libgfortran_la_OBJECTS:%.lo=.libs/%.o) \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ `echo $(libgfortran_la_LIBADD) | \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
|
||||
@LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@ > $@ || (rm -f $@ ; exit 1)
|
||||
|
||||
# Turn on vectorization and loop unrolling for matmul.
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmul_c))): AM_CFLAGS += -ffast-math -ftree-vectorize -funroll-loops --param max-unroll-times=4
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmul_c))): AM_CFLAGS += -ffast-math -fno-associative-math -funroll-loops --param max-unroll-times=4
|
||||
# Logical matmul doesn't vectorize.
|
||||
$(patsubst %.c,%.lo,$(notdir $(i_matmull_c))): AM_CFLAGS += -funroll-loops
|
||||
|
||||
# Add the -fallow-leading-underscore option when needed
|
||||
$(patsubst %.F90,%.lo,$(patsubst %.f90,%.lo,$(notdir $(gfor_specific_src)))): AM_FCFLAGS += -fallow-leading-underscore
|
||||
selected_real_kind.lo selected_int_kind.lo: AM_FCFLAGS += -fallow-leading-underscore
|
||||
$(patsubst %.F90,%.lo,$(patsubst %.f90,%.lo,$(notdir $(gfor_specific_src)))):
|
||||
selected_real_kind.lo selected_int_kind.lo:
|
||||
|
||||
# Add flags for IEEE modules
|
||||
@IEEE_SUPPORT_TRUE@$(patsubst %.F90,%.lo,$(notdir $(gfor_ieee_src))): AM_FCFLAGS += -Wno-unused-dummy-argument -Wno-c-binding-type -ffree-line-length-0 -fallow-leading-underscore
|
||||
@IEEE_SUPPORT_TRUE@$(patsubst %.F90,%.lo,$(notdir $(gfor_ieee_src))): AM_FCFLAGS += -ffree-line-length-0
|
||||
|
||||
# Dependencies between IEEE_ARITHMETIC and IEEE_EXCEPTIONS
|
||||
ieee_arithmetic.lo: ieee/ieee_arithmetic.F90 ieee_exceptions.lo
|
||||
|
@ -5588,13 +5522,13 @@ ieee_exceptions.mod: ieee_exceptions.lo
|
|||
:
|
||||
ieee_arithmetic.mod: ieee_arithmetic.lo
|
||||
:
|
||||
@onestep_TRUE@libgfortran_c.c libgfortran_f.f90 libgfortran_F.F90:
|
||||
@onestep_TRUE@liblfortran_c.c liblfortran_f.f90 liblfortran_F.F90:
|
||||
@onestep_TRUE@ echo > $@
|
||||
# overrides for libtool perusing the dummy sources
|
||||
@onestep_TRUE@libgfortran_c.o: $(filter %.c,$(prereq_SRC))
|
||||
@onestep_TRUE@liblfortran_c.o: $(filter %.c,$(prereq_SRC))
|
||||
@onestep_TRUE@ $(COMPILE) -c $^ -o $@ -combine
|
||||
|
||||
@onestep_TRUE@libgfortran_c.lo: $(filter %.c,$(prereq_SRC))
|
||||
@onestep_TRUE@liblfortran_c.lo: $(filter %.c,$(prereq_SRC))
|
||||
@onestep_TRUE@ $(LTCOMPILE) -c -o $@ $^ -combine
|
||||
|
||||
kinds.h: $(srcdir)/mk-kinds-h.sh
|
||||
|
@ -5606,18 +5540,14 @@ kinds.inc: kinds.h
|
|||
c99_protos.inc: $(srcdir)/c99_protos.h
|
||||
grep '^#' < $(srcdir)/c99_protos.h > $@
|
||||
|
||||
selected_int_kind.inc: $(srcdir)/mk-sik-inc.sh
|
||||
$(SHELL) $(srcdir)/mk-sik-inc.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
|
||||
selected_real_kind.inc: $(srcdir)/mk-srk-inc.sh
|
||||
$(SHELL) $(srcdir)/mk-srk-inc.sh '$(FCCOMPILE)' > $@ || rm $@
|
||||
|
||||
fpu-target.h: $(srcdir)/$(FPU_HOST_HEADER)
|
||||
cp $(srcdir)/$(FPU_HOST_HEADER) $@
|
||||
|
||||
fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h
|
||||
grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true
|
||||
grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true
|
||||
fpu-target.inc: fpu-target.h
|
||||
grep '^#define GFC_FPE_' < $(srcdir)/commonLibFortran.h > $@ || true
|
||||
|
||||
@MAINTAINER_MODE_TRUE@$(i_all_c): m4/all.m4 $(I_M4_DEPS2)
|
||||
@MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@
|
||||
|
|
|
@ -298,60 +298,10 @@ AC_DEFUN([LIBGFOR_CHECK_FLOAT128], [
|
|||
if test "x$libgfor_cv_have_float128" = xyes; then
|
||||
AC_DEFINE(HAVE_FLOAT128, 1, [Define if have a usable __float128 type.])
|
||||
|
||||
dnl Check whether -Wl,--as-needed resp. -Wl,-zignore is supported
|
||||
dnl
|
||||
dnl Turn warnings into error to avoid testsuite breakage. So enable
|
||||
dnl AC_LANG_WERROR, but there's currently (autoconf 2.64) no way to turn
|
||||
dnl it off again. As a workaround, save and restore werror flag like
|
||||
dnl AC_PATH_XTRA.
|
||||
dnl Cf. http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01889.html
|
||||
ac_xsave_[]_AC_LANG_ABBREV[]_werror_flag=$ac_[]_AC_LANG_ABBREV[]_werror_flag
|
||||
AC_CACHE_CHECK([whether --as-needed/-z ignore works],
|
||||
[libgfor_cv_have_as_needed],
|
||||
[
|
||||
# Test for native Solaris options first.
|
||||
# No whitespace after -z to pass it through -Wl.
|
||||
libgfor_cv_as_needed_option="-zignore"
|
||||
libgfor_cv_no_as_needed_option="-zrecord"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,$libgfor_cv_as_needed_option -lm -Wl,$libgfor_cv_no_as_needed_option"
|
||||
libgfor_cv_have_as_needed=no
|
||||
AC_LANG_WERROR
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
|
||||
[libgfor_cv_have_as_needed=yes],
|
||||
[libgfor_cv_have_as_needed=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
if test "x$libgfor_cv_have_as_needed" = xno; then
|
||||
libgfor_cv_as_needed_option="--as-needed"
|
||||
libgfor_cv_no_as_needed_option="--no-as-needed"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,$libgfor_cv_as_needed_option -lm -Wl,$libgfor_cv_no_as_needed_option"
|
||||
libgfor_cv_have_as_needed=no
|
||||
AC_LANG_WERROR
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
|
||||
[libgfor_cv_have_as_needed=yes],
|
||||
[libgfor_cv_have_as_needed=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
fi
|
||||
ac_[]_AC_LANG_ABBREV[]_werror_flag=$ac_xsave_[]_AC_LANG_ABBREV[]_werror_flag
|
||||
])
|
||||
|
||||
dnl For static libgfortran linkage, depend on libquadmath only if needed.
|
||||
if test "x$libgfor_cv_have_as_needed" = xyes; then
|
||||
LIBQUADSPEC="%{static-libgfortran:$libgfor_cv_as_needed_option} -lquadmath %{static-libgfortran:$libgfor_cv_no_as_needed_option}"
|
||||
else
|
||||
LIBQUADSPEC="-lquadmath"
|
||||
fi
|
||||
if test -f ../libquadmath/libquadmath.la; then
|
||||
LIBQUADLIB=../libquadmath/libquadmath.la
|
||||
LIBQUADLIB_DEP=../libquadmath/libquadmath.la
|
||||
LIBQUADINCLUDE='-I$(srcdir)/../libquadmath'
|
||||
else
|
||||
LIBQUADLIB="-lquadmath"
|
||||
LIBQUADLIB_DEP=
|
||||
LIBQUADINCLUDE=
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# for --disable-quadmath
|
||||
LIBQUADLIB=
|
||||
|
|
|
@ -1024,10 +1024,7 @@ AC_SUBST([am__untar])
|
|||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([../config/depstand.m4])
|
||||
m4_include([../config/hwcaps.m4])
|
||||
m4_include([../config/lead-dot.m4])
|
||||
m4_include([../config/lthostflags.m4])
|
||||
m4_include([../config/multi.m4])
|
||||
m4_include([../config/override.m4])
|
||||
m4_include([../config/stdint.m4])
|
||||
m4_include([../ltoptions.m4])
|
||||
|
|
|
@ -30,7 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
#include <stddef.h> /* For size_t. */
|
||||
#include <stdint.h> /* For int32_t. */
|
||||
|
||||
#include "libgfortran.h"
|
||||
#include "liblfortran.h"
|
||||
|
||||
#if 0
|
||||
#ifndef __GNUC__
|
||||
|
@ -44,7 +44,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
#endif
|
||||
|
||||
/* Definitions of the Fortran 2008 standard; need to kept in sync with
|
||||
ISO_FORTRAN_ENV, cf. gcc/fortran/libgfortran.h. */
|
||||
ISO_FORTRAN_ENV, cf. gcc/fortran/liblfortran.h. */
|
||||
typedef enum
|
||||
{
|
||||
CAF_STAT_UNLOCKED = 0,
|
||||
|
@ -183,81 +183,81 @@ typedef struct caf_reference_t {
|
|||
} u;
|
||||
} caf_reference_t;
|
||||
|
||||
void _gfortran_caf_init (int *, char ***);
|
||||
void _gfortran_caf_finalize (void);
|
||||
void _lfortran_caf_init (int *, char ***);
|
||||
void _lfortran_caf_finalize (void);
|
||||
|
||||
int _gfortran_caf_this_image (int);
|
||||
int _gfortran_caf_num_images (int, int);
|
||||
int _lfortran_caf_this_image (int);
|
||||
int _lfortran_caf_num_images (int, int);
|
||||
|
||||
void _gfortran_caf_register (size_t, caf_register_t, caf_token_t *,
|
||||
void _lfortran_caf_register (size_t, caf_register_t, caf_token_t *,
|
||||
gfc_descriptor_t *, int *, char *, int);
|
||||
void _gfortran_caf_deregister (caf_token_t *, caf_deregister_t, int *, char *,
|
||||
void _lfortran_caf_deregister (caf_token_t *, caf_deregister_t, int *, char *,
|
||||
int);
|
||||
|
||||
void _gfortran_caf_sync_all (int *, char *, int);
|
||||
void _gfortran_caf_sync_memory (int *, char *, int);
|
||||
void _gfortran_caf_sync_images (int, int[], int *, char *, int);
|
||||
void _lfortran_caf_sync_all (int *, char *, int);
|
||||
void _lfortran_caf_sync_memory (int *, char *, int);
|
||||
void _lfortran_caf_sync_images (int, int[], int *, char *, int);
|
||||
|
||||
void _gfortran_caf_stop_numeric (int32_t)
|
||||
void _lfortran_caf_stop_numeric (int32_t)
|
||||
__attribute__ ((noreturn));
|
||||
void _gfortran_caf_stop_str (const char *, int32_t)
|
||||
void _lfortran_caf_stop_str (const char *, int32_t)
|
||||
__attribute__ ((noreturn));
|
||||
void _gfortran_caf_error_stop_str (const char *, int32_t)
|
||||
void _lfortran_caf_error_stop_str (const char *, int32_t)
|
||||
__attribute__ ((noreturn));
|
||||
void _gfortran_caf_error_stop (int32_t) __attribute__ ((noreturn));
|
||||
void _gfortran_caf_fail_image (void) __attribute__ ((noreturn));
|
||||
void _lfortran_caf_error_stop (int32_t) __attribute__ ((noreturn));
|
||||
void _lfortran_caf_fail_image (void) __attribute__ ((noreturn));
|
||||
|
||||
void _gfortran_caf_co_broadcast (gfc_descriptor_t *, int, int *, char *, int);
|
||||
void _gfortran_caf_co_sum (gfc_descriptor_t *, int, int *, char *, int);
|
||||
void _gfortran_caf_co_min (gfc_descriptor_t *, int, int *, char *, int, int);
|
||||
void _gfortran_caf_co_max (gfc_descriptor_t *, int, int *, char *, int, int);
|
||||
void _gfortran_caf_co_reduce (gfc_descriptor_t *, void* (*) (void *, void*),
|
||||
void _lfortran_caf_co_broadcast (gfc_descriptor_t *, int, int *, char *, int);
|
||||
void _lfortran_caf_co_sum (gfc_descriptor_t *, int, int *, char *, int);
|
||||
void _lfortran_caf_co_min (gfc_descriptor_t *, int, int *, char *, int, int);
|
||||
void _lfortran_caf_co_max (gfc_descriptor_t *, int, int *, char *, int, int);
|
||||
void _lfortran_caf_co_reduce (gfc_descriptor_t *, void* (*) (void *, void*),
|
||||
int, int, int *, char *, int, int);
|
||||
|
||||
void _gfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
void _lfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
caf_vector_t *, gfc_descriptor_t *, int, int, bool,
|
||||
int *);
|
||||
void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
void _lfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
caf_vector_t *, gfc_descriptor_t *, int, int, bool,
|
||||
int *);
|
||||
void _gfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
void _lfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||
caf_vector_t *, caf_token_t, size_t, int,
|
||||
gfc_descriptor_t *, caf_vector_t *, int, int, bool);
|
||||
gfc_descriptor_t *, caf_vector_t *, int, int, bool, int *stat);
|
||||
|
||||
void _gfortran_caf_get_by_ref (caf_token_t token, int image_idx,
|
||||
void _lfortran_caf_get_by_ref (caf_token_t token, int image_idx,
|
||||
gfc_descriptor_t *dst, caf_reference_t *refs, int dst_kind,
|
||||
int src_kind, bool may_require_tmp, bool dst_reallocatable, int *stat);
|
||||
void _gfortran_caf_send_by_ref (caf_token_t token, int image_index,
|
||||
void _lfortran_caf_send_by_ref (caf_token_t token, int image_index,
|
||||
gfc_descriptor_t *src, caf_reference_t *refs, int dst_kind,
|
||||
int src_kind, bool may_require_tmp, bool dst_reallocatable, int *stat);
|
||||
void _gfortran_caf_sendget_by_ref (
|
||||
void _lfortran_caf_sendget_by_ref (
|
||||
caf_token_t dst_token, int dst_image_index, caf_reference_t *dst_refs,
|
||||
caf_token_t src_token, int src_image_index, caf_reference_t *src_refs,
|
||||
int dst_kind, int src_kind, bool may_require_tmp, int *dst_stat,
|
||||
int *src_stat);
|
||||
|
||||
void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
|
||||
void _lfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
|
||||
int, int);
|
||||
void _gfortran_caf_atomic_ref (caf_token_t, size_t, int, void *, int *,
|
||||
void _lfortran_caf_atomic_ref (caf_token_t, size_t, int, void *, int *,
|
||||
int, int);
|
||||
void _gfortran_caf_atomic_cas (caf_token_t, size_t, int, void *, void *,
|
||||
void _lfortran_caf_atomic_cas (caf_token_t, size_t, int, void *, void *,
|
||||
void *, int *, int, int);
|
||||
void _gfortran_caf_atomic_op (int, caf_token_t, size_t, int, void *, void *,
|
||||
void _lfortran_caf_atomic_op (int, caf_token_t, size_t, int, void *, void *,
|
||||
int *, int, int);
|
||||
|
||||
void _gfortran_caf_lock (caf_token_t, size_t, int, int *, int *, char *, int);
|
||||
void _gfortran_caf_unlock (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _gfortran_caf_event_post (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _gfortran_caf_event_wait (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _gfortran_caf_event_query (caf_token_t, size_t, int, int *, int *);
|
||||
void _lfortran_caf_lock (caf_token_t, size_t, int, int *, int *, char *, int);
|
||||
void _lfortran_caf_unlock (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _lfortran_caf_event_post (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _lfortran_caf_event_wait (caf_token_t, size_t, int, int *, char *, int);
|
||||
void _lfortran_caf_event_query (caf_token_t, size_t, int, int *, int *);
|
||||
|
||||
void _gfortran_caf_failed_images (gfc_descriptor_t *,
|
||||
void _lfortran_caf_failed_images (gfc_descriptor_t *,
|
||||
caf_team_t * __attribute__ ((unused)), int *);
|
||||
int _gfortran_caf_image_status (int, caf_team_t * __attribute__ ((unused)));
|
||||
void _gfortran_caf_stopped_images (gfc_descriptor_t *,
|
||||
int _lfortran_caf_image_status (int, caf_team_t * __attribute__ ((unused)));
|
||||
void _lfortran_caf_stopped_images (gfc_descriptor_t *,
|
||||
caf_team_t * __attribute__ ((unused)),
|
||||
int *);
|
||||
|
||||
int _gfortran_caf_is_present (caf_token_t, int, caf_reference_t *);
|
||||
int _lfortran_caf_is_present (caf_token_t, int, caf_reference_t *);
|
||||
|
||||
#endif /* LIBCAF_H */
|
||||
|
|
|
@ -53,7 +53,7 @@ static void
|
|||
caf_runtime_error (const char *message, ...)
|
||||
{
|
||||
va_list ap;
|
||||
fprintf (stderr, "Fortran runtime error on image %d: ", caf_this_image);
|
||||
fprintf (stderr, _("Fortran runtime error on image %d: "), caf_this_image);
|
||||
va_start (ap, message);
|
||||
vfprintf (stderr, message, ap);
|
||||
va_end (ap);
|
||||
|
@ -75,7 +75,7 @@ caf_runtime_error (const char *message, ...)
|
|||
libaray is initialized. */
|
||||
|
||||
void
|
||||
_gfortran_caf_init (int *argc, char ***argv)
|
||||
_lfortran_caf_init (int *argc, char ***argv)
|
||||
{
|
||||
if (caf_num_images == 0)
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ _gfortran_caf_init (int *argc, char ***argv)
|
|||
/* Finalize coarray program. */
|
||||
|
||||
void
|
||||
_gfortran_caf_finalize (void)
|
||||
_lfortran_caf_finalize (void)
|
||||
{
|
||||
while (caf_static_list != NULL)
|
||||
{
|
||||
|
@ -115,14 +115,14 @@ _gfortran_caf_finalize (void)
|
|||
|
||||
|
||||
int
|
||||
_gfortran_caf_this_image (int distance __attribute__ ((unused)))
|
||||
_lfortran_caf_this_image (int distance __attribute__ ((unused)))
|
||||
{
|
||||
return caf_this_image;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_gfortran_caf_num_images (int distance __attribute__ ((unused)),
|
||||
_lfortran_caf_num_images (int distance __attribute__ ((unused)),
|
||||
int failed __attribute__ ((unused)))
|
||||
{
|
||||
return caf_num_images;
|
||||
|
@ -130,7 +130,7 @@ _gfortran_caf_num_images (int distance __attribute__ ((unused)),
|
|||
|
||||
|
||||
void *
|
||||
_gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token,
|
||||
_lfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token,
|
||||
int *stat, char *errmsg, int errmsg_len,
|
||||
int num_alloc_comps __attribute__ ((unused)))
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token,
|
|||
|
||||
/* Start MPI if not already started. */
|
||||
if (caf_num_images == 0)
|
||||
_gfortran_caf_init (NULL, NULL);
|
||||
_lfortran_caf_init (NULL, NULL);
|
||||
|
||||
/* Token contains only a list of pointers. */
|
||||
local = malloc (size);
|
||||
|
@ -180,9 +180,9 @@ error:
|
|||
char *msg;
|
||||
|
||||
if (caf_is_finalized)
|
||||
msg = "Failed to allocate coarray - there are stopped images";
|
||||
msg = _("Failed to allocate coarray - there are stopped images");
|
||||
else
|
||||
msg = "Failed to allocate coarray";
|
||||
msg = _("Failed to allocate coarray");
|
||||
|
||||
if (stat)
|
||||
{
|
||||
|
@ -205,12 +205,11 @@ error:
|
|||
|
||||
|
||||
void
|
||||
_gfortran_caf_deregister (caf_token_t *token, int *stat, char *errmsg, int errmsg_len)
|
||||
_lfortran_caf_deregister (caf_token_t *token, int *stat, char *errmsg, int errmsg_len)
|
||||
{
|
||||
if (unlikely (caf_is_finalized))
|
||||
{
|
||||
const char msg[] = "Failed to deallocate coarray - "
|
||||
"there are stopped images";
|
||||
const char msg[] = _("Failed to deallocate coarray - there are stopped images");
|
||||
if (stat)
|
||||
{
|
||||
*stat = STAT_STOPPED_IMAGE;
|
||||
|
@ -228,7 +227,7 @@ _gfortran_caf_deregister (caf_token_t *token, int *stat, char *errmsg, int errms
|
|||
caf_runtime_error (msg);
|
||||
}
|
||||
|
||||
_gfortran_caf_sync_all (NULL, NULL, 0);
|
||||
_lfortran_caf_sync_all (NULL, NULL, 0);
|
||||
|
||||
if (stat)
|
||||
*stat = 0;
|
||||
|
@ -239,7 +238,7 @@ _gfortran_caf_deregister (caf_token_t *token, int *stat, char *errmsg, int errms
|
|||
|
||||
|
||||
void
|
||||
_gfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len)
|
||||
_lfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len)
|
||||
{
|
||||
int ierr;
|
||||
|
||||
|
@ -255,9 +254,9 @@ _gfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len)
|
|||
{
|
||||
char *msg;
|
||||
if (caf_is_finalized)
|
||||
msg = "SYNC ALL failed - there are stopped images";
|
||||
msg = _("SYNC ALL failed - there are stopped images");
|
||||
else
|
||||
msg = "SYNC ALL failed";
|
||||
msg = _("SYNC ALL failed");
|
||||
|
||||
if (errmsg_len > 0)
|
||||
{
|
||||
|
@ -277,7 +276,7 @@ _gfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len)
|
|||
SYNC IMAGES([]) has count == 0. Note further that SYNC IMAGES(*)
|
||||
is not equivalent to SYNC ALL. */
|
||||
void
|
||||
_gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
|
||||
_lfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
|
||||
int errmsg_len)
|
||||
{
|
||||
int ierr;
|
||||
|
@ -295,8 +294,7 @@ _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
|
|||
for (i = 0; i < count; i++)
|
||||
if (images[i] < 1 || images[i] > caf_num_images)
|
||||
{
|
||||
fprintf (stderr, "COARRAY ERROR: Invalid image index %d to SYNC "
|
||||
"IMAGES", images[i]);
|
||||
fprintf (stderr, _("COARRAY ERROR: Invalid image index %d to SYNC IMAGES"), images[i]);
|
||||
error_stop (1);
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +304,7 @@ _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
|
|||
mapped to MPI communicators. Thus, exist early with an error message. */
|
||||
if (count > 0)
|
||||
{
|
||||
fprintf (stderr, "COARRAY ERROR: SYNC IMAGES not yet implemented");
|
||||
fprintf (stderr, _("COARRAY ERROR: SYNC IMAGES not yet implemented"));
|
||||
error_stop (1);
|
||||
}
|
||||
|
||||
|
@ -323,9 +321,9 @@ _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
|
|||
{
|
||||
char *msg;
|
||||
if (caf_is_finalized)
|
||||
msg = "SYNC IMAGES failed - there are stopped images";
|
||||
msg = _("SYNC IMAGES failed - there are stopped images");
|
||||
else
|
||||
msg = "SYNC IMAGES failed";
|
||||
msg = _("SYNC IMAGES failed");
|
||||
|
||||
if (errmsg_len > 0)
|
||||
{
|
||||
|
@ -358,7 +356,7 @@ error_stop (int error)
|
|||
/* ERROR STOP function for string arguments. */
|
||||
|
||||
void
|
||||
_gfortran_caf_error_stop_str (const char *string, int32_t len)
|
||||
_lfortran_caf_error_stop_str (const char *string, int32_t len)
|
||||
{
|
||||
fputs ("ERROR STOP ", stderr);
|
||||
while (len--)
|
||||
|
@ -372,7 +370,7 @@ _gfortran_caf_error_stop_str (const char *string, int32_t len)
|
|||
/* ERROR STOP function for numerical arguments. */
|
||||
|
||||
void
|
||||
_gfortran_caf_error_stop (int32_t error)
|
||||
_lfortran_caf_error_stop (int32_t error)
|
||||
{
|
||||
fprintf (stderr, "ERROR STOP %d\n", error);
|
||||
error_stop (error);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,138 @@
|
|||
#pragma once
|
||||
|
||||
/* this file must be the same as in liblfortran/liblfortran (for fixing Bug 654) */
|
||||
|
||||
/* Header file to the Fortran front-end and runtime library
|
||||
Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
*/
|
||||
#include "ftn_lang_flags.h"
|
||||
|
||||
/* Bitmasks for the various FPE that can be enabled. These need to be straight integers
|
||||
e.g., 8 instead of (1<<3), because they will be included in Fortran source. */
|
||||
#define GFC_FPE_INVALID 1
|
||||
#define GFC_FPE_DENORMAL 2
|
||||
#define GFC_FPE_ZERO 4
|
||||
#define GFC_FPE_OVERFLOW 8
|
||||
#define GFC_FPE_UNDERFLOW 16
|
||||
#define GFC_FPE_INEXACT 32
|
||||
|
||||
/* Defines for floating-point rounding modes. */
|
||||
#define GFC_FPE_DOWNWARD 1
|
||||
#define GFC_FPE_TONEAREST 2
|
||||
#define GFC_FPE_TOWARDZERO 3
|
||||
#define GFC_FPE_UPWARD 4
|
||||
|
||||
/* Size of the buffer required to store FPU state for any target.
|
||||
In particular, this has to be larger than fenv_t on all glibc targets.
|
||||
Currently, the winner is x86_64 with 32 bytes. */
|
||||
#define GFC_FPE_STATE_BUFFER_SIZE 32
|
||||
|
||||
/* Bitmasks for the various runtime checks that can be enabled. */
|
||||
#define GFC_RTCHECK_BOUNDS (1<<0)
|
||||
#define GFC_RTCHECK_ARRAY_TEMPS (1<<1)
|
||||
#define GFC_RTCHECK_RECURSION (1<<2)
|
||||
#define GFC_RTCHECK_DO (1<<3)
|
||||
#define GFC_RTCHECK_POINTER (1<<4)
|
||||
#define GFC_RTCHECK_MEM (1<<5)
|
||||
#define GFC_RTCHECK_ALL (GFC_RTCHECK_BOUNDS \
|
||||
| GFC_RTCHECK_RECURSION | GFC_RTCHECK_DO \
|
||||
| GFC_RTCHECK_POINTER | GFC_RTCHECK_MEM)
|
||||
|
||||
/* Special unit numbers used to convey certain conditions. Numbers -4
|
||||
thru -9 available. NEWUNIT values start at -10. */
|
||||
#define GFC_INTERNAL_UNIT -1 /* KIND=1 Internal Unit. */
|
||||
#define GFC_INTERNAL_UNIT4 -2 /* KIND=4 Internal Unit. */
|
||||
#define GFC_INVALID_UNIT -3
|
||||
|
||||
/* Possible values for the CONVERT I/O specifier. */
|
||||
typedef enum
|
||||
{
|
||||
GFC_CONVERT_NONE = -1,
|
||||
GFC_CONVERT_NATIVE = 0,
|
||||
GFC_CONVERT_SWAP,
|
||||
GFC_CONVERT_BIG,
|
||||
GFC_CONVERT_LITTLE
|
||||
}
|
||||
unit_convert;
|
||||
|
||||
|
||||
/* Runtime errors. */
|
||||
typedef enum
|
||||
{
|
||||
LIBERROR_FIRST = -3, /* Marker for the first error. */
|
||||
LIBERROR_EOR = -2, /* End of record, must be negative. */
|
||||
LIBERROR_END = -1, /* End of file, must be negative. */
|
||||
LIBERROR_OK = 0, /* Indicates success, must be zero. */
|
||||
LIBERROR_OS = 5000, /* OS error, more info in errno. */
|
||||
LIBERROR_OPTION_CONFLICT,
|
||||
LIBERROR_BAD_OPTION,
|
||||
LIBERROR_MISSING_OPTION,
|
||||
LIBERROR_ALREADY_OPEN,
|
||||
LIBERROR_BAD_UNIT,
|
||||
LIBERROR_FORMAT,
|
||||
LIBERROR_BAD_ACTION,
|
||||
LIBERROR_ENDFILE,
|
||||
LIBERROR_BAD_US,
|
||||
LIBERROR_READ_VALUE,
|
||||
LIBERROR_READ_OVERFLOW,
|
||||
LIBERROR_INTERNAL,
|
||||
LIBERROR_INTERNAL_UNIT,
|
||||
LIBERROR_ALLOCATION,
|
||||
LIBERROR_DIRECT_EOR,
|
||||
LIBERROR_SHORT_RECORD,
|
||||
LIBERROR_CORRUPT_FILE,
|
||||
LIBERROR_INQUIRE_INTERNAL_UNIT, /* Must be different from STAT_STOPPED_IMAGE. */
|
||||
LIBERROR_LAST /* Not a real error, the last error # + 1. */
|
||||
}
|
||||
libgfortran_error_codes;
|
||||
|
||||
/* Must kept in sync with libgfortrancaf.h. */
|
||||
typedef enum
|
||||
{
|
||||
GFC_STAT_UNLOCKED = 0,
|
||||
GFC_STAT_LOCKED,
|
||||
GFC_STAT_LOCKED_OTHER_IMAGE,
|
||||
GFC_STAT_STOPPED_IMAGE = 6000, /* See LIBERROR_INQUIRE_INTERNAL_UNIT above. */
|
||||
GFC_STAT_FAILED_IMAGE
|
||||
}
|
||||
libgfortran_stat_codes;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GFC_CAF_ATOMIC_ADD = 1,
|
||||
GFC_CAF_ATOMIC_AND,
|
||||
GFC_CAF_ATOMIC_OR,
|
||||
GFC_CAF_ATOMIC_XOR
|
||||
} libcaf_atomic_codes;
|
||||
|
||||
|
||||
/* For CO_REDUCE. */
|
||||
#define GFC_CAF_BYREF (1<<0)
|
||||
#define GFC_CAF_HIDDENLEN (1<<1)
|
||||
#define GFC_CAF_ARG_VALUE (1<<2)
|
||||
#define GFC_CAF_ARG_DESC (1<<3)
|
||||
|
||||
/* Default unit number for preconnected standard input and output. */
|
||||
#define GFC_STDIN_UNIT_NUMBER 5
|
||||
#define GFC_STDOUT_UNIT_NUMBER 6
|
||||
#define GFC_STDERR_UNIT_NUMBER 0
|
||||
|
||||
|
||||
/* FIXME: Increase to 15 for Fortran 2008. Also needs changes to
|
||||
GFC_DTYPE_RANK_MASK. See PR 36825. */
|
||||
#define GFC_MAX_DIMENSIONS 7
|
||||
|
||||
#define GFC_DTYPE_RANK_MASK 0x07
|
||||
#define GFC_DTYPE_TYPE_SHIFT 3
|
||||
#define GFC_DTYPE_TYPE_MASK 0x38
|
||||
#define GFC_DTYPE_SIZE_SHIFT 6
|
||||
|
||||
/* Basic types. BT_VOID is used by ISO C Binding so funcs like c_f_pointer
|
||||
can take any arg with the pointer attribute as a param. These are also
|
||||
used in the run-time library for IO. */
|
||||
typedef enum
|
||||
{ BT_UNKNOWN = 0, BT_INTEGER, BT_LOGICAL, BT_REAL, BT_COMPLEX,
|
||||
BT_DERIVED, BT_CHARACTER, BT_CLASS, BT_PROCEDURE, BT_HOLLERITH, BT_VOID,
|
||||
BT_ASSUMED, BT_UNION
|
||||
}
|
||||
bt;
|
|
@ -905,11 +905,6 @@
|
|||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
|
|
@ -88,8 +88,8 @@ typedef struct
|
|||
my_fenv_t;
|
||||
|
||||
/* Check we can actually store the FPU state in the allocated size. */
|
||||
_Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
"GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
//_Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
// "GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
|
||||
|
||||
/* Raise the supported floating-point exceptions from EXCEPTS. Other
|
||||
|
|
|
@ -39,8 +39,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
|
||||
/* Check we can actually store the FPU state in the allocated size. */
|
||||
_Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
"GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
//_Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
// "GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
|
||||
|
||||
void
|
||||
|
@ -135,36 +135,30 @@ set_fpu (void)
|
|||
{
|
||||
#ifndef TRP_INVALID
|
||||
if (options.fpe & GFC_FPE_INVALID)
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
if (options.fpe & GFC_FPE_DENORMAL)
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' exception not supported.\n");
|
||||
|
||||
#ifndef TRP_DIV_BY_ZERO
|
||||
if (options.fpe & GFC_FPE_ZERO)
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef TRP_OVERFLOW
|
||||
if (options.fpe & GFC_FPE_OVERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef TRP_UNDERFLOW
|
||||
if (options.fpe & GFC_FPE_UNDERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef TRP_INEXACT
|
||||
if (options.fpe & GFC_FPE_INEXACT)
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
set_fpu_trap_exceptions (options.fpe, 0);
|
||||
|
|
|
@ -32,23 +32,17 @@ void
|
|||
set_fpu (void)
|
||||
{
|
||||
if (options.fpe & GFC_FPE_INVALID)
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' exception not supported.\n");
|
||||
if (options.fpe & GFC_FPE_DENORMAL)
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' exception not supported.\n");
|
||||
if (options.fpe & GFC_FPE_ZERO)
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' exception not supported.\n");
|
||||
if (options.fpe & GFC_FPE_OVERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' exception not supported.\n");
|
||||
if (options.fpe & GFC_FPE_UNDERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' exception not supported.\n");
|
||||
if (options.fpe & GFC_FPE_INEXACT)
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' exception not supported.\n");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -27,14 +27,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
feenableexcept function in fenv.h to set individual exceptions
|
||||
(there's nothing to do that in C99). */
|
||||
|
||||
|
||||
#ifdef HAVE_FENV_H
|
||||
#define __USE_GNU
|
||||
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Check we can actually store the FPU state in the allocated size. */
|
||||
_Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
"GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
//_Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
// "GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
|
||||
|
||||
void set_fpu_trap_exceptions (int trap, int notrap)
|
||||
|
@ -163,38 +165,32 @@ void set_fpu (void)
|
|||
{
|
||||
#ifndef FE_INVALID
|
||||
if (options.fpe & GFC_FPE_INVALID)
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FE_DENORMAL
|
||||
if (options.fpe & GFC_FPE_DENORMAL)
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FE_DIVBYZERO
|
||||
if (options.fpe & GFC_FPE_ZERO)
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FE_OVERFLOW
|
||||
if (options.fpe & GFC_FPE_OVERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FE_UNDERFLOW
|
||||
if (options.fpe & GFC_FPE_UNDERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FE_INEXACT
|
||||
if (options.fpe & GFC_FPE_INEXACT)
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
set_fpu_trap_exceptions (options.fpe, 0);
|
||||
|
|
|
@ -150,38 +150,32 @@ set_fpu (void)
|
|||
{
|
||||
#ifndef FP_X_INV
|
||||
if (options.fpe & GFC_FPE_INVALID)
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'invalid operation' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FP_X_DNML
|
||||
if (options.fpe & GFC_FPE_DENORMAL)
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: Floating point 'denormal operand' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FP_X_DZ
|
||||
if (options.fpe & GFC_FPE_ZERO)
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'division by zero' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FP_X_OFL
|
||||
if (options.fpe & GFC_FPE_OVERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'overflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FP_X_UFL
|
||||
if (options.fpe & GFC_FPE_UNDERFLOW)
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'underflow' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
#ifndef FP_X_IMP
|
||||
if (options.fpe & GFC_FPE_INEXACT)
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' "
|
||||
"exception not supported.\n");
|
||||
estr_write ("Fortran runtime warning: IEEE 'inexact' exception not supported.\n");
|
||||
#endif
|
||||
|
||||
set_fpu_trap_exceptions (options.fpe, 0);
|
||||
|
@ -389,8 +383,8 @@ typedef struct
|
|||
|
||||
|
||||
/* Check we can actually store the FPU state in the allocated size. */
|
||||
_Static_assert (sizeof(fpu_state_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
"GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
//_Static_assert (sizeof(fpu_state_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
|
||||
// "GFC_FPE_STATE_BUFFER_SIZE is too small");
|
||||
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#define _FP_W_TYPE_SIZE 32
|
||||
#define _FP_W_TYPE unsigned int
|
||||
#define _FP_WS_TYPE signed int
|
||||
#define _FP_I_TYPE int
|
||||
|
||||
#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
|
||||
__asm__ ("add{l} {%11,%3|%3,%11}\n\t" \
|
||||
"adc{l} {%9,%2|%2,%9}\n\t" \
|
||||
"adc{l} {%7,%1|%1,%7}\n\t" \
|
||||
"adc{l} {%5,%0|%0,%5}" \
|
||||
: "=r" ((USItype) (r3)), \
|
||||
"=&r" ((USItype) (r2)), \
|
||||
"=&r" ((USItype) (r1)), \
|
||||
"=&r" ((USItype) (r0)) \
|
||||
: "%0" ((USItype) (x3)), \
|
||||
"g" ((USItype) (y3)), \
|
||||
"%1" ((USItype) (x2)), \
|
||||
"g" ((USItype) (y2)), \
|
||||
"%2" ((USItype) (x1)), \
|
||||
"g" ((USItype) (y1)), \
|
||||
"%3" ((USItype) (x0)), \
|
||||
"g" ((USItype) (y0)))
|
||||
#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
|
||||
__asm__ ("add{l} {%8,%2|%2,%8}\n\t" \
|
||||
"adc{l} {%6,%1|%1,%6}\n\t" \
|
||||
"adc{l} {%4,%0|%0,%4}" \
|
||||
: "=r" ((USItype) (r2)), \
|
||||
"=&r" ((USItype) (r1)), \
|
||||
"=&r" ((USItype) (r0)) \
|
||||
: "%0" ((USItype) (x2)), \
|
||||
"g" ((USItype) (y2)), \
|
||||
"%1" ((USItype) (x1)), \
|
||||
"g" ((USItype) (y1)), \
|
||||
"%2" ((USItype) (x0)), \
|
||||
"g" ((USItype) (y0)))
|
||||
#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
|
||||
__asm__ ("sub{l} {%11,%3|%3,%11}\n\t" \
|
||||
"sbb{l} {%9,%2|%2,%9}\n\t" \
|
||||
"sbb{l} {%7,%1|%1,%7}\n\t" \
|
||||
"sbb{l} {%5,%0|%0,%5}" \
|
||||
: "=r" ((USItype) (r3)), \
|
||||
"=&r" ((USItype) (r2)), \
|
||||
"=&r" ((USItype) (r1)), \
|
||||
"=&r" ((USItype) (r0)) \
|
||||
: "0" ((USItype) (x3)), \
|
||||
"g" ((USItype) (y3)), \
|
||||
"1" ((USItype) (x2)), \
|
||||
"g" ((USItype) (y2)), \
|
||||
"2" ((USItype) (x1)), \
|
||||
"g" ((USItype) (y1)), \
|
||||
"3" ((USItype) (x0)), \
|
||||
"g" ((USItype) (y0)))
|
||||
#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
|
||||
__asm__ ("sub{l} {%8,%2|%2,%8}\n\t" \
|
||||
"sbb{l} {%6,%1|%1,%6}\n\t" \
|
||||
"sbb{l} {%4,%0|%0,%4}" \
|
||||
: "=r" ((USItype) (r2)), \
|
||||
"=&r" ((USItype) (r1)), \
|
||||
"=&r" ((USItype) (r0)) \
|
||||
: "0" ((USItype) (x2)), \
|
||||
"g" ((USItype) (y2)), \
|
||||
"1" ((USItype) (x1)), \
|
||||
"g" ((USItype) (y1)), \
|
||||
"2" ((USItype) (x0)), \
|
||||
"g" ((USItype) (y0)))
|
||||
#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
|
||||
__asm__ ("add{l} {%4,%3|%3,%4}\n\t" \
|
||||
"adc{l} {$0,%2|%2,0}\n\t" \
|
||||
"adc{l} {$0,%1|%1,0}\n\t" \
|
||||
"adc{l} {$0,%0|%0,0}" \
|
||||
: "+r" ((USItype) (x3)), \
|
||||
"+&r" ((USItype) (x2)), \
|
||||
"+&r" ((USItype) (x1)), \
|
||||
"+&r" ((USItype) (x0)) \
|
||||
: "g" ((USItype) (i)))
|
||||
|
||||
|
||||
#define _FP_MUL_MEAT_S(R,X,Y) \
|
||||
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
|
||||
#define _FP_MUL_MEAT_D(R,X,Y) \
|
||||
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
|
||||
#define _FP_MUL_MEAT_Q(R,X,Y) \
|
||||
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
|
||||
|
||||
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
|
||||
|
||||
#define _FP_NANFRAC_S _FP_QNANBIT_S
|
||||
#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
|
||||
/* Even if XFmode is 12byte, we have to pad it to
|
||||
16byte since soft-fp emulation is done in 16byte. */
|
||||
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0, 0, 0
|
||||
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#define FP_EX_SHIFT 0
|
||||
|
||||
#define _FP_DECL_EX \
|
||||
unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
|
||||
|
||||
#define FP_RND_NEAREST 0
|
||||
#define FP_RND_ZERO 0xc00
|
||||
#define FP_RND_PINF 0x800
|
||||
#define FP_RND_MINF 0x400
|
||||
|
||||
#define FP_RND_MASK 0xc00
|
||||
|
||||
#define FP_INIT_ROUNDMODE \
|
||||
do { \
|
||||
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (_fcw)); \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
HOST_LIBGCC2_CFLAGS += -mlong-double-80
|
|
@ -0,0 +1,5 @@
|
|||
# Omit TImode functions
|
||||
softfp_int_modes := si di
|
||||
|
||||
# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
|
||||
LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
|
|
@ -0,0 +1,62 @@
|
|||
/* Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
union _FP_UNION_Q
|
||||
{
|
||||
__float128 flt;
|
||||
struct
|
||||
{
|
||||
unsigned long frac0 : 32;
|
||||
unsigned long frac1 : 32;
|
||||
unsigned long frac2 : 32;
|
||||
unsigned long frac3 : 16;
|
||||
unsigned exp : 15;
|
||||
unsigned sign : 1;
|
||||
} bits __attribute__((packed));
|
||||
};
|
||||
|
||||
__float128 __copysigntf3 (__float128, __float128);
|
||||
__float128 __fabstf2 (__float128);
|
||||
|
||||
__float128
|
||||
__copysigntf3 (__float128 a, __float128 b)
|
||||
{
|
||||
union _FP_UNION_Q A, B;
|
||||
|
||||
A.flt = a;
|
||||
B.flt = b;
|
||||
A.bits.sign = B.bits.sign;
|
||||
|
||||
return A.flt;
|
||||
}
|
||||
|
||||
__float128
|
||||
__fabstf2 (__float128 a)
|
||||
{
|
||||
union _FP_UNION_Q A;
|
||||
|
||||
A.flt = a;
|
||||
A.bits.sign = 0;
|
||||
|
||||
return A.flt;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifdef SHARED
|
||||
#define __divtc3 __divtc3_shared
|
||||
#endif
|
||||
|
||||
#define L_divtc3
|
||||
#include "libgcc2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __divtc3
|
||||
extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
|
||||
asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifdef SHARED
|
||||
#define __multc3 __multc3_shared
|
||||
#endif
|
||||
|
||||
#define L_multc3
|
||||
#include "libgcc2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __multc3
|
||||
extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
|
||||
asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifdef SHARED
|
||||
#define __powitf2 __powitf2_shared
|
||||
#endif
|
||||
|
||||
#define L_powitf2
|
||||
#include "libgcc2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __powitf2
|
||||
extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
|
||||
asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
#ifdef SHARED
|
||||
#define __netf2 __netf2_shared
|
||||
#endif
|
||||
|
||||
#include "soft-fp/eqtf2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __netf2
|
||||
strong_alias (__netf2_shared, __netf2_compat);
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __netf2_compat,__netf2@GCC_3.0");
|
||||
asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
#ifdef SHARED
|
||||
#define __gttf2 __gttf2_shared
|
||||
#endif
|
||||
|
||||
#include "soft-fp/getf2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __gttf2
|
||||
strong_alias (__gttf2_shared, __gttf2_compat);
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
|
||||
asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
#ifdef SHARED
|
||||
#define __lttf2 __lttf2_shared
|
||||
#endif
|
||||
|
||||
#include "soft-fp/letf2.c"
|
||||
|
||||
#ifdef SHARED
|
||||
#undef __lttf2
|
||||
strong_alias (__lttf2_shared, __lttf2_compat);
|
||||
|
||||
#ifndef _WIN32
|
||||
asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
|
||||
asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#define _FP_W_TYPE_SIZE 64
|
||||
#define _FP_W_TYPE unsigned long long
|
||||
#define _FP_WS_TYPE signed long long
|
||||
#define _FP_I_TYPE long long
|
||||
|
||||
typedef int TItype __attribute__ ((mode (TI)));
|
||||
typedef unsigned int UTItype __attribute__ ((mode (TI)));
|
||||
|
||||
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
|
||||
|
||||
#define _FP_MUL_MEAT_Q(R,X,Y) \
|
||||
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
|
||||
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
|
||||
|
||||
#define _FP_NANFRAC_S _FP_QNANBIT_S
|
||||
#define _FP_NANFRAC_D _FP_QNANBIT_D
|
||||
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
|
||||
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#define FP_EX_SHIFT 7
|
||||
|
||||
#define _FP_DECL_EX \
|
||||
unsigned int _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
|
||||
|
||||
#define FP_RND_NEAREST 0
|
||||
#define FP_RND_ZERO 0x6000
|
||||
#define FP_RND_PINF 0x4000
|
||||
#define FP_RND_MINF 0x2000
|
||||
|
||||
#define FP_RND_MASK 0x6000
|
||||
|
||||
#define FP_INIT_ROUNDMODE \
|
||||
do { \
|
||||
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_fcw)); \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
# When TFmode was first added to x86-64 in gcc 4.3.0, some TFmode
|
||||
# support functions got improper versions by accident. Here we
|
||||
# correct the version and provide backward binary compatibility.
|
||||
|
||||
# Filter out the following TFmode functions.
|
||||
tf-compats = getf2.c letf2.c eqtf2.c
|
||||
tf-functions := $(addprefix $(srcdir)/soft-fp/, $(tf-compats))
|
||||
LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
|
||||
LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
|
||||
|
||||
# Replace _divtc3, _multc3 and _powitf2.
|
||||
libgcc2-tf-functions = _divtc3 _multc3 _powitf2
|
||||
LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
|
||||
libgcc2-tf-compats = $(addsuffix .c, $(libgcc2-tf-functions))
|
||||
LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
|
|
@ -0,0 +1,397 @@
|
|||
/* Get CPU type and Features for x86 processors.
|
||||
Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
Contributed by Sriraman Tallam (tmsriram@google.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "cpuid.h"
|
||||
#include "tsystem.h"
|
||||
#include "auto-target.h"
|
||||
#include "cpuinfo.h"
|
||||
|
||||
#ifdef HAVE_INIT_PRIORITY
|
||||
#define CONSTRUCTOR_PRIORITY (101)
|
||||
#else
|
||||
#define CONSTRUCTOR_PRIORITY
|
||||
#endif
|
||||
|
||||
int __cpu_indicator_init (void)
|
||||
__attribute__ ((constructor CONSTRUCTOR_PRIORITY));
|
||||
|
||||
|
||||
struct __processor_model __cpu_model = { };
|
||||
|
||||
|
||||
/* Get the specific type of AMD CPU. */
|
||||
|
||||
static void
|
||||
get_amd_cpu (unsigned int family, unsigned int model)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
/* AMD Family 10h. */
|
||||
case 0x10:
|
||||
__cpu_model.__cpu_type = AMDFAM10H;
|
||||
switch (model)
|
||||
{
|
||||
case 0x2:
|
||||
/* Barcelona. */
|
||||
__cpu_model.__cpu_subtype = AMDFAM10H_BARCELONA;
|
||||
break;
|
||||
case 0x4:
|
||||
/* Shanghai. */
|
||||
__cpu_model.__cpu_subtype = AMDFAM10H_SHANGHAI;
|
||||
break;
|
||||
case 0x8:
|
||||
/* Istanbul. */
|
||||
__cpu_model.__cpu_subtype = AMDFAM10H_ISTANBUL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* AMD Family 14h "btver1". */
|
||||
case 0x14:
|
||||
__cpu_model.__cpu_type = AMD_BTVER1;
|
||||
break;
|
||||
/* AMD Family 15h "Bulldozer". */
|
||||
case 0x15:
|
||||
__cpu_model.__cpu_type = AMDFAM15H;
|
||||
/* Bulldozer version 1. */
|
||||
if ( model <= 0xf)
|
||||
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
|
||||
/* Bulldozer version 2 "Piledriver" */
|
||||
if (model >= 0x10 && model <= 0x2f)
|
||||
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
|
||||
/* Bulldozer version 3 "Steamroller" */
|
||||
if (model >= 0x30 && model <= 0x4f)
|
||||
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
|
||||
/* Bulldozer version 4 "Excavator" */
|
||||
if (model >= 0x60 && model <= 0x7f)
|
||||
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
|
||||
break;
|
||||
/* AMD Family 16h "btver2" */
|
||||
case 0x16:
|
||||
__cpu_model.__cpu_type = AMD_BTVER2;
|
||||
break;
|
||||
case 0x17:
|
||||
__cpu_model.__cpu_type = AMDFAM17H;
|
||||
/* AMD family 17h version 1. */
|
||||
if (model <= 0x1f)
|
||||
__cpu_model.__cpu_subtype = AMDFAM17H_ZNVER1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the specific type of Intel CPU. */
|
||||
|
||||
static void
|
||||
get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
|
||||
{
|
||||
/* Parse family and model only if brand ID is 0. */
|
||||
if (brand_id == 0)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
case 0x5:
|
||||
/* Pentium. */
|
||||
break;
|
||||
case 0x6:
|
||||
switch (model)
|
||||
{
|
||||
case 0x1c:
|
||||
case 0x26:
|
||||
/* Bonnell. */
|
||||
__cpu_model.__cpu_type = INTEL_BONNELL;
|
||||
break;
|
||||
case 0x37:
|
||||
case 0x4a:
|
||||
case 0x4d:
|
||||
case 0x5a:
|
||||
case 0x5d:
|
||||
/* Silvermont. */
|
||||
__cpu_model.__cpu_type = INTEL_SILVERMONT;
|
||||
break;
|
||||
case 0x57:
|
||||
/* Knights Landing. */
|
||||
__cpu_model.__cpu_type = INTEL_KNL;
|
||||
break;
|
||||
case 0x1a:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
case 0x2e:
|
||||
/* Nehalem. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM;
|
||||
break;
|
||||
case 0x25:
|
||||
case 0x2c:
|
||||
case 0x2f:
|
||||
/* Westmere. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE;
|
||||
break;
|
||||
case 0x2a:
|
||||
case 0x2d:
|
||||
/* Sandy Bridge. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
|
||||
break;
|
||||
case 0x3a:
|
||||
case 0x3e:
|
||||
/* Ivy Bridge. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
|
||||
break;
|
||||
case 0x3c:
|
||||
case 0x3f:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
/* Haswell. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL;
|
||||
break;
|
||||
case 0x3d:
|
||||
case 0x47:
|
||||
case 0x4f:
|
||||
case 0x56:
|
||||
/* Broadwell. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL;
|
||||
break;
|
||||
case 0x4e:
|
||||
case 0x5e:
|
||||
/* Skylake. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE;
|
||||
break;
|
||||
case 0x55:
|
||||
/* Skylake with AVX-512 support. */
|
||||
__cpu_model.__cpu_type = INTEL_COREI7;
|
||||
__cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x1d:
|
||||
/* Penryn. */
|
||||
case 0x0f:
|
||||
/* Merom. */
|
||||
__cpu_model.__cpu_type = INTEL_CORE2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We have no idea. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is
|
||||
the max possible level of CPUID insn. */
|
||||
static void
|
||||
get_available_features (unsigned int ecx, unsigned int edx,
|
||||
int max_cpuid_level)
|
||||
{
|
||||
unsigned int eax, ebx;
|
||||
unsigned int ext_level;
|
||||
|
||||
unsigned int features = 0;
|
||||
|
||||
if (edx & bit_CMOV)
|
||||
features |= (1 << FEATURE_CMOV);
|
||||
if (edx & bit_MMX)
|
||||
features |= (1 << FEATURE_MMX);
|
||||
if (edx & bit_SSE)
|
||||
features |= (1 << FEATURE_SSE);
|
||||
if (edx & bit_SSE2)
|
||||
features |= (1 << FEATURE_SSE2);
|
||||
if (ecx & bit_POPCNT)
|
||||
features |= (1 << FEATURE_POPCNT);
|
||||
if (ecx & bit_AES)
|
||||
features |= (1 << FEATURE_AES);
|
||||
if (ecx & bit_PCLMUL)
|
||||
features |= (1 << FEATURE_PCLMUL);
|
||||
if (ecx & bit_SSE3)
|
||||
features |= (1 << FEATURE_SSE3);
|
||||
if (ecx & bit_SSSE3)
|
||||
features |= (1 << FEATURE_SSSE3);
|
||||
if (ecx & bit_SSE4_1)
|
||||
features |= (1 << FEATURE_SSE4_1);
|
||||
if (ecx & bit_SSE4_2)
|
||||
features |= (1 << FEATURE_SSE4_2);
|
||||
if (ecx & bit_AVX)
|
||||
features |= (1 << FEATURE_AVX);
|
||||
if (ecx & bit_FMA)
|
||||
features |= (1 << FEATURE_FMA);
|
||||
|
||||
/* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
|
||||
if (max_cpuid_level >= 7)
|
||||
{
|
||||
__cpuid_count (7, 0, eax, ebx, ecx, edx);
|
||||
if (ebx & bit_BMI)
|
||||
features |= (1 << FEATURE_BMI);
|
||||
if (ebx & bit_AVX2)
|
||||
features |= (1 << FEATURE_AVX2);
|
||||
if (ebx & bit_BMI2)
|
||||
features |= (1 << FEATURE_BMI2);
|
||||
if (ebx & bit_AVX512F)
|
||||
features |= (1 << FEATURE_AVX512F);
|
||||
if (ebx & bit_AVX512VL)
|
||||
features |= (1 << FEATURE_AVX512VL);
|
||||
if (ebx & bit_AVX512BW)
|
||||
features |= (1 << FEATURE_AVX512BW);
|
||||
if (ebx & bit_AVX512DQ)
|
||||
features |= (1 << FEATURE_AVX512DQ);
|
||||
if (ebx & bit_AVX512CD)
|
||||
features |= (1 << FEATURE_AVX512CD);
|
||||
if (ebx & bit_AVX512PF)
|
||||
features |= (1 << FEATURE_AVX512PF);
|
||||
if (ebx & bit_AVX512ER)
|
||||
features |= (1 << FEATURE_AVX512ER);
|
||||
if (ebx & bit_AVX512IFMA)
|
||||
features |= (1 << FEATURE_AVX512IFMA);
|
||||
if (ecx & bit_AVX512VBMI)
|
||||
features |= (1 << FEATURE_AVX512VBMI);
|
||||
if (ecx & bit_AVX512VPOPCNTDQ)
|
||||
features |= (1 << FEATURE_AVX512VPOPCNTDQ);
|
||||
if (edx & bit_AVX5124VNNIW)
|
||||
features |= (1 << FEATURE_AVX5124VNNIW);
|
||||
if (edx & bit_AVX5124FMAPS)
|
||||
features |= (1 << FEATURE_AVX5124FMAPS);
|
||||
}
|
||||
|
||||
/* Check cpuid level of extended features. */
|
||||
__cpuid (0x80000000, ext_level, ebx, ecx, edx);
|
||||
|
||||
if (ext_level >= 0x80000001)
|
||||
{
|
||||
__cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
|
||||
if (ecx & bit_SSE4a)
|
||||
features |= (1 << FEATURE_SSE4_A);
|
||||
if (ecx & bit_FMA4)
|
||||
features |= (1 << FEATURE_FMA4);
|
||||
if (ecx & bit_XOP)
|
||||
features |= (1 << FEATURE_XOP);
|
||||
}
|
||||
|
||||
__cpu_model.__cpu_features[0] = features;
|
||||
}
|
||||
|
||||
/* A constructor function that is sets __cpu_model and __cpu_features with
|
||||
the right values. This needs to run only once. This constructor is
|
||||
given the highest priority and it should run before constructors without
|
||||
the priority set. However, it still runs after ifunc initializers and
|
||||
needs to be called explicitly there. */
|
||||
|
||||
int __attribute__ ((constructor CONSTRUCTOR_PRIORITY))
|
||||
__cpu_indicator_init (void)
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
int max_level;
|
||||
unsigned int vendor;
|
||||
unsigned int model, family, brand_id;
|
||||
unsigned int extended_model, extended_family;
|
||||
|
||||
/* This function needs to run just once. */
|
||||
if (__cpu_model.__cpu_vendor)
|
||||
return 0;
|
||||
|
||||
/* Assume cpuid insn present. Run in level 0 to get vendor id. */
|
||||
if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
|
||||
{
|
||||
__cpu_model.__cpu_vendor = VENDOR_OTHER;
|
||||
return -1;
|
||||
}
|
||||
|
||||
vendor = ebx;
|
||||
max_level = eax;
|
||||
|
||||
if (max_level < 1)
|
||||
{
|
||||
__cpu_model.__cpu_vendor = VENDOR_OTHER;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
|
||||
{
|
||||
__cpu_model.__cpu_vendor = VENDOR_OTHER;
|
||||
return -1;
|
||||
}
|
||||
|
||||
model = (eax >> 4) & 0x0f;
|
||||
family = (eax >> 8) & 0x0f;
|
||||
brand_id = ebx & 0xff;
|
||||
extended_model = (eax >> 12) & 0xf0;
|
||||
extended_family = (eax >> 20) & 0xff;
|
||||
|
||||
if (vendor == signature_INTEL_ebx)
|
||||
{
|
||||
/* Adjust model and family for Intel CPUS. */
|
||||
if (family == 0x0f)
|
||||
{
|
||||
family += extended_family;
|
||||
model += extended_model;
|
||||
}
|
||||
else if (family == 0x06)
|
||||
model += extended_model;
|
||||
|
||||
/* Get CPU type. */
|
||||
get_intel_cpu (family, model, brand_id);
|
||||
/* Find available features. */
|
||||
get_available_features (ecx, edx, max_level);
|
||||
__cpu_model.__cpu_vendor = VENDOR_INTEL;
|
||||
}
|
||||
else if (vendor == signature_AMD_ebx)
|
||||
{
|
||||
/* Adjust model and family for AMD CPUS. */
|
||||
if (family == 0x0f)
|
||||
{
|
||||
family += extended_family;
|
||||
model += extended_model;
|
||||
}
|
||||
|
||||
/* Get CPU type. */
|
||||
get_amd_cpu (family, model);
|
||||
/* Find available features. */
|
||||
get_available_features (ecx, edx, max_level);
|
||||
__cpu_model.__cpu_vendor = VENDOR_AMD;
|
||||
}
|
||||
else
|
||||
__cpu_model.__cpu_vendor = VENDOR_OTHER;
|
||||
|
||||
gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX);
|
||||
gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX);
|
||||
gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined SHARED && defined USE_ELF_SYMVER
|
||||
__asm__ (".symver __cpu_indicator_init, __cpu_indicator_init@GCC_4.8.0");
|
||||
__asm__ (".symver __cpu_model, __cpu_model@GCC_4.8.0");
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/* Get CPU type and Features for x86 processors.
|
||||
Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
Contributed by Sriraman Tallam (tmsriram@google.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Processor Vendor and Models. */
|
||||
|
||||
enum processor_vendor
|
||||
{
|
||||
VENDOR_INTEL = 1,
|
||||
VENDOR_AMD,
|
||||
VENDOR_OTHER,
|
||||
VENDOR_MAX
|
||||
};
|
||||
|
||||
/* Any new types or subtypes have to be inserted at the end. */
|
||||
|
||||
enum processor_types
|
||||
{
|
||||
INTEL_BONNELL = 1,
|
||||
INTEL_CORE2,
|
||||
INTEL_COREI7,
|
||||
AMDFAM10H,
|
||||
AMDFAM15H,
|
||||
INTEL_SILVERMONT,
|
||||
INTEL_KNL,
|
||||
AMD_BTVER1,
|
||||
AMD_BTVER2,
|
||||
AMDFAM17H,
|
||||
CPU_TYPE_MAX
|
||||
};
|
||||
|
||||
enum processor_subtypes
|
||||
{
|
||||
INTEL_COREI7_NEHALEM = 1,
|
||||
INTEL_COREI7_WESTMERE,
|
||||
INTEL_COREI7_SANDYBRIDGE,
|
||||
AMDFAM10H_BARCELONA,
|
||||
AMDFAM10H_SHANGHAI,
|
||||
AMDFAM10H_ISTANBUL,
|
||||
AMDFAM15H_BDVER1,
|
||||
AMDFAM15H_BDVER2,
|
||||
AMDFAM15H_BDVER3,
|
||||
AMDFAM15H_BDVER4,
|
||||
AMDFAM17H_ZNVER1,
|
||||
INTEL_COREI7_IVYBRIDGE,
|
||||
INTEL_COREI7_HASWELL,
|
||||
INTEL_COREI7_BROADWELL,
|
||||
INTEL_COREI7_SKYLAKE,
|
||||
INTEL_COREI7_SKYLAKE_AVX512,
|
||||
CPU_SUBTYPE_MAX
|
||||
};
|
||||
|
||||
/* ISA Features supported. New features have to be inserted at the end. */
|
||||
|
||||
enum processor_features
|
||||
{
|
||||
FEATURE_CMOV = 0,
|
||||
FEATURE_MMX,
|
||||
FEATURE_POPCNT,
|
||||
FEATURE_SSE,
|
||||
FEATURE_SSE2,
|
||||
FEATURE_SSE3,
|
||||
FEATURE_SSSE3,
|
||||
FEATURE_SSE4_1,
|
||||
FEATURE_SSE4_2,
|
||||
FEATURE_AVX,
|
||||
FEATURE_AVX2,
|
||||
FEATURE_SSE4_A,
|
||||
FEATURE_FMA4,
|
||||
FEATURE_XOP,
|
||||
FEATURE_FMA,
|
||||
FEATURE_AVX512F,
|
||||
FEATURE_BMI,
|
||||
FEATURE_BMI2,
|
||||
FEATURE_AES,
|
||||
FEATURE_PCLMUL,
|
||||
FEATURE_AVX512VL,
|
||||
FEATURE_AVX512BW,
|
||||
FEATURE_AVX512DQ,
|
||||
FEATURE_AVX512CD,
|
||||
FEATURE_AVX512ER,
|
||||
FEATURE_AVX512PF,
|
||||
FEATURE_AVX512VBMI,
|
||||
FEATURE_AVX512IFMA,
|
||||
FEATURE_AVX5124VNNIW,
|
||||
FEATURE_AVX5124FMAPS,
|
||||
FEATURE_AVX512VPOPCNTDQ
|
||||
};
|
||||
|
||||
extern struct __processor_model
|
||||
{
|
||||
unsigned int __cpu_vendor;
|
||||
unsigned int __cpu_type;
|
||||
unsigned int __cpu_subtype;
|
||||
unsigned int __cpu_features[1];
|
||||
} __cpu_model;
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2017 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 3, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* Under Section 7 of GPL version 3, you are granted additional
|
||||
* permissions described in the GCC Runtime Library Exception, version
|
||||
* 3.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License and
|
||||
* a copy of the GCC Runtime Library Exception along with this program;
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */
|
||||
#define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */
|
||||
|
||||
#ifndef __x86_64__
|
||||
/* All 64-bit targets have SSE and DAZ;
|
||||
only check them explicitly for 32-bit ones. */
|
||||
#include "cpuid.h"
|
||||
|
||||
__attribute__ ((target("fxsr,sse")))
|
||||
static void
|
||||
/* The i386 ABI only requires 4-byte stack alignment, so this is necessary
|
||||
to make sure the fxsave struct gets correct alignment.
|
||||
See PR27537 and PR28621. */
|
||||
__attribute__ ((force_align_arg_pointer))
|
||||
set_fast_math_sse (unsigned int edx)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
|
||||
if (edx & bit_FXSAVE)
|
||||
{
|
||||
/* Check if DAZ is available. */
|
||||
struct
|
||||
{
|
||||
unsigned short cwd;
|
||||
unsigned short swd;
|
||||
unsigned short twd;
|
||||
unsigned short fop;
|
||||
unsigned int fip;
|
||||
unsigned int fcs;
|
||||
unsigned int foo;
|
||||
unsigned int fos;
|
||||
unsigned int mxcsr;
|
||||
unsigned int mxcsr_mask;
|
||||
unsigned int st_space[32];
|
||||
unsigned int xmm_space[32];
|
||||
unsigned int padding[56];
|
||||
} __attribute__ ((aligned (16))) fxsave;
|
||||
|
||||
/* This is necessary since some implementations of FXSAVE
|
||||
do not modify reserved areas within the image. */
|
||||
fxsave.mxcsr_mask = 0;
|
||||
|
||||
__builtin_ia32_fxsave (&fxsave);
|
||||
|
||||
mxcsr = fxsave.mxcsr;
|
||||
|
||||
if (fxsave.mxcsr_mask & MXCSR_DAZ)
|
||||
mxcsr |= MXCSR_DAZ;
|
||||
}
|
||||
else
|
||||
mxcsr = __builtin_ia32_stmxcsr ();
|
||||
|
||||
mxcsr |= MXCSR_FTZ;
|
||||
__builtin_ia32_ldmxcsr (mxcsr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __attribute__((constructor))
|
||||
set_fast_math (void)
|
||||
{
|
||||
#ifndef __x86_64__
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
|
||||
return;
|
||||
|
||||
if (edx & bit_SSE)
|
||||
set_fast_math_sse (edx);
|
||||
#else
|
||||
unsigned int mxcsr = __builtin_ia32_stmxcsr ();
|
||||
mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
|
||||
__builtin_ia32_ldmxcsr (mxcsr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/* crti.S for x86.
|
||||
|
||||
Copyright (C) 1993-2017 Free Software Foundation, Inc.
|
||||
Written By Fred Fish, Nov 1992
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This file just supplies labeled starting points for the .init and .fini
|
||||
sections. It is linked in before the values-Xx.o files and also before
|
||||
crtbegin.o. */
|
||||
|
||||
.ident "GNU C crti.s"
|
||||
|
||||
.section .init
|
||||
.globl _init
|
||||
.type _init,@function
|
||||
_init:
|
||||
|
||||
.section .fini
|
||||
.globl _fini
|
||||
.type _fini,@function
|
||||
_fini:
|
|
@ -0,0 +1,35 @@
|
|||
/* crtn.S for x86.
|
||||
|
||||
Copyright (C) 1993-2017 Free Software Foundation, Inc.
|
||||
Written By Fred Fish, Nov 1992
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This file just supplies returns for the .init and .fini sections. It is
|
||||
linked in after all other files. */
|
||||
|
||||
.ident "GNU C crtn.o"
|
||||
|
||||
.section .init
|
||||
ret $0x0
|
||||
|
||||
.section .fini
|
||||
ret $0x0
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 3, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* Under Section 7 of GPL version 3, you are granted additional
|
||||
* permissions described in the GCC Runtime Library Exception, version
|
||||
* 3.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License and
|
||||
* a copy of the GCC Runtime Library Exception along with this program;
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#if __PREC == 32
|
||||
#define X87CW (0 << 8) /* Single precision (24 bits) */
|
||||
#elif __PREC == 64
|
||||
#define X87CW (2 << 8) /* Double precision (53 bits) */
|
||||
#elif __PREC == 80
|
||||
#define X87CW (3 << 8) /* Extended precision (64 bits) */
|
||||
#else
|
||||
#error "Wrong precision requested."
|
||||
#endif
|
||||
|
||||
#define X87CW_PCMASK (3 << 8)
|
||||
|
||||
static void __attribute__((constructor))
|
||||
set_precision (void)
|
||||
{
|
||||
unsigned short int cwd;
|
||||
|
||||
asm volatile ("fstcw\t%0" : "=m" (cwd));
|
||||
|
||||
cwd &= ~X87CW_PCMASK;
|
||||
cwd |= X87CW;
|
||||
|
||||
asm volatile ("fldcw\t%0" : : "m" (cwd));
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,161 @@
|
|||
/* crtbegin object for windows32 targets.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Target machine header files require this define. */
|
||||
#define IN_LIBGCC2
|
||||
|
||||
#include "auto-host.h"
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "libgcc_tm.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef LIBGCC_SONAME
|
||||
#define LIBGCC_SONAME "libgcc_s.dll"
|
||||
#endif
|
||||
|
||||
#if DWARF2_UNWIND_INFO
|
||||
/* Make the declarations weak. This is critical for
|
||||
_Jv_RegisterClasses because it lives in libgcj.a */
|
||||
extern void __register_frame_info (__attribute__((unused)) const void *,
|
||||
__attribute__((unused)) struct object *)
|
||||
TARGET_ATTRIBUTE_WEAK;
|
||||
extern void *__deregister_frame_info (__attribute__((unused)) const void *)
|
||||
TARGET_ATTRIBUTE_WEAK;
|
||||
|
||||
/* Work around for current cygwin32 build problems (Bug gas/16858).
|
||||
Compile weak default functions only for 64-bit systems,
|
||||
when absolutely necessary. */
|
||||
#ifdef __x86_64__
|
||||
TARGET_ATTRIBUTE_WEAK void
|
||||
__register_frame_info (__attribute__((unused)) const void *p,
|
||||
__attribute__((unused)) struct object *o)
|
||||
{
|
||||
}
|
||||
|
||||
TARGET_ATTRIBUTE_WEAK void *
|
||||
__deregister_frame_info (__attribute__((unused)) const void *p)
|
||||
{
|
||||
return (void*) 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* DWARF2_UNWIND_INFO */
|
||||
|
||||
#if defined(HAVE_LD_RO_RW_SECTION_MIXING)
|
||||
# define EH_FRAME_SECTION_CONST const
|
||||
#else
|
||||
# define EH_FRAME_SECTION_CONST
|
||||
#endif
|
||||
|
||||
/* Stick a label at the beginning of the frame unwind info so we can
|
||||
register/deregister it with the exception handling library code. */
|
||||
#if DWARF2_UNWIND_INFO
|
||||
static EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
|
||||
__attribute__((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
|
||||
= { };
|
||||
|
||||
static struct object obj;
|
||||
|
||||
/* Handle of libgcc's DLL reference. */
|
||||
HANDLE hmod_libgcc;
|
||||
static void * (*deregister_frame_fn) (const void *) = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* Declare the __dso_handle variable. It should have a unique value
|
||||
in every shared-object; in a main program its value is zero. The
|
||||
object should in any case be protected. This means the instance
|
||||
in one DSO or the main program is not used in another object. The
|
||||
dynamic linker takes care of this. */
|
||||
|
||||
#ifdef CRTSTUFFS_O
|
||||
extern void *__ImageBase;
|
||||
void *__dso_handle = &__ImageBase;
|
||||
#else
|
||||
void *__dso_handle = 0;
|
||||
#endif
|
||||
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
|
||||
/* Pull in references from libgcc.a(unwind-dw2-fde.o) in the
|
||||
startfile. These are referenced by a ctor and dtor in crtend.o. */
|
||||
extern void __gcc_register_frame (void);
|
||||
extern void __gcc_deregister_frame (void);
|
||||
|
||||
void
|
||||
__gcc_register_frame (void)
|
||||
{
|
||||
#if DWARF2_UNWIND_INFO
|
||||
/* Weak undefined symbols won't be pulled in from dlls; hence
|
||||
we first test if the dll is already loaded and, if so,
|
||||
get the symbol's address at run-time. If the dll is not loaded,
|
||||
fallback to weak linkage to static archive. */
|
||||
|
||||
void (*register_frame_fn) (const void *, struct object *);
|
||||
HANDLE h = GetModuleHandle (LIBGCC_SONAME);
|
||||
|
||||
if (h)
|
||||
{
|
||||
/* Increasing the load-count of LIBGCC_SONAME DLL. */
|
||||
hmod_libgcc = LoadLibrary (LIBGCC_SONAME);
|
||||
register_frame_fn = (void (*) (const void *, struct object *))
|
||||
GetProcAddress (h, "__register_frame_info");
|
||||
deregister_frame_fn = (void* (*) (const void *))
|
||||
GetProcAddress (h, "__deregister_frame_info");
|
||||
}
|
||||
else
|
||||
{
|
||||
register_frame_fn = __register_frame_info;
|
||||
deregister_frame_fn = __deregister_frame_info;
|
||||
}
|
||||
if (register_frame_fn)
|
||||
register_frame_fn (__EH_FRAME_BEGIN__, &obj);
|
||||
#endif
|
||||
|
||||
#if DEFAULT_USE_CXA_ATEXIT
|
||||
/* If we use the __cxa_atexit method to register C++ dtors
|
||||
at object construction, also use atexit to register eh frame
|
||||
info cleanup. */
|
||||
atexit(__gcc_deregister_frame);
|
||||
#endif /* DEFAULT_USE_CXA_ATEXIT */
|
||||
}
|
||||
|
||||
void
|
||||
__gcc_deregister_frame (void)
|
||||
{
|
||||
#if DWARF2_UNWIND_INFO
|
||||
if (deregister_frame_fn)
|
||||
deregister_frame_fn (__EH_FRAME_BEGIN__);
|
||||
if (hmod_libgcc)
|
||||
FreeLibrary (hmod_libgcc);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* crtend object for windows32 targets.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Target machine header files require this define. */
|
||||
#define IN_LIBGCC2
|
||||
|
||||
/* auto-host.h is needed by cygming.h for HAVE_GAS_WEAK and here
|
||||
for HAVE_LD_RO_RW_SECTION_MIXING. */
|
||||
#include "auto-host.h"
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "libgcc_tm.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
|
||||
#if defined(HAVE_LD_RO_RW_SECTION_MIXING)
|
||||
# define EH_FRAME_SECTION_CONST const
|
||||
#else
|
||||
# define EH_FRAME_SECTION_CONST
|
||||
#endif
|
||||
|
||||
#if DWARF2_UNWIND_INFO
|
||||
/* Terminate the frame unwind info section with a 0 as a sentinel;
|
||||
this would be the 'length' field in a real FDE. */
|
||||
|
||||
static EH_FRAME_SECTION_CONST int __FRAME_END__[]
|
||||
__attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__),
|
||||
aligned(4)))
|
||||
= { 0 };
|
||||
#endif
|
||||
|
||||
extern void __gcc_register_frame (void);
|
||||
extern void __gcc_deregister_frame (void);
|
||||
|
||||
static void register_frame_ctor (void) __attribute__ ((constructor (0)));
|
||||
|
||||
static void
|
||||
register_frame_ctor (void)
|
||||
{
|
||||
__gcc_register_frame ();
|
||||
}
|
||||
|
||||
#if !DEFAULT_USE_CXA_ATEXIT
|
||||
static void deregister_frame_dtor (void) __attribute__ ((destructor (0)));
|
||||
|
||||
static void
|
||||
deregister_frame_dtor (void)
|
||||
{
|
||||
__gcc_deregister_frame ();
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,187 @@
|
|||
/* stuff needed for libgcc on win32.
|
||||
*
|
||||
* Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
* Written By Steve Chamberlain
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 3, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* Under Section 7 of GPL version 3, you are granted additional
|
||||
* permissions described in the GCC Runtime Library Exception, version
|
||||
* 3.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License and
|
||||
* a copy of the GCC Runtime Library Exception along with this program;
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "auto-host.h"
|
||||
|
||||
#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
|
||||
.cfi_sections .debug_frame
|
||||
# define cfi_startproc() .cfi_startproc
|
||||
# define cfi_endproc() .cfi_endproc
|
||||
# define cfi_adjust_cfa_offset(X) .cfi_adjust_cfa_offset X
|
||||
# define cfi_def_cfa_register(X) .cfi_def_cfa_register X
|
||||
# define cfi_register(D,S) .cfi_register D, S
|
||||
# ifdef __x86_64__
|
||||
# define cfi_push(X) .cfi_adjust_cfa_offset 8; .cfi_rel_offset X, 0
|
||||
# define cfi_pop(X) .cfi_adjust_cfa_offset -8; .cfi_restore X
|
||||
# else
|
||||
# define cfi_push(X) .cfi_adjust_cfa_offset 4; .cfi_rel_offset X, 0
|
||||
# define cfi_pop(X) .cfi_adjust_cfa_offset -4; .cfi_restore X
|
||||
# endif
|
||||
#else
|
||||
# define cfi_startproc()
|
||||
# define cfi_endproc()
|
||||
# define cfi_adjust_cfa_offset(X)
|
||||
# define cfi_def_cfa_register(X)
|
||||
# define cfi_register(D,S)
|
||||
# define cfi_push(X)
|
||||
# define cfi_pop(X)
|
||||
#endif /* HAVE_GAS_CFI_SECTIONS_DIRECTIVE */
|
||||
|
||||
#ifdef L_chkstk
|
||||
/* Function prologue calls __chkstk to probe the stack when allocating more
|
||||
than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K
|
||||
increments is necessary to ensure that the guard pages used
|
||||
by the OS virtual memory manger are allocated in correct sequence. */
|
||||
|
||||
.global ___chkstk
|
||||
.global __alloca
|
||||
#ifdef __x86_64__
|
||||
/* __alloca is a normal function call, which uses %rcx as the argument. */
|
||||
cfi_startproc()
|
||||
__alloca:
|
||||
movq %rcx, %rax
|
||||
/* FALLTHRU */
|
||||
|
||||
/* ___chkstk is a *special* function call, which uses %rax as the argument.
|
||||
We avoid clobbering the 4 integer argument registers, %rcx, %rdx,
|
||||
%r8 and %r9, which leaves us with %rax, %r10, and %r11 to use. */
|
||||
.align 4
|
||||
___chkstk:
|
||||
popq %r11 /* pop return address */
|
||||
cfi_adjust_cfa_offset(-8) /* indicate return address in r11 */
|
||||
cfi_register(%rip, %r11)
|
||||
movq %rsp, %r10
|
||||
cmpq $0x1000, %rax /* > 4k ?*/
|
||||
jb 2f
|
||||
|
||||
1: subq $0x1000, %r10 /* yes, move pointer down 4k*/
|
||||
orl $0x0, (%r10) /* probe there */
|
||||
subq $0x1000, %rax /* decrement count */
|
||||
cmpq $0x1000, %rax
|
||||
ja 1b /* and do it again */
|
||||
|
||||
2: subq %rax, %r10
|
||||
movq %rsp, %rax /* hold CFA until return */
|
||||
cfi_def_cfa_register(%rax)
|
||||
orl $0x0, (%r10) /* less than 4k, just peek here */
|
||||
movq %r10, %rsp /* decrement stack */
|
||||
|
||||
/* Push the return value back. Doing this instead of just
|
||||
jumping to %r11 preserves the cached call-return stack
|
||||
used by most modern processors. */
|
||||
pushq %r11
|
||||
ret
|
||||
cfi_endproc()
|
||||
#else
|
||||
cfi_startproc()
|
||||
___chkstk:
|
||||
__alloca:
|
||||
pushl %ecx /* save temp */
|
||||
cfi_push(%eax)
|
||||
leal 8(%esp), %ecx /* point past return addr */
|
||||
cmpl $0x1000, %eax /* > 4k ?*/
|
||||
jb 2f
|
||||
|
||||
1: subl $0x1000, %ecx /* yes, move pointer down 4k*/
|
||||
orl $0x0, (%ecx) /* probe there */
|
||||
subl $0x1000, %eax /* decrement count */
|
||||
cmpl $0x1000, %eax
|
||||
ja 1b /* and do it again */
|
||||
|
||||
2: subl %eax, %ecx
|
||||
orl $0x0, (%ecx) /* less than 4k, just peek here */
|
||||
movl %esp, %eax /* save current stack pointer */
|
||||
cfi_def_cfa_register(%eax)
|
||||
movl %ecx, %esp /* decrement stack */
|
||||
movl (%eax), %ecx /* recover saved temp */
|
||||
|
||||
/* Copy the return register. Doing this instead of just jumping to
|
||||
the address preserves the cached call-return stack used by most
|
||||
modern processors. */
|
||||
pushl 4(%eax)
|
||||
ret
|
||||
cfi_endproc()
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* L_chkstk */
|
||||
|
||||
#ifdef L_chkstk_ms
|
||||
/* ___chkstk_ms is a *special* function call, which uses %rax as the argument.
|
||||
We avoid clobbering any registers. Unlike ___chkstk, it just probes the
|
||||
stack and does no stack allocation. */
|
||||
.global ___chkstk_ms
|
||||
#ifdef __x86_64__
|
||||
cfi_startproc()
|
||||
___chkstk_ms:
|
||||
pushq %rcx /* save temps */
|
||||
cfi_push(%rcx)
|
||||
pushq %rax
|
||||
cfi_push(%rax)
|
||||
cmpq $0x1000, %rax /* > 4k ?*/
|
||||
leaq 24(%rsp), %rcx /* point past return addr */
|
||||
jb 2f
|
||||
|
||||
1: subq $0x1000, %rcx /* yes, move pointer down 4k */
|
||||
orq $0x0, (%rcx) /* probe there */
|
||||
subq $0x1000, %rax /* decrement count */
|
||||
cmpq $0x1000, %rax
|
||||
ja 1b /* and do it again */
|
||||
|
||||
2: subq %rax, %rcx
|
||||
orq $0x0, (%rcx) /* less than 4k, just peek here */
|
||||
|
||||
popq %rax
|
||||
cfi_pop(%rax)
|
||||
popq %rcx
|
||||
cfi_pop(%rcx)
|
||||
ret
|
||||
cfi_endproc()
|
||||
#else
|
||||
cfi_startproc()
|
||||
___chkstk_ms:
|
||||
pushl %ecx /* save temp */
|
||||
cfi_push(%ecx)
|
||||
pushl %eax
|
||||
cfi_push(%eax)
|
||||
cmpl $0x1000, %eax /* > 4k ?*/
|
||||
leal 12(%esp), %ecx /* point past return addr */
|
||||
jb 2f
|
||||
|
||||
1: subl $0x1000, %ecx /* yes, move pointer down 4k*/
|
||||
orl $0x0, (%ecx) /* probe there */
|
||||
subl $0x1000, %eax /* decrement count */
|
||||
cmpl $0x1000, %eax
|
||||
ja 1b /* and do it again */
|
||||
|
||||
2: subl %eax, %ecx
|
||||
orl $0x0, (%ecx) /* less than 4k, just peek here */
|
||||
|
||||
popl %eax
|
||||
cfi_pop(%eax)
|
||||
popl %ecx
|
||||
cfi_pop(%ecx)
|
||||
ret
|
||||
cfi_endproc()
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* L_chkstk_ms */
|
|
@ -0,0 +1,32 @@
|
|||
/* Target definitions for x86 running Darwin, library renames.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The system ___divdc3 routine in libSystem on darwin10 is not
|
||||
accurate to 1ulp, ours is, so we avoid ever using the system name
|
||||
for this routine and instead install a non-conflicting name that is
|
||||
accurate. See darwin_rename_builtins. */
|
||||
#ifdef L_divdc3
|
||||
#define DECLARE_LIBRARY_RENAMES \
|
||||
asm(".text; ___divdc3: jmp ___ieee_divdc3 ; .globl ___divdc3");
|
||||
#endif
|
|
@ -0,0 +1,180 @@
|
|||
/* DWARF2 EH unwinding support for DragonFly BSD: AMD x86-64 and x86.
|
||||
Copyright (C) 2014-2017 Free Software Foundation, Inc.
|
||||
Contributed by John Marino <gnugcc@marino.st>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/sigframe.h>
|
||||
|
||||
|
||||
#define REG_NAME(reg) sf_uc.uc_mcontext.mc_## reg
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_dragonfly_fallback_frame_state
|
||||
|
||||
|
||||
static void
|
||||
x86_64_sigtramp_range (unsigned char **start, unsigned char **end)
|
||||
{
|
||||
unsigned long ps_strings;
|
||||
int mib[2];
|
||||
size_t len;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PS_STRINGS;
|
||||
len = sizeof (ps_strings);
|
||||
sysctl (mib, 2, &ps_strings, &len, NULL, 0);
|
||||
|
||||
*start = (unsigned char *)ps_strings - 32;
|
||||
*end = (unsigned char *)ps_strings;
|
||||
}
|
||||
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_64_dragonfly_fallback_frame_state
|
||||
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
unsigned char *sigtramp_start, *sigtramp_end;
|
||||
struct sigframe *sf;
|
||||
long new_cfa;
|
||||
|
||||
x86_64_sigtramp_range(&sigtramp_start, &sigtramp_end);
|
||||
if (pc >= sigtramp_end || pc < sigtramp_start)
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
sf = (struct sigframe *) context->cfa;
|
||||
new_cfa = sf->REG_NAME(rsp);
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
/* Register 7 is rsp */
|
||||
fs->regs.cfa_reg = 7;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(rax) - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(rdx) - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(rcx) - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(rbx) - new_cfa;
|
||||
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[4].loc.offset = (long)&sf->REG_NAME(rsi) - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(rdi) - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(rbp) - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(r8) - new_cfa;
|
||||
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[9].loc.offset = (long)&sf->REG_NAME(r9) - new_cfa;
|
||||
fs->regs.reg[10].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[10].loc.offset = (long)&sf->REG_NAME(r10) - new_cfa;
|
||||
fs->regs.reg[11].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[11].loc.offset = (long)&sf->REG_NAME(r11) - new_cfa;
|
||||
fs->regs.reg[12].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[12].loc.offset = (long)&sf->REG_NAME(r12) - new_cfa;
|
||||
fs->regs.reg[13].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[13].loc.offset = (long)&sf->REG_NAME(r13) - new_cfa;
|
||||
fs->regs.reg[14].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[14].loc.offset = (long)&sf->REG_NAME(r14) - new_cfa;
|
||||
fs->regs.reg[15].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[15].loc.offset = (long)&sf->REG_NAME(r15) - new_cfa;
|
||||
fs->regs.reg[16].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[16].loc.offset = (long)&sf->REG_NAME(rip) - new_cfa;
|
||||
fs->retaddr_column = 16;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#else /* Next section is for i386 */
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_dragonfly_fallback_frame_state
|
||||
|
||||
|
||||
static void
|
||||
x86_sigtramp_range (unsigned char **start, unsigned char **end)
|
||||
{
|
||||
unsigned long ps_strings;
|
||||
int mib[2];
|
||||
size_t len;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PS_STRINGS;
|
||||
len = sizeof (ps_strings);
|
||||
sysctl (mib, 2, &ps_strings, &len, NULL, 0);
|
||||
|
||||
*start = (unsigned char *)ps_strings - 128;
|
||||
*end = (unsigned char *)ps_strings;
|
||||
}
|
||||
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_dragonfly_fallback_frame_state
|
||||
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
unsigned char *sigtramp_start, *sigtramp_end;
|
||||
struct sigframe *sf;
|
||||
long new_cfa;
|
||||
|
||||
x86_sigtramp_range(&sigtramp_start, &sigtramp_end);
|
||||
|
||||
if (pc >= sigtramp_end || pc < sigtramp_start)
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
sf = (struct sigframe *) context->cfa;
|
||||
new_cfa = sf->REG_NAME(esp);
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = 4;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(eax) - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(ebx) - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(ecx) - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(edx) - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(esi) - new_cfa;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&sf->REG_NAME(edi) - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(ebp) - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(eip) - new_cfa;
|
||||
fs->retaddr_column = 8;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
#endif /* ifdef __x86_64__ */
|
|
@ -0,0 +1,36 @@
|
|||
/* Definitions for Intel 386 ELF systems.
|
||||
Copyright (C) 2015-2017 Free Software Foundation, Inc.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef __i386__
|
||||
/* Used by crtstuff.c to initialize the base of data-relative relocations.
|
||||
These are GOT relative on x86, so return the pic register. */
|
||||
#define CRT_GET_RFIB_DATA(BASE) \
|
||||
__asm__ ("call\t.LPR%=\n" \
|
||||
".LPR%=:\n\t" \
|
||||
"pop{l}\t%0\n\t" \
|
||||
/* Due to a GAS bug, this cannot use EAX. That encodes \
|
||||
smaller than the traditional EBX, which results in the \
|
||||
offset being off by one. */ \
|
||||
"add{l}\t{$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0" \
|
||||
"|%0,_GLOBAL_OFFSET_TABLE_+(.-.LPR%=)}" \
|
||||
: "=d"(BASE))
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/* Implement __enable_execute_stack for Windows32.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
extern void __enable_execute_stack (void *);
|
||||
|
||||
void
|
||||
__enable_execute_stack (void *addr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION b;
|
||||
|
||||
if (!VirtualQuery (addr, &b, sizeof(b)))
|
||||
abort ();
|
||||
VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,
|
||||
&b.Protect);
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/* DWARF2 EH unwinding support for FreeBSD: AMD x86-64 and x86.
|
||||
Copyright (C) 2015-2017 Free Software Foundation, Inc.
|
||||
Contributed by John Marino <gnugcc@marino.st>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/sigframe.h>
|
||||
|
||||
#define REG_NAME(reg) sf_uc.uc_mcontext.mc_## reg
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_freebsd_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_64_freebsd_fallback_frame_state
|
||||
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
struct sigframe *sf;
|
||||
long new_cfa;
|
||||
|
||||
/* Prior to FreeBSD 9, the signal trampoline was located immediately
|
||||
before the ps_strings. To support non-executable stacks on AMD64,
|
||||
the sigtramp was moved to a shared page for FreeBSD 9. Unfortunately
|
||||
this means looking frame patterns again (sys/amd64/amd64/sigtramp.S)
|
||||
rather than using the robust and convenient KERN_PS_STRINGS trick.
|
||||
|
||||
<pc + 00>: lea 0x10(%rsp),%rdi
|
||||
<pc + 05>: pushq $0x0
|
||||
<pc + 17>: mov $0x1a1,%rax
|
||||
<pc + 14>: syscall
|
||||
|
||||
If we can't find this pattern, we're at the end of the stack.
|
||||
*/
|
||||
|
||||
if (!( *(unsigned int *)(context->ra) == 0x247c8d48
|
||||
&& *(unsigned int *)(context->ra + 4) == 0x48006a10
|
||||
&& *(unsigned int *)(context->ra + 8) == 0x01a1c0c7
|
||||
&& *(unsigned int *)(context->ra + 12) == 0x050f0000 ))
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
sf = (struct sigframe *) context->cfa;
|
||||
new_cfa = sf->REG_NAME(rsp);
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
/* Register 7 is rsp */
|
||||
fs->regs.cfa_reg = 7;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(rax) - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(rdx) - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(rcx) - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(rbx) - new_cfa;
|
||||
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[4].loc.offset = (long)&sf->REG_NAME(rsi) - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(rdi) - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(rbp) - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(r8) - new_cfa;
|
||||
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[9].loc.offset = (long)&sf->REG_NAME(r9) - new_cfa;
|
||||
fs->regs.reg[10].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[10].loc.offset = (long)&sf->REG_NAME(r10) - new_cfa;
|
||||
fs->regs.reg[11].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[11].loc.offset = (long)&sf->REG_NAME(r11) - new_cfa;
|
||||
fs->regs.reg[12].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[12].loc.offset = (long)&sf->REG_NAME(r12) - new_cfa;
|
||||
fs->regs.reg[13].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[13].loc.offset = (long)&sf->REG_NAME(r13) - new_cfa;
|
||||
fs->regs.reg[14].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[14].loc.offset = (long)&sf->REG_NAME(r14) - new_cfa;
|
||||
fs->regs.reg[15].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[15].loc.offset = (long)&sf->REG_NAME(r15) - new_cfa;
|
||||
fs->regs.reg[16].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[16].loc.offset = (long)&sf->REG_NAME(rip) - new_cfa;
|
||||
fs->retaddr_column = 16;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#else /* Next section is for i386 */
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_freebsd_fallback_frame_state
|
||||
|
||||
/*
|
||||
* We can't use KERN_PS_STRINGS anymore if we want to support FreeBSD32
|
||||
* compat on AMD64. The sigtramp is in a shared page in that case so the
|
||||
* x86_sigtramp_range only works on a true i386 system. We have to
|
||||
* search for the sigtramp frame if we want it working everywhere.
|
||||
*/
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_freebsd_fallback_frame_state
|
||||
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
struct sigframe *sf;
|
||||
long new_cfa;
|
||||
|
||||
/*
|
||||
* i386 sigtramp frame we are looking for follows.
|
||||
* Apparently PSL_VM is variable, so we can't look past context->ra + 4
|
||||
* <sigcode>:
|
||||
* 0: ff 54 24 10 call *0x10(%esp) *SIGF_HANDLER
|
||||
* 4: 8d 44 24 20 lea 0x20(%esp),%eax SIGF_UC
|
||||
* 8: 50 push %eax
|
||||
* 9: f7 40 54 00 00 02 00 testl $0x20000,0x54(%eax) $PSL_VM
|
||||
* 10: 75 03 jne 15 <sigcode+0x15>
|
||||
* 12: 8e 68 14 mov 0x14(%eax),%gs UC_GS
|
||||
* 15: b8 a1 01 00 00 mov 0x1a1,%eax $SYS_sigreturn
|
||||
*/
|
||||
|
||||
if (!( *(unsigned int *)(context->ra - 4) == 0x102454ff
|
||||
&& *(unsigned int *)(context->ra) == 0x2024448d ))
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
sf = (struct sigframe *) context->cfa;
|
||||
new_cfa = sf->REG_NAME(esp);
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = 4;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(eax) - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(ebx) - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(ecx) - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(edx) - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(esi) - new_cfa;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&sf->REG_NAME(edi) - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(ebp) - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(eip) - new_cfa;
|
||||
fs->retaddr_column = 8;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
#endif /* ifdef __x86_64__ */
|
|
@ -0,0 +1,267 @@
|
|||
/* Implementation of W32-specific threads compatibility routines for
|
||||
libgcc2. */
|
||||
|
||||
/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
|
||||
Modified and moved to separate file by Danny Smith
|
||||
<dannysmith@users.sourceforge.net>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <windows.h>
|
||||
#ifndef __GTHREAD_HIDE_WIN32API
|
||||
# define __GTHREAD_HIDE_WIN32API 1
|
||||
#endif
|
||||
#undef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
#define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
#include "gthr-win32.h"
|
||||
|
||||
/* Windows32 threads specific definitions. The windows32 threading model
|
||||
does not map well into pthread-inspired gcc's threading model, and so
|
||||
there are caveats one needs to be aware of.
|
||||
|
||||
1. The destructor supplied to __gthread_key_create is ignored for
|
||||
generic x86-win32 ports. This will certainly cause memory leaks
|
||||
due to unreclaimed eh contexts (sizeof (eh_context) is at least
|
||||
24 bytes for x86 currently).
|
||||
|
||||
This memory leak may be significant for long-running applications
|
||||
that make heavy use of C++ EH.
|
||||
|
||||
However, Mingw runtime (version 0.3 or newer) provides a mechanism
|
||||
to emulate pthreads key dtors; the runtime provides a special DLL,
|
||||
linked in if -mthreads option is specified, that runs the dtors in
|
||||
the reverse order of registration when each thread exits. If
|
||||
-mthreads option is not given, a stub is linked in instead of the
|
||||
DLL, which results in memory leak. Other x86-win32 ports can use
|
||||
the same technique of course to avoid the leak.
|
||||
|
||||
2. The error codes returned are non-POSIX like, and cast into ints.
|
||||
This may cause incorrect error return due to truncation values on
|
||||
hw where sizeof (DWORD) > sizeof (int).
|
||||
|
||||
3. We are currently using a special mutex instead of the Critical
|
||||
Sections, since Win9x does not support TryEnterCriticalSection
|
||||
(while NT does).
|
||||
|
||||
The basic framework should work well enough. In the long term, GCC
|
||||
needs to use Structured Exception Handling on Windows32. */
|
||||
|
||||
int
|
||||
__gthr_win32_once (__gthread_once_t *once, void (*func) (void))
|
||||
{
|
||||
if (once == NULL || func == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (! once->done)
|
||||
{
|
||||
if (InterlockedIncrement (&(once->started)) == 0)
|
||||
{
|
||||
(*func) ();
|
||||
once->done = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Another thread is currently executing the code, so wait for it
|
||||
to finish; yield the CPU in the meantime. If performance
|
||||
does become an issue, the solution is to use an Event that
|
||||
we wait on here (and set above), but that implies a place to
|
||||
create the event before this routine is called. */
|
||||
while (! once->done)
|
||||
Sleep (0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Windows32 thread local keys don't support destructors; this leads to
|
||||
leaks, especially in threaded applications making extensive use of
|
||||
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
|
||||
|
||||
int
|
||||
__gthr_win32_key_create (__gthread_key_t *key,
|
||||
void (*dtor) (void *) __attribute__((unused)))
|
||||
{
|
||||
int status = 0;
|
||||
DWORD tls_index = TlsAlloc ();
|
||||
if (tls_index != 0xFFFFFFFF)
|
||||
{
|
||||
*key = tls_index;
|
||||
#ifdef MINGW32_SUPPORTS_MT_EH
|
||||
/* Mingw runtime will run the dtors in reverse order for each thread
|
||||
when the thread exits. */
|
||||
status = __mingwthr_key_dtor (*key, dtor);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
status = (int) GetLastError ();
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_key_delete (__gthread_key_t key)
|
||||
{
|
||||
return (TlsFree (key) != 0) ? 0 : (int) GetLastError ();
|
||||
}
|
||||
|
||||
void *
|
||||
__gthr_win32_getspecific (__gthread_key_t key)
|
||||
{
|
||||
DWORD lasterror;
|
||||
void *ptr;
|
||||
lasterror = GetLastError();
|
||||
ptr = TlsGetValue(key);
|
||||
SetLastError( lasterror );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_setspecific (__gthread_key_t key, const void *ptr)
|
||||
{
|
||||
if (TlsSetValue (key, CONST_CAST2(void *, const void *, ptr)) != 0)
|
||||
return 0;
|
||||
else
|
||||
return GetLastError ();
|
||||
}
|
||||
|
||||
void
|
||||
__gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
|
||||
{
|
||||
mutex->counter = -1;
|
||||
mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex)
|
||||
{
|
||||
CloseHandle ((HANDLE) mutex->sema);
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
if (InterlockedIncrement (&mutex->counter) == 0 ||
|
||||
WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||
some best-effort cleanup here. */
|
||||
InterlockedDecrement (&mutex->counter);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_mutex_trylock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
if (InterlockedDecrement (&mutex->counter) >= 0)
|
||||
return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
mutex->counter = -1;
|
||||
mutex->depth = 0;
|
||||
mutex->owner = 0;
|
||||
mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
DWORD me = GetCurrentThreadId();
|
||||
if (InterlockedIncrement (&mutex->counter) == 0)
|
||||
{
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
}
|
||||
else if (mutex->owner == me)
|
||||
{
|
||||
InterlockedDecrement (&mutex->counter);
|
||||
++(mutex->depth);
|
||||
}
|
||||
else if (WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||
some best-effort cleanup here. */
|
||||
InterlockedDecrement (&mutex->counter);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
DWORD me = GetCurrentThreadId();
|
||||
if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
|
||||
{
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
}
|
||||
else if (mutex->owner == me)
|
||||
++(mutex->depth);
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
--(mutex->depth);
|
||||
if (mutex->depth == 0)
|
||||
{
|
||||
mutex->owner = 0;
|
||||
|
||||
if (InterlockedDecrement (&mutex->counter) >= 0)
|
||||
return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
CloseHandle ((HANDLE) mutex->sema);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,787 @@
|
|||
/* Threads compatibility routines for libgcc2 and libobjc. */
|
||||
/* Compile this one with gcc. */
|
||||
|
||||
/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_GTHR_WIN32_H
|
||||
#define GCC_GTHR_WIN32_H
|
||||
|
||||
/* Make sure CONST_CAST2 (origin in system.h) is declared. */
|
||||
#ifndef CONST_CAST2
|
||||
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
|
||||
#endif
|
||||
|
||||
/* Windows32 threads specific definitions. The windows32 threading model
|
||||
does not map well into pthread-inspired gcc's threading model, and so
|
||||
there are caveats one needs to be aware of.
|
||||
|
||||
1. The destructor supplied to __gthread_key_create is ignored for
|
||||
generic x86-win32 ports. This will certainly cause memory leaks
|
||||
due to unreclaimed eh contexts (sizeof (eh_context) is at least
|
||||
24 bytes for x86 currently).
|
||||
|
||||
This memory leak may be significant for long-running applications
|
||||
that make heavy use of C++ EH.
|
||||
|
||||
However, Mingw runtime (version 0.3 or newer) provides a mechanism
|
||||
to emulate pthreads key dtors; the runtime provides a special DLL,
|
||||
linked in if -mthreads option is specified, that runs the dtors in
|
||||
the reverse order of registration when each thread exits. If
|
||||
-mthreads option is not given, a stub is linked in instead of the
|
||||
DLL, which results in memory leak. Other x86-win32 ports can use
|
||||
the same technique of course to avoid the leak.
|
||||
|
||||
2. The error codes returned are non-POSIX like, and cast into ints.
|
||||
This may cause incorrect error return due to truncation values on
|
||||
hw where sizeof (DWORD) > sizeof (int).
|
||||
|
||||
3. We are currently using a special mutex instead of the Critical
|
||||
Sections, since Win9x does not support TryEnterCriticalSection
|
||||
(while NT does).
|
||||
|
||||
The basic framework should work well enough. In the long term, GCC
|
||||
needs to use Structured Exception Handling on Windows32. */
|
||||
|
||||
#define __GTHREADS 1
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef __MINGW32__
|
||||
#include <_mingw.h>
|
||||
#endif
|
||||
|
||||
#ifndef __UNUSED_PARAM
|
||||
#define __UNUSED_PARAM(x) x
|
||||
#endif
|
||||
|
||||
#ifdef _LIBOBJC
|
||||
|
||||
/* This is necessary to prevent windef.h (included from windows.h) from
|
||||
defining its own BOOL as a typedef. */
|
||||
#ifndef __OBJC__
|
||||
#define __OBJC__
|
||||
#endif
|
||||
#include <windows.h>
|
||||
/* Now undef the windows BOOL. */
|
||||
#undef BOOL
|
||||
|
||||
/* Key structure for maintaining thread specific storage */
|
||||
static DWORD __gthread_objc_data_tls = (DWORD) -1;
|
||||
|
||||
/* Backend initialization functions */
|
||||
|
||||
/* Initialize the threads subsystem. */
|
||||
int
|
||||
__gthread_objc_init_thread_system (void)
|
||||
{
|
||||
/* Initialize the thread storage key. */
|
||||
if ((__gthread_objc_data_tls = TlsAlloc ()) != (DWORD) -1)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the threads subsystem. */
|
||||
int
|
||||
__gthread_objc_close_thread_system (void)
|
||||
{
|
||||
if (__gthread_objc_data_tls != (DWORD) -1)
|
||||
TlsFree (__gthread_objc_data_tls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend thread functions */
|
||||
|
||||
/* Create a new thread of execution. */
|
||||
objc_thread_t
|
||||
__gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
|
||||
{
|
||||
DWORD thread_id = 0;
|
||||
HANDLE win32_handle;
|
||||
|
||||
if (!(win32_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) func,
|
||||
arg, 0, &thread_id)))
|
||||
thread_id = 0;
|
||||
|
||||
return (objc_thread_t) (INT_PTR) thread_id;
|
||||
}
|
||||
|
||||
/* Set the current thread's priority. */
|
||||
int
|
||||
__gthread_objc_thread_set_priority (int priority)
|
||||
{
|
||||
int sys_priority = 0;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_NORMAL;
|
||||
break;
|
||||
default:
|
||||
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
case OBJC_THREAD_LOW_PRIORITY:
|
||||
sys_priority = THREAD_PRIORITY_LOWEST;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change priority */
|
||||
if (SetThreadPriority (GetCurrentThread (), sys_priority))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the current thread's priority. */
|
||||
int
|
||||
__gthread_objc_thread_get_priority (void)
|
||||
{
|
||||
int sys_priority;
|
||||
|
||||
sys_priority = GetThreadPriority (GetCurrentThread ());
|
||||
|
||||
switch (sys_priority)
|
||||
{
|
||||
case THREAD_PRIORITY_HIGHEST:
|
||||
case THREAD_PRIORITY_TIME_CRITICAL:
|
||||
case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||
case THREAD_PRIORITY_NORMAL:
|
||||
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||
|
||||
default:
|
||||
case THREAD_PRIORITY_BELOW_NORMAL:
|
||||
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||
|
||||
case THREAD_PRIORITY_IDLE:
|
||||
case THREAD_PRIORITY_LOWEST:
|
||||
return OBJC_THREAD_LOW_PRIORITY;
|
||||
}
|
||||
|
||||
/* Couldn't get priority. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yield our process time to another thread. */
|
||||
void
|
||||
__gthread_objc_thread_yield (void)
|
||||
{
|
||||
Sleep (0);
|
||||
}
|
||||
|
||||
/* Terminate the current thread. */
|
||||
int
|
||||
__gthread_objc_thread_exit (void)
|
||||
{
|
||||
/* exit the thread */
|
||||
ExitThread (__objc_thread_exit_status);
|
||||
|
||||
/* Failed if we reached here */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns an integer value which uniquely describes a thread. */
|
||||
objc_thread_t
|
||||
__gthread_objc_thread_id (void)
|
||||
{
|
||||
return (objc_thread_t) (INT_PTR) GetCurrentThreadId ();
|
||||
}
|
||||
|
||||
/* Sets the thread's local storage pointer. */
|
||||
int
|
||||
__gthread_objc_thread_set_data (void *value)
|
||||
{
|
||||
if (TlsSetValue (__gthread_objc_data_tls, value))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns the thread's local storage pointer. */
|
||||
void *
|
||||
__gthread_objc_thread_get_data (void)
|
||||
{
|
||||
DWORD lasterror;
|
||||
void *ptr;
|
||||
|
||||
lasterror = GetLastError ();
|
||||
|
||||
ptr = TlsGetValue (__gthread_objc_data_tls); /* Return thread data. */
|
||||
|
||||
SetLastError (lasterror);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Backend mutex functions */
|
||||
|
||||
/* Allocate a mutex. */
|
||||
int
|
||||
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
|
||||
{
|
||||
if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deallocate a mutex. */
|
||||
int
|
||||
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
|
||||
{
|
||||
CloseHandle ((HANDLE) (mutex->backend));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Grab a lock on a mutex. */
|
||||
int
|
||||
__gthread_objc_mutex_lock (objc_mutex_t mutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = WaitForSingleObject ((HANDLE) (mutex->backend), INFINITE);
|
||||
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to grab a lock on a mutex. */
|
||||
int
|
||||
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = WaitForSingleObject ((HANDLE) (mutex->backend), 0);
|
||||
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
|
||||
{
|
||||
if (ReleaseMutex ((HANDLE) (mutex->backend)) == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backend condition mutex functions */
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__gthread_objc_condition_allocate (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__gthread_objc_condition_deallocate (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__gthread_objc_condition_wait (objc_condition_t __UNUSED_PARAM(condition),
|
||||
objc_mutex_t __UNUSED_PARAM(mutex))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__gthread_objc_condition_broadcast (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__gthread_objc_condition_signal (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else /* _LIBOBJC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned long __gthread_key_t;
|
||||
|
||||
typedef struct {
|
||||
int done;
|
||||
long started;
|
||||
} __gthread_once_t;
|
||||
|
||||
typedef struct {
|
||||
long counter;
|
||||
void *sema;
|
||||
} __gthread_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
long counter;
|
||||
long depth;
|
||||
unsigned long owner;
|
||||
void *sema;
|
||||
} __gthread_recursive_mutex_t;
|
||||
|
||||
#define __GTHREAD_ONCE_INIT {0, -1}
|
||||
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
|
||||
#define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0}
|
||||
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION \
|
||||
__gthread_recursive_mutex_init_function
|
||||
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
|
||||
|
||||
#if defined (_WIN32) && !defined(__CYGWIN__)
|
||||
#define MINGW32_SUPPORTS_MT_EH 1
|
||||
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
|
||||
if -mthreads option was specified, or 0 otherwise. This is to get around
|
||||
the lack of weak symbols in PE-COFF. */
|
||||
extern int _CRT_MT;
|
||||
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
|
||||
#endif /* _WIN32 && !__CYGWIN__ */
|
||||
|
||||
/* The Windows95 kernel does not export InterlockedCompareExchange.
|
||||
This provides a substitute. When building apps that reference
|
||||
gthread_mutex_try_lock, the __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
macro must be defined if Windows95 is a target. Currently
|
||||
gthread_mutex_try_lock is not referenced by libgcc or libstdc++. */
|
||||
#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
static inline long
|
||||
__gthr_i486_lock_cmp_xchg(long *__dest, long __xchg, long __comperand)
|
||||
{
|
||||
long result;
|
||||
__asm__ __volatile__ ("\n\
|
||||
lock\n\
|
||||
cmpxchg{l} {%4, %1|%1, %4}\n"
|
||||
: "=a" (result), "=m" (*__dest)
|
||||
: "0" (__comperand), "m" (*__dest), "r" (__xchg)
|
||||
: "cc");
|
||||
return result;
|
||||
}
|
||||
#define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg
|
||||
#else /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
|
||||
#define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange
|
||||
#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
|
||||
|
||||
static inline int
|
||||
__gthread_active_p (void)
|
||||
{
|
||||
#ifdef MINGW32_SUPPORTS_MT_EH
|
||||
return _CRT_MT;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __GTHREAD_HIDE_WIN32API
|
||||
|
||||
/* The implementations are in config/i386/gthr-win32.c in libgcc.a.
|
||||
Only stubs are exposed to avoid polluting the C++ namespace with
|
||||
windows api definitions. */
|
||||
|
||||
extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
|
||||
extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
|
||||
extern int __gthr_win32_key_delete (__gthread_key_t);
|
||||
extern void * __gthr_win32_getspecific (__gthread_key_t);
|
||||
extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
|
||||
extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
|
||||
extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
|
||||
extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
|
||||
extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);
|
||||
extern void
|
||||
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *);
|
||||
extern int __gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *);
|
||||
extern int
|
||||
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *);
|
||||
extern int __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *);
|
||||
extern void __gthr_win32_mutex_destroy (__gthread_mutex_t *);
|
||||
extern int
|
||||
__gthr_win32_recursive_mutex_destroy (__gthread_recursive_mutex_t *);
|
||||
|
||||
static inline int
|
||||
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_once (__once, __func);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
|
||||
{
|
||||
return __gthr_win32_key_create (__key, __dtor);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_key_delete (__gthread_key_t __key)
|
||||
{
|
||||
return __gthr_win32_key_delete (__key);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
__gthread_getspecific (__gthread_key_t __key)
|
||||
{
|
||||
return __gthr_win32_getspecific (__key);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||
{
|
||||
return __gthr_win32_setspecific (__key, __ptr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
__gthr_win32_mutex_init_function (__mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
__gthr_win32_mutex_destroy (__mutex);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_mutex_lock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_mutex_trylock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_mutex_unlock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
__gthr_win32_recursive_mutex_init_function (__mutex);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_recursive_mutex_lock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_recursive_mutex_trylock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
return __gthr_win32_recursive_mutex_unlock (__mutex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
return __gthr_win32_recursive_mutex_destroy (__mutex);
|
||||
}
|
||||
|
||||
#else /* ! __GTHREAD_HIDE_WIN32API */
|
||||
|
||||
#define NOGDI
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
|
||||
static inline int
|
||||
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
|
||||
{
|
||||
if (! __gthread_active_p ())
|
||||
return -1;
|
||||
else if (__once == NULL || __func == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (! __once->done)
|
||||
{
|
||||
if (InterlockedIncrement (&(__once->started)) == 0)
|
||||
{
|
||||
(*__func) ();
|
||||
__once->done = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Another thread is currently executing the code, so wait for it
|
||||
to finish; yield the CPU in the meantime. If performance
|
||||
does become an issue, the solution is to use an Event that
|
||||
we wait on here (and set above), but that implies a place to
|
||||
create the event before this routine is called. */
|
||||
while (! __once->done)
|
||||
Sleep (0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Windows32 thread local keys don't support destructors; this leads to
|
||||
leaks, especially in threaded applications making extensive use of
|
||||
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
|
||||
static inline int
|
||||
__gthread_key_create (__gthread_key_t *__key,
|
||||
void (*__dtor) (void *) __attribute__((__unused__)))
|
||||
{
|
||||
int __status = 0;
|
||||
DWORD __tls_index = TlsAlloc ();
|
||||
if (__tls_index != 0xFFFFFFFF)
|
||||
{
|
||||
*__key = __tls_index;
|
||||
#ifdef MINGW32_SUPPORTS_MT_EH
|
||||
/* Mingw runtime will run the dtors in reverse order for each thread
|
||||
when the thread exits. */
|
||||
__status = __mingwthr_key_dtor (*__key, __dtor);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
__status = (int) GetLastError ();
|
||||
return __status;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_key_delete (__gthread_key_t __key)
|
||||
{
|
||||
return (TlsFree (__key) != 0) ? 0 : (int) GetLastError ();
|
||||
}
|
||||
|
||||
static inline void *
|
||||
__gthread_getspecific (__gthread_key_t __key)
|
||||
{
|
||||
DWORD __lasterror;
|
||||
void *__ptr;
|
||||
|
||||
__lasterror = GetLastError ();
|
||||
|
||||
__ptr = TlsGetValue (__key);
|
||||
|
||||
SetLastError (__lasterror);
|
||||
|
||||
return __ptr;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||
{
|
||||
if (TlsSetValue (__key, CONST_CAST2(void *, const void *, __ptr)) != 0)
|
||||
return 0;
|
||||
else
|
||||
return GetLastError ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
__mutex->counter = -1;
|
||||
__mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
CloseHandle ((HANDLE) __mutex->sema);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
int __status = 0;
|
||||
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
if (InterlockedIncrement (&__mutex->counter) == 0 ||
|
||||
WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||
__status = 0;
|
||||
else
|
||||
{
|
||||
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||
some best-effort cleanup here. */
|
||||
InterlockedDecrement (&__mutex->counter);
|
||||
__status = 1;
|
||||
}
|
||||
}
|
||||
return __status;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
int __status = 0;
|
||||
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
|
||||
__status = 0;
|
||||
else
|
||||
__status = 1;
|
||||
}
|
||||
return __status;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
if (InterlockedDecrement (&__mutex->counter) >= 0)
|
||||
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
__mutex->counter = -1;
|
||||
__mutex->depth = 0;
|
||||
__mutex->owner = 0;
|
||||
__mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
DWORD __me = GetCurrentThreadId();
|
||||
if (InterlockedIncrement (&__mutex->counter) == 0)
|
||||
{
|
||||
__mutex->depth = 1;
|
||||
__mutex->owner = __me;
|
||||
}
|
||||
else if (__mutex->owner == __me)
|
||||
{
|
||||
InterlockedDecrement (&__mutex->counter);
|
||||
++(__mutex->depth);
|
||||
}
|
||||
else if (WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
__mutex->depth = 1;
|
||||
__mutex->owner = __me;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||
some best-effort cleanup here. */
|
||||
InterlockedDecrement (&__mutex->counter);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
DWORD __me = GetCurrentThreadId();
|
||||
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
|
||||
{
|
||||
__mutex->depth = 1;
|
||||
__mutex->owner = __me;
|
||||
}
|
||||
else if (__mutex->owner == __me)
|
||||
++(__mutex->depth);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
if (__gthread_active_p ())
|
||||
{
|
||||
--(__mutex->depth);
|
||||
if (__mutex->depth == 0)
|
||||
{
|
||||
__mutex->owner = 0;
|
||||
|
||||
if (InterlockedDecrement (&__mutex->counter) >= 0)
|
||||
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
|
||||
{
|
||||
CloseHandle ((HANDLE) __mutex->sema);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __GTHREAD_HIDE_WIN32API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBOBJC */
|
||||
|
||||
#endif /* ! GCC_GTHR_WIN32_H */
|
|
@ -0,0 +1,117 @@
|
|||
# Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 128 bit long double support was introduced with GCC 4.6.0 for FreeBSD.
|
||||
# These lines make the symbols to get a @@GCC_4.6.0.
|
||||
|
||||
%exclude {
|
||||
__addtf3
|
||||
__copysigntf3
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
__fabstf2
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
__fixtfti
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
__fixunstfti
|
||||
__floatditf
|
||||
__floatsitf
|
||||
__floattitf
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
__floatuntitf
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
GCC_4.6.0 {
|
||||
__addtf3
|
||||
%ifndef __x86_64__
|
||||
__copysigntf3
|
||||
%endif
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
%ifndef __x86_64__
|
||||
__fabstf2
|
||||
%endif
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
%ifdef __x86_64__
|
||||
__fixtfti
|
||||
%endif
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
%ifdef __x86_64__
|
||||
__fixunstfti
|
||||
%endif
|
||||
__floatditf
|
||||
__floatsitf
|
||||
%ifdef __x86_64__
|
||||
__floattitf
|
||||
%endif
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
%ifdef __x86_64__
|
||||
__floatuntitf
|
||||
%endif
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
GCC_4.8.0 {
|
||||
__cpu_model
|
||||
__cpu_indicator_init
|
||||
}
|
||||
|
||||
GCC_7.0.0 {
|
||||
__signbittf2
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
GCC_4.8 {
|
||||
_GCC_specific_handler
|
||||
__gcc_personality_seh0
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
# Copyright (C) 2005-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
__Unwind_Backtrace
|
||||
__Unwind_DeleteException
|
||||
__Unwind_FindEnclosingFunction
|
||||
__Unwind_Find_FDE
|
||||
__Unwind_ForcedUnwind
|
||||
__Unwind_GetCFA
|
||||
__Unwind_GetDataRelBase
|
||||
__Unwind_GetGR
|
||||
__Unwind_GetIP
|
||||
__Unwind_GetLanguageSpecificData
|
||||
__Unwind_GetRegionStart
|
||||
__Unwind_GetTextRelBase
|
||||
__Unwind_RaiseException
|
||||
__Unwind_Resume
|
||||
__Unwind_Resume_or_Rethrow
|
||||
__Unwind_SetGR
|
||||
__Unwind_SetIP
|
||||
___absvdi2
|
||||
___absvsi2
|
||||
___addvdi3
|
||||
___addvsi3
|
||||
___ashldi3
|
||||
___ashrdi3
|
||||
___clear_cache
|
||||
___clzdi2
|
||||
___clzsi2
|
||||
___cmpdi2
|
||||
___ctzdi2
|
||||
___ctzsi2
|
||||
___deregister_frame
|
||||
___deregister_frame_info
|
||||
___deregister_frame_info_bases
|
||||
___divdc3
|
||||
___divdi3
|
||||
___divsc3
|
||||
___divxc3
|
||||
___enable_execute_stack
|
||||
___ffsdi2
|
||||
___fixdfdi
|
||||
___fixsfdi
|
||||
___fixunsdfdi
|
||||
___fixunsdfsi
|
||||
___fixunssfdi
|
||||
___fixunssfsi
|
||||
___fixunsxfdi
|
||||
___fixunsxfsi
|
||||
___fixxfdi
|
||||
___floatdidf
|
||||
___floatdisf
|
||||
___floatdixf
|
||||
___gcc_personality_v0
|
||||
___lshrdi3
|
||||
___moddi3
|
||||
___muldc3
|
||||
___muldi3
|
||||
___mulsc3
|
||||
___mulvdi3
|
||||
___mulvsi3
|
||||
___mulxc3
|
||||
___negdi2
|
||||
___negvdi2
|
||||
___negvsi2
|
||||
___paritydi2
|
||||
___paritysi2
|
||||
___popcountdi2
|
||||
___popcountsi2
|
||||
___powidf2
|
||||
___powisf2
|
||||
___powixf2
|
||||
___register_frame
|
||||
___register_frame_info
|
||||
___register_frame_info_bases
|
||||
___register_frame_info_table
|
||||
___register_frame_info_table_bases
|
||||
___register_frame_table
|
||||
___subvdi3
|
||||
___subvsi3
|
||||
___ucmpdi2
|
||||
___udivdi3
|
||||
___udivmoddi4
|
||||
___umoddi3
|
|
@ -0,0 +1,102 @@
|
|||
# Copyright (C) 2005-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
__Unwind_Backtrace
|
||||
__Unwind_DeleteException
|
||||
__Unwind_FindEnclosingFunction
|
||||
__Unwind_Find_FDE
|
||||
__Unwind_ForcedUnwind
|
||||
__Unwind_GetCFA
|
||||
__Unwind_GetDataRelBase
|
||||
__Unwind_GetGR
|
||||
__Unwind_GetIP
|
||||
__Unwind_GetIPInfo
|
||||
__Unwind_GetLanguageSpecificData
|
||||
__Unwind_GetRegionStart
|
||||
__Unwind_GetTextRelBase
|
||||
__Unwind_RaiseException
|
||||
__Unwind_Resume
|
||||
__Unwind_Resume_or_Rethrow
|
||||
__Unwind_SetGR
|
||||
__Unwind_SetIP
|
||||
___absvdi2
|
||||
___absvsi2
|
||||
___addvdi3
|
||||
___addvsi3
|
||||
___ashldi3
|
||||
___ashrdi3
|
||||
___clear_cache
|
||||
___clzdi2
|
||||
___clzsi2
|
||||
___cmpdi2
|
||||
___ctzdi2
|
||||
___ctzsi2
|
||||
___deregister_frame
|
||||
___deregister_frame_info
|
||||
___deregister_frame_info_bases
|
||||
___divdc3
|
||||
___divdi3
|
||||
___divsc3
|
||||
___divxc3
|
||||
___enable_execute_stack
|
||||
___ffsdi2
|
||||
___fixdfdi
|
||||
___fixsfdi
|
||||
___fixunsdfdi
|
||||
___fixunsdfsi
|
||||
___fixunssfdi
|
||||
___fixunssfsi
|
||||
___fixunsxfdi
|
||||
___fixunsxfsi
|
||||
___fixxfdi
|
||||
___floatdidf
|
||||
___floatdisf
|
||||
___floatdixf
|
||||
___floatundidf
|
||||
___floatundisf
|
||||
___floatundixf
|
||||
___gcc_personality_v0
|
||||
___lshrdi3
|
||||
___moddi3
|
||||
___muldc3
|
||||
___muldi3
|
||||
___mulsc3
|
||||
___mulvdi3
|
||||
___mulvsi3
|
||||
___mulxc3
|
||||
___negdi2
|
||||
___negvdi2
|
||||
___negvsi2
|
||||
___paritydi2
|
||||
___paritysi2
|
||||
___popcountdi2
|
||||
___popcountsi2
|
||||
___powidf2
|
||||
___powisf2
|
||||
___powixf2
|
||||
___register_frame
|
||||
___register_frame_info
|
||||
___register_frame_info_bases
|
||||
___register_frame_info_table
|
||||
___register_frame_info_table_bases
|
||||
___register_frame_table
|
||||
___subvdi3
|
||||
___subvsi3
|
||||
___ucmpdi2
|
||||
___udivdi3
|
||||
___udivmoddi4
|
||||
___umoddi3
|
|
@ -0,0 +1,196 @@
|
|||
# Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# In order to work around the very problems that force us to now generally
|
||||
# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
|
||||
# By now choosing the same version tags for these specific routines, we
|
||||
# maintain enough binary compatibility to allow future versions of glibc
|
||||
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
|
||||
|
||||
%ifndef __x86_64__
|
||||
%exclude {
|
||||
__divdi3
|
||||
__moddi3
|
||||
__udivdi3
|
||||
__umoddi3
|
||||
__register_frame
|
||||
__register_frame_table
|
||||
__deregister_frame
|
||||
__register_frame_info
|
||||
__deregister_frame_info
|
||||
__frame_state_for
|
||||
__register_frame_info_table
|
||||
}
|
||||
|
||||
%inherit GCC_3.0 GLIBC_2.0
|
||||
GLIBC_2.0 {
|
||||
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
|
||||
__divdi3
|
||||
__moddi3
|
||||
__udivdi3
|
||||
__umoddi3
|
||||
|
||||
# Exception handling support functions used by most everyone.
|
||||
__register_frame
|
||||
__register_frame_table
|
||||
__deregister_frame
|
||||
__register_frame_info
|
||||
__deregister_frame_info
|
||||
__frame_state_for
|
||||
__register_frame_info_table
|
||||
}
|
||||
%endif
|
||||
|
||||
# 128 bit long double support was introduced with GCC 4.3.0 to 64bit
|
||||
# and with GCC 4.4.0 to 32bit. These lines make the symbols to get
|
||||
# a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
|
||||
|
||||
%exclude {
|
||||
__addtf3
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
__fixtfti
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
__fixunstfti
|
||||
__floatditf
|
||||
__floatsitf
|
||||
__floattitf
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
__floatuntitf
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
%ifdef __x86_64__
|
||||
# Those symbols had improper versions when they were added to gcc 4.3.0.
|
||||
# We corrected the default version to GCC_4.3.0. But we keep the old
|
||||
# version for backward binary compatibility.
|
||||
GCC_3.0 {
|
||||
__gttf2
|
||||
__lttf2
|
||||
__netf2
|
||||
}
|
||||
|
||||
GCC_4.0.0 {
|
||||
__divtc3
|
||||
__multc3
|
||||
__powitf2
|
||||
}
|
||||
|
||||
GCC_4.3.0 {
|
||||
__addtf3
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
__fixtfti
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
__fixunstfti
|
||||
__floatditf
|
||||
__floatsitf
|
||||
__floattitf
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
__floatuntitf
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
GCC_4.8.0 {
|
||||
__cpu_model
|
||||
__cpu_indicator_init
|
||||
}
|
||||
%else
|
||||
GCC_4.4.0 {
|
||||
__addtf3
|
||||
__copysigntf3
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__fabstf2
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
__floatditf
|
||||
__floatsitf
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
GCC_4.5.0 {
|
||||
__extendxftf2
|
||||
}
|
||||
|
||||
GCC_4.8.0 {
|
||||
__cpu_model
|
||||
__cpu_indicator_init
|
||||
}
|
||||
%endif
|
|
@ -0,0 +1,117 @@
|
|||
# Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# 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 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 128 bit long double support was introduced with GCC 4.5.0 for Solaris 2.
|
||||
# These lines make the symbols to get a @@GCC_4.5.0.
|
||||
|
||||
%exclude {
|
||||
__addtf3
|
||||
__copysigntf3
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
__fabstf2
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
__fixtfti
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
__fixunstfti
|
||||
__floatditf
|
||||
__floatsitf
|
||||
__floattitf
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
__floatuntitf
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
GCC_4.5.0 {
|
||||
__addtf3
|
||||
%ifndef __x86_64__
|
||||
__copysigntf3
|
||||
%endif
|
||||
__divtc3
|
||||
__divtf3
|
||||
__eqtf2
|
||||
__extenddftf2
|
||||
__extendsftf2
|
||||
__extendxftf2
|
||||
%ifndef __x86_64__
|
||||
__fabstf2
|
||||
%endif
|
||||
__fixtfdi
|
||||
__fixtfsi
|
||||
%ifdef __x86_64__
|
||||
__fixtfti
|
||||
%endif
|
||||
__fixunstfdi
|
||||
__fixunstfsi
|
||||
%ifdef __x86_64__
|
||||
__fixunstfti
|
||||
%endif
|
||||
__floatditf
|
||||
__floatsitf
|
||||
%ifdef __x86_64__
|
||||
__floattitf
|
||||
%endif
|
||||
__floatunditf
|
||||
__floatunsitf
|
||||
%ifdef __x86_64__
|
||||
__floatuntitf
|
||||
%endif
|
||||
__getf2
|
||||
__gttf2
|
||||
__letf2
|
||||
__lttf2
|
||||
__multc3
|
||||
__multf3
|
||||
__negtf2
|
||||
__netf2
|
||||
__powitf2
|
||||
__subtf3
|
||||
__trunctfdf2
|
||||
__trunctfsf2
|
||||
__trunctfxf2
|
||||
__unordtf2
|
||||
}
|
||||
|
||||
GCC_4.8.0 {
|
||||
__cpu_model
|
||||
__cpu_indicator_init
|
||||
}
|
||||
|
||||
GCC_7.0.0 {
|
||||
__signbittf2
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/* DWARF2 EH unwinding support for AMD x86-64 and x86.
|
||||
Copyright (C) 2004-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs.
|
||||
Don't use this at all if inhibit_libc is used. */
|
||||
|
||||
#ifndef inhibit_libc
|
||||
|
||||
/* There's no sys/ucontext.h for glibc 2.0, so no
|
||||
signal-turned-exceptions for them. There's also no configure-run for
|
||||
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
|
||||
target libc version macro should be enough. */
|
||||
#if defined __GLIBC__ && !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_64_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
struct sigcontext *sc;
|
||||
long new_cfa;
|
||||
|
||||
/* movq $__NR_rt_sigreturn, %rax ; syscall. */
|
||||
#ifdef __LP64__
|
||||
#define RT_SIGRETURN_SYSCALL 0x050f0000000fc0c7ULL
|
||||
#else
|
||||
#define RT_SIGRETURN_SYSCALL 0x050f40000201c0c7ULL
|
||||
#endif
|
||||
if (*(unsigned char *)(pc+0) == 0x48
|
||||
&& *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL)
|
||||
{
|
||||
struct ucontext *uc_ = context->cfa;
|
||||
/* The void * cast is necessary to avoid an aliasing warning.
|
||||
The aliasing warning is correct, but should not be a problem
|
||||
because it does not alias anything. */
|
||||
sc = (struct sigcontext *) (void *) &uc_->uc_mcontext;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
new_cfa = sc->rsp;
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
/* Register 7 is rsp */
|
||||
fs->regs.cfa_reg = 7;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sc->rax - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sc->rdx - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sc->rcx - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sc->rbx - new_cfa;
|
||||
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[4].loc.offset = (long)&sc->rsi - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sc->rdi - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sc->rbp - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sc->r8 - new_cfa;
|
||||
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[9].loc.offset = (long)&sc->r9 - new_cfa;
|
||||
fs->regs.reg[10].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[10].loc.offset = (long)&sc->r10 - new_cfa;
|
||||
fs->regs.reg[11].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[11].loc.offset = (long)&sc->r11 - new_cfa;
|
||||
fs->regs.reg[12].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[12].loc.offset = (long)&sc->r12 - new_cfa;
|
||||
fs->regs.reg[13].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[13].loc.offset = (long)&sc->r13 - new_cfa;
|
||||
fs->regs.reg[14].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[14].loc.offset = (long)&sc->r14 - new_cfa;
|
||||
fs->regs.reg[15].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[15].loc.offset = (long)&sc->r15 - new_cfa;
|
||||
fs->regs.reg[16].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
|
||||
fs->retaddr_column = 16;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#else /* ifdef __x86_64__ */
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
struct sigcontext *sc;
|
||||
long new_cfa;
|
||||
|
||||
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */
|
||||
if (*(unsigned short *)(pc+0) == 0xb858
|
||||
&& *(unsigned int *)(pc+2) == 119
|
||||
&& *(unsigned short *)(pc+6) == 0x80cd)
|
||||
sc = context->cfa + 4;
|
||||
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */
|
||||
else if (*(unsigned char *)(pc+0) == 0xb8
|
||||
&& *(unsigned int *)(pc+1) == 173
|
||||
&& *(unsigned short *)(pc+5) == 0x80cd)
|
||||
{
|
||||
struct rt_sigframe {
|
||||
int sig;
|
||||
siginfo_t *pinfo;
|
||||
void *puc;
|
||||
siginfo_t info;
|
||||
struct ucontext uc;
|
||||
} *rt_ = context->cfa;
|
||||
/* The void * cast is necessary to avoid an aliasing warning.
|
||||
The aliasing warning is correct, but should not be a problem
|
||||
because it does not alias anything. */
|
||||
sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
new_cfa = sc->esp;
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = 4;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&sc->eax - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&sc->ebx - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&sc->ecx - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&sc->edx - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&sc->esi - new_cfa;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&sc->edi - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&sc->ebp - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sc->eip - new_cfa;
|
||||
fs->retaddr_column = 8;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#define MD_FROB_UPDATE_CONTEXT x86_frob_update_context
|
||||
|
||||
/* Fix up for kernels that have vDSO, but don't have S flag in it. */
|
||||
|
||||
static void
|
||||
x86_frob_update_context (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
|
||||
/* movl $__NR_rt_sigreturn,%eax ; {int $0x80 | syscall} */
|
||||
if (*(unsigned char *)(pc+0) == 0xb8
|
||||
&& *(unsigned int *)(pc+1) == 173
|
||||
&& (*(unsigned short *)(pc+5) == 0x80cd
|
||||
|| *(unsigned short *)(pc+5) == 0x050f))
|
||||
_Unwind_SetSignalFrame (context, 1);
|
||||
}
|
||||
|
||||
#endif /* ifdef __x86_64__ */
|
||||
#endif /* not glibc 2.0 */
|
||||
#endif /* ifdef inhibit_libc */
|
|
@ -0,0 +1,863 @@
|
|||
# x86/x86_64 support for -fsplit-stack.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# Contributed by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
# This file is part of GCC.
|
||||
|
||||
# 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 3, or (at your option) any later
|
||||
# version.
|
||||
|
||||
# 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.
|
||||
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# Support for allocating more stack space when using -fsplit-stack.
|
||||
# When a function discovers that it needs more stack space, it will
|
||||
# call __morestack with the size of the stack frame and the size of
|
||||
# the parameters to copy from the old stack frame to the new one.
|
||||
# The __morestack function preserves the parameter registers and
|
||||
# calls __generic_morestack to actually allocate the stack space.
|
||||
|
||||
# When this is called stack space is very low, but we ensure that
|
||||
# there is enough space to push the parameter registers and to call
|
||||
# __generic_morestack.
|
||||
|
||||
# When calling __generic_morestack, FRAME_SIZE points to the size of
|
||||
# the desired frame when the function is called, and the function
|
||||
# sets it to the size of the allocated stack. OLD_STACK points to
|
||||
# the parameters on the old stack and PARAM_SIZE is the number of
|
||||
# bytes of parameters to copy to the new stack. These are the
|
||||
# parameters of the function that called __morestack. The
|
||||
# __generic_morestack function returns the new stack pointer,
|
||||
# pointing to the address of the first copied parameter. The return
|
||||
# value minus the returned *FRAME_SIZE will be the first address on
|
||||
# the stack which we should not use.
|
||||
|
||||
# void *__generic_morestack (size_t *frame_size, void *old_stack,
|
||||
# size_t param_size);
|
||||
|
||||
# The __morestack routine has to arrange for the caller to return to a
|
||||
# stub on the new stack. The stub is responsible for restoring the
|
||||
# old stack pointer and returning to the caller's caller. This calls
|
||||
# __generic_releasestack to retrieve the old stack pointer and release
|
||||
# the newly allocated stack.
|
||||
|
||||
# void *__generic_releasestack (size_t *available);
|
||||
|
||||
# We do a little dance so that the processor's call/return return
|
||||
# address prediction works out. The compiler arranges for the caller
|
||||
# to look like this:
|
||||
# call __generic_morestack
|
||||
# ret
|
||||
# L:
|
||||
# // carry on with function
|
||||
# After we allocate more stack, we call L, which is in our caller.
|
||||
# When that returns (to the predicted instruction), we release the
|
||||
# stack segment and reset the stack pointer. We then return to the
|
||||
# predicted instruction, namely the ret instruction immediately after
|
||||
# the call to __generic_morestack. That then returns to the caller of
|
||||
# the original caller.
|
||||
|
||||
|
||||
# The amount of extra space we ask for. In general this has to be
|
||||
# enough for the dynamic loader to find a symbol and for a signal
|
||||
# handler to run.
|
||||
|
||||
#ifndef __x86_64__
|
||||
#define BACKOFF (1024)
|
||||
#else
|
||||
#define BACKOFF (1536)
|
||||
#endif
|
||||
|
||||
|
||||
# The amount of space we ask for when calling non-split-stack code.
|
||||
#define NON_SPLIT_STACK 0x100000
|
||||
|
||||
# This entry point is for split-stack code which calls non-split-stack
|
||||
# code. When the linker sees this case, it converts the call to
|
||||
# __morestack to call __morestack_non_split instead. We just bump the
|
||||
# requested stack space by 16K.
|
||||
|
||||
.global __morestack_non_split
|
||||
.hidden __morestack_non_split
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack_non_split,@function
|
||||
#endif
|
||||
|
||||
__morestack_non_split:
|
||||
.cfi_startproc
|
||||
|
||||
#ifndef __x86_64__
|
||||
|
||||
# See below for an extended explanation of this.
|
||||
.cfi_def_cfa %esp,16
|
||||
|
||||
pushl %eax # Save %eax in case it is a parameter.
|
||||
|
||||
.cfi_adjust_cfa_offset 4 # Account for pushed register.
|
||||
|
||||
movl %esp,%eax # Current stack,
|
||||
subl 8(%esp),%eax # less required stack frame size,
|
||||
subl $NON_SPLIT_STACK,%eax # less space for non-split code.
|
||||
cmpl %gs:0x30,%eax # See if we have enough space.
|
||||
jb 2f # Get more space if we need it.
|
||||
|
||||
# Here the stack is
|
||||
# %esp + 20: stack pointer after two returns
|
||||
# %esp + 16: return address of morestack caller's caller
|
||||
# %esp + 12: size of parameters
|
||||
# %esp + 8: new stack frame size
|
||||
# %esp + 4: return address of this function
|
||||
# %esp: saved %eax
|
||||
#
|
||||
# Since we aren't doing a full split stack, we don't need to
|
||||
# do anything when our caller returns. So we return to our
|
||||
# caller rather than calling it, and let it return as usual.
|
||||
# To make that work we adjust the return address.
|
||||
|
||||
# This breaks call/return address prediction for the call to
|
||||
# this function. I can't figure out a way to make it work
|
||||
# short of copying the parameters down the stack, which will
|
||||
# probably take more clock cycles than we will lose breaking
|
||||
# call/return address prediction. We will only break
|
||||
# prediction for this call, not for our caller.
|
||||
|
||||
movl 4(%esp),%eax # Increment the return address
|
||||
cmpb $0xc3,(%eax) # to skip the ret instruction;
|
||||
je 1f # see above.
|
||||
addl $2,%eax
|
||||
1: inc %eax
|
||||
|
||||
# If the instruction that we return to is
|
||||
# leal 20(%ebp),{%eax,%ecx,%edx}
|
||||
# then we have been called by a varargs function that expects
|
||||
# %ebp to hold a real value. That can only work if we do the
|
||||
# full stack split routine. FIXME: This is fragile.
|
||||
cmpb $0x8d,(%eax)
|
||||
jne 3f
|
||||
cmpb $0x14,2(%eax)
|
||||
jne 3f
|
||||
cmpb $0x45,1(%eax)
|
||||
je 2f
|
||||
cmpb $0x4d,1(%eax)
|
||||
je 2f
|
||||
cmpb $0x55,1(%eax)
|
||||
je 2f
|
||||
|
||||
3:
|
||||
movl %eax,4(%esp) # Update return address.
|
||||
|
||||
popl %eax # Restore %eax and stack.
|
||||
|
||||
.cfi_adjust_cfa_offset -4 # Account for popped register.
|
||||
|
||||
ret $8 # Return to caller, popping args.
|
||||
|
||||
2:
|
||||
.cfi_adjust_cfa_offset 4 # Back to where we were.
|
||||
|
||||
popl %eax # Restore %eax and stack.
|
||||
|
||||
.cfi_adjust_cfa_offset -4 # Account for popped register.
|
||||
|
||||
# Increment space we request.
|
||||
addl $NON_SPLIT_STACK+0x1000+BACKOFF,4(%esp)
|
||||
|
||||
# Fall through into morestack.
|
||||
|
||||
#else
|
||||
|
||||
# See below for an extended explanation of this.
|
||||
.cfi_def_cfa %rsp,16
|
||||
|
||||
pushq %rax # Save %rax in case caller is using
|
||||
# it to preserve original %r10.
|
||||
.cfi_adjust_cfa_offset 8 # Adjust for pushed register.
|
||||
|
||||
movq %rsp,%rax # Current stack,
|
||||
subq %r10,%rax # less required stack frame size,
|
||||
subq $NON_SPLIT_STACK,%rax # less space for non-split code.
|
||||
|
||||
#ifdef __LP64__
|
||||
cmpq %fs:0x70,%rax # See if we have enough space.
|
||||
#else
|
||||
cmpl %fs:0x40,%eax
|
||||
#endif
|
||||
|
||||
jb 2f # Get more space if we need it.
|
||||
|
||||
# If the instruction that we return to is
|
||||
# leaq 24(%rbp), %r11n
|
||||
# then we have been called by a varargs function that expects
|
||||
# %ebp to hold a real value. That can only work if we do the
|
||||
# full stack split routine. FIXME: This is fragile.
|
||||
movq 8(%rsp),%rax
|
||||
incq %rax # Skip ret instruction in caller.
|
||||
cmpl $0x185d8d4c,(%rax)
|
||||
je 2f
|
||||
|
||||
# This breaks call/return prediction, as described above.
|
||||
incq 8(%rsp) # Increment the return address.
|
||||
|
||||
popq %rax # Restore register.
|
||||
|
||||
.cfi_adjust_cfa_offset -8 # Adjust for popped register.
|
||||
|
||||
ret # Return to caller.
|
||||
|
||||
2:
|
||||
popq %rax # Restore register.
|
||||
|
||||
.cfi_adjust_cfa_offset -8 # Adjust for popped register.
|
||||
|
||||
# Increment space we request.
|
||||
addq $NON_SPLIT_STACK+0x1000+BACKOFF,%r10
|
||||
|
||||
# Fall through into morestack.
|
||||
|
||||
#endif
|
||||
|
||||
.cfi_endproc
|
||||
#ifdef __ELF__
|
||||
.size __morestack_non_split, . - __morestack_non_split
|
||||
#endif
|
||||
|
||||
# __morestack_non_split falls through into __morestack.
|
||||
|
||||
|
||||
# The __morestack function.
|
||||
|
||||
.global __morestack
|
||||
.hidden __morestack
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack,@function
|
||||
#endif
|
||||
|
||||
__morestack:
|
||||
.LFB1:
|
||||
.cfi_startproc
|
||||
|
||||
|
||||
#ifndef __x86_64__
|
||||
|
||||
|
||||
# The 32-bit __morestack function.
|
||||
|
||||
# We use a cleanup to restore the stack guard if an exception
|
||||
# is thrown through this code.
|
||||
#ifndef __PIC__
|
||||
.cfi_personality 0,__gcc_personality_v0
|
||||
.cfi_lsda 0,.LLSDA1
|
||||
#else
|
||||
.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
|
||||
.cfi_lsda 0x1b,.LLSDA1
|
||||
#endif
|
||||
|
||||
# We return below with a ret $8. We will return to a single
|
||||
# return instruction, which will return to the caller of our
|
||||
# caller. We let the unwinder skip that single return
|
||||
# instruction, and just return to the real caller.
|
||||
|
||||
# Here CFA points just past the return address on the stack,
|
||||
# e.g., on function entry it is %esp + 4. The stack looks
|
||||
# like this:
|
||||
# CFA + 12: stack pointer after two returns
|
||||
# CFA + 8: return address of morestack caller's caller
|
||||
# CFA + 4: size of parameters
|
||||
# CFA: new stack frame size
|
||||
# CFA - 4: return address of this function
|
||||
# CFA - 8: previous value of %ebp; %ebp points here
|
||||
# Setting the new CFA to be the current CFA + 12 (i.e., %esp +
|
||||
# 16) will make the unwinder pick up the right return address.
|
||||
|
||||
.cfi_def_cfa %esp,16
|
||||
|
||||
pushl %ebp
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_offset %ebp, -20
|
||||
movl %esp,%ebp
|
||||
.cfi_def_cfa_register %ebp
|
||||
|
||||
# In 32-bit mode the parameters are pushed on the stack. The
|
||||
# argument size is pushed then the new stack frame size is
|
||||
# pushed.
|
||||
|
||||
# In the body of a non-leaf function, the stack pointer will
|
||||
# be aligned to a 16-byte boundary. That is CFA + 12 in the
|
||||
# stack picture above: (CFA + 12) % 16 == 0. At this point we
|
||||
# have %esp == CFA - 8, so %esp % 16 == 12. We need some
|
||||
# space for saving registers and passing parameters, and we
|
||||
# need to wind up with %esp % 16 == 0.
|
||||
subl $44,%esp
|
||||
|
||||
# Because our cleanup code may need to clobber %ebx, we need
|
||||
# to save it here so the unwinder can restore the value used
|
||||
# by the caller. Note that we don't have to restore the
|
||||
# register, since we don't change it, we just have to save it
|
||||
# for the unwinder.
|
||||
movl %ebx,-4(%ebp)
|
||||
.cfi_offset %ebx, -24
|
||||
|
||||
# In 32-bit mode the registers %eax, %edx, and %ecx may be
|
||||
# used for parameters, depending on the regparm and fastcall
|
||||
# attributes.
|
||||
|
||||
movl %eax,-8(%ebp)
|
||||
movl %edx,-12(%ebp)
|
||||
movl %ecx,-16(%ebp)
|
||||
|
||||
call __morestack_block_signals
|
||||
|
||||
movl 12(%ebp),%eax # The size of the parameters.
|
||||
movl %eax,8(%esp)
|
||||
leal 20(%ebp),%eax # Address of caller's parameters.
|
||||
movl %eax,4(%esp)
|
||||
addl $BACKOFF,8(%ebp) # Ask for backoff bytes.
|
||||
leal 8(%ebp),%eax # The address of the new frame size.
|
||||
movl %eax,(%esp)
|
||||
|
||||
call __generic_morestack
|
||||
|
||||
movl %eax,%esp # Switch to the new stack.
|
||||
subl 8(%ebp),%eax # The end of the stack space.
|
||||
addl $BACKOFF,%eax # Back off 512 bytes.
|
||||
|
||||
.LEHB0:
|
||||
# FIXME: The offset must match
|
||||
# TARGET_THREAD_SPLIT_STACK_OFFSET in
|
||||
# gcc/config/i386/linux.h.
|
||||
movl %eax,%gs:0x30 # Save the new stack boundary.
|
||||
|
||||
call __morestack_unblock_signals
|
||||
|
||||
movl -12(%ebp),%edx # Restore registers.
|
||||
movl -16(%ebp),%ecx
|
||||
|
||||
movl 4(%ebp),%eax # Increment the return address
|
||||
cmpb $0xc3,(%eax) # to skip the ret instruction;
|
||||
je 1f # see above.
|
||||
addl $2,%eax
|
||||
1: inc %eax
|
||||
|
||||
movl %eax,-12(%ebp) # Store return address in an
|
||||
# unused slot.
|
||||
|
||||
movl -8(%ebp),%eax # Restore the last register.
|
||||
|
||||
call *-12(%ebp) # Call our caller!
|
||||
|
||||
# The caller will return here, as predicted.
|
||||
|
||||
# Save the registers which may hold a return value. We
|
||||
# assume that __generic_releasestack does not touch any
|
||||
# floating point or vector registers.
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
|
||||
# Push the arguments to __generic_releasestack now so that the
|
||||
# stack is at a 16-byte boundary for
|
||||
# __morestack_block_signals.
|
||||
pushl $0 # Where the available space is returned.
|
||||
leal 0(%esp),%eax # Push its address.
|
||||
push %eax
|
||||
|
||||
call __morestack_block_signals
|
||||
|
||||
call __generic_releasestack
|
||||
|
||||
subl 4(%esp),%eax # Subtract available space.
|
||||
addl $BACKOFF,%eax # Back off 512 bytes.
|
||||
.LEHE0:
|
||||
movl %eax,%gs:0x30 # Save the new stack boundary.
|
||||
|
||||
addl $8,%esp # Remove values from stack.
|
||||
|
||||
# We need to restore the old stack pointer, which is in %rbp,
|
||||
# before we unblock signals. We also need to restore %eax and
|
||||
# %edx after we unblock signals but before we return. Do this
|
||||
# by moving %eax and %edx from the current stack to the old
|
||||
# stack.
|
||||
|
||||
popl %edx # Pop return value from current stack.
|
||||
popl %eax
|
||||
|
||||
movl %ebp,%esp # Restore stack pointer.
|
||||
|
||||
# As before, we now have %esp % 16 == 12.
|
||||
|
||||
pushl %eax # Push return value on old stack.
|
||||
pushl %edx
|
||||
subl $4,%esp # Align stack to 16-byte boundary.
|
||||
|
||||
call __morestack_unblock_signals
|
||||
|
||||
addl $4,%esp
|
||||
popl %edx # Restore return value.
|
||||
popl %eax
|
||||
|
||||
.cfi_remember_state
|
||||
|
||||
# We never changed %ebx, so we don't have to actually restore it.
|
||||
.cfi_restore %ebx
|
||||
|
||||
popl %ebp
|
||||
.cfi_restore %ebp
|
||||
.cfi_def_cfa %esp, 16
|
||||
ret $8 # Return to caller, which will
|
||||
# immediately return. Pop
|
||||
# arguments as we go.
|
||||
|
||||
# This is the cleanup code called by the stack unwinder when unwinding
|
||||
# through the code between .LEHB0 and .LEHE0 above.
|
||||
|
||||
.L1:
|
||||
.cfi_restore_state
|
||||
subl $16,%esp # Maintain 16 byte alignment.
|
||||
movl %eax,4(%esp) # Save exception header.
|
||||
movl %ebp,(%esp) # Stack pointer after resume.
|
||||
call __generic_findstack
|
||||
movl %ebp,%ecx # Get the stack pointer.
|
||||
subl %eax,%ecx # Subtract available space.
|
||||
addl $BACKOFF,%ecx # Back off 512 bytes.
|
||||
movl %ecx,%gs:0x30 # Save new stack boundary.
|
||||
movl 4(%esp),%eax # Function argument.
|
||||
movl %eax,(%esp)
|
||||
#ifdef __PIC__
|
||||
call __x86.get_pc_thunk.bx # %ebx may not be set up for us.
|
||||
addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
||||
call _Unwind_Resume@PLT # Resume unwinding.
|
||||
#else
|
||||
call _Unwind_Resume
|
||||
#endif
|
||||
|
||||
#else /* defined(__x86_64__) */
|
||||
|
||||
|
||||
# The 64-bit __morestack function.
|
||||
|
||||
# We use a cleanup to restore the stack guard if an exception
|
||||
# is thrown through this code.
|
||||
#ifndef __PIC__
|
||||
.cfi_personality 0x3,__gcc_personality_v0
|
||||
.cfi_lsda 0x3,.LLSDA1
|
||||
#else
|
||||
.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
|
||||
.cfi_lsda 0x1b,.LLSDA1
|
||||
#endif
|
||||
|
||||
# We will return a single return instruction, which will
|
||||
# return to the caller of our caller. Let the unwinder skip
|
||||
# that single return instruction, and just return to the real
|
||||
# caller.
|
||||
.cfi_def_cfa %rsp,16
|
||||
|
||||
# Set up a normal backtrace.
|
||||
pushq %rbp
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_offset %rbp, -24
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
|
||||
# In 64-bit mode the new stack frame size is passed in r10
|
||||
# and the argument size is passed in r11.
|
||||
|
||||
addq $BACKOFF,%r10 # Ask for backoff bytes.
|
||||
pushq %r10 # Save new frame size.
|
||||
|
||||
# In 64-bit mode the registers %rdi, %rsi, %rdx, %rcx, %r8,
|
||||
# and %r9 may be used for parameters. We also preserve %rax
|
||||
# which the caller may use to hold %r10.
|
||||
|
||||
pushq %rax
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %rdx
|
||||
pushq %rcx
|
||||
pushq %r8
|
||||
pushq %r9
|
||||
|
||||
pushq %r11
|
||||
|
||||
# We entered morestack with the stack pointer aligned to a
|
||||
# 16-byte boundary (the call to morestack's caller used 8
|
||||
# bytes, and the call to morestack used 8 bytes). We have now
|
||||
# pushed 10 registers, so we are still aligned to a 16-byte
|
||||
# boundary.
|
||||
|
||||
call __morestack_block_signals
|
||||
|
||||
leaq -8(%rbp),%rdi # Address of new frame size.
|
||||
leaq 24(%rbp),%rsi # The caller's parameters.
|
||||
popq %rdx # The size of the parameters.
|
||||
|
||||
subq $8,%rsp # Align stack.
|
||||
|
||||
call __generic_morestack
|
||||
|
||||
movq -8(%rbp),%r10 # Reload modified frame size
|
||||
movq %rax,%rsp # Switch to the new stack.
|
||||
subq %r10,%rax # The end of the stack space.
|
||||
addq $BACKOFF,%rax # Back off 1024 bytes.
|
||||
|
||||
.LEHB0:
|
||||
# FIXME: The offset must match
|
||||
# TARGET_THREAD_SPLIT_STACK_OFFSET in
|
||||
# gcc/config/i386/linux64.h.
|
||||
# Macro to save the new stack boundary.
|
||||
#ifdef __LP64__
|
||||
#define X86_64_SAVE_NEW_STACK_BOUNDARY(reg) movq %r##reg,%fs:0x70
|
||||
#else
|
||||
#define X86_64_SAVE_NEW_STACK_BOUNDARY(reg) movl %e##reg,%fs:0x40
|
||||
#endif
|
||||
X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
|
||||
|
||||
call __morestack_unblock_signals
|
||||
|
||||
movq -24(%rbp),%rdi # Restore registers.
|
||||
movq -32(%rbp),%rsi
|
||||
movq -40(%rbp),%rdx
|
||||
movq -48(%rbp),%rcx
|
||||
movq -56(%rbp),%r8
|
||||
movq -64(%rbp),%r9
|
||||
|
||||
movq 8(%rbp),%r10 # Increment the return address
|
||||
incq %r10 # to skip the ret instruction;
|
||||
# see above.
|
||||
|
||||
movq -16(%rbp),%rax # Restore caller's %rax.
|
||||
|
||||
call *%r10 # Call our caller!
|
||||
|
||||
# The caller will return here, as predicted.
|
||||
|
||||
# Save the registers which may hold a return value. We
|
||||
# assume that __generic_releasestack does not touch any
|
||||
# floating point or vector registers.
|
||||
pushq %rax
|
||||
pushq %rdx
|
||||
|
||||
call __morestack_block_signals
|
||||
|
||||
pushq $0 # For alignment.
|
||||
pushq $0 # Where the available space is returned.
|
||||
leaq 0(%rsp),%rdi # Pass its address.
|
||||
|
||||
call __generic_releasestack
|
||||
|
||||
subq 0(%rsp),%rax # Subtract available space.
|
||||
addq $BACKOFF,%rax # Back off 1024 bytes.
|
||||
.LEHE0:
|
||||
X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
|
||||
|
||||
addq $16,%rsp # Remove values from stack.
|
||||
|
||||
# We need to restore the old stack pointer, which is in %rbp,
|
||||
# before we unblock signals. We also need to restore %rax and
|
||||
# %rdx after we unblock signals but before we return. Do this
|
||||
# by moving %rax and %rdx from the current stack to the old
|
||||
# stack.
|
||||
|
||||
popq %rdx # Pop return value from current stack.
|
||||
popq %rax
|
||||
|
||||
movq %rbp,%rsp # Restore stack pointer.
|
||||
|
||||
# Now (%rsp & 16) == 8.
|
||||
|
||||
subq $8,%rsp # For alignment.
|
||||
pushq %rax # Push return value on old stack.
|
||||
pushq %rdx
|
||||
|
||||
call __morestack_unblock_signals
|
||||
|
||||
popq %rdx # Restore return value.
|
||||
popq %rax
|
||||
addq $8,%rsp
|
||||
|
||||
.cfi_remember_state
|
||||
popq %rbp
|
||||
.cfi_restore %rbp
|
||||
.cfi_def_cfa %rsp, 16
|
||||
ret # Return to caller, which will
|
||||
# immediately return.
|
||||
|
||||
# This is the cleanup code called by the stack unwinder when unwinding
|
||||
# through the code between .LEHB0 and .LEHE0 above.
|
||||
|
||||
.L1:
|
||||
.cfi_restore_state
|
||||
subq $16,%rsp # Maintain 16 byte alignment.
|
||||
movq %rax,(%rsp) # Save exception header.
|
||||
movq %rbp,%rdi # Stack pointer after resume.
|
||||
call __generic_findstack
|
||||
movq %rbp,%rcx # Get the stack pointer.
|
||||
subq %rax,%rcx # Subtract available space.
|
||||
addq $BACKOFF,%rcx # Back off 1024 bytes.
|
||||
X86_64_SAVE_NEW_STACK_BOUNDARY (cx)
|
||||
movq (%rsp),%rdi # Restore exception data for call.
|
||||
#ifdef __PIC__
|
||||
call _Unwind_Resume@PLT # Resume unwinding.
|
||||
#else
|
||||
call _Unwind_Resume # Resume unwinding.
|
||||
#endif
|
||||
|
||||
#endif /* defined(__x86_64__) */
|
||||
|
||||
.cfi_endproc
|
||||
#ifdef __ELF__
|
||||
.size __morestack, . - __morestack
|
||||
#endif
|
||||
|
||||
#if !defined(__x86_64__) && defined(__PIC__)
|
||||
# Output the thunk to get PC into bx, since we use it above.
|
||||
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
|
||||
.globl __x86.get_pc_thunk.bx
|
||||
.hidden __x86.get_pc_thunk.bx
|
||||
#ifdef __ELF__
|
||||
.type __x86.get_pc_thunk.bx, @function
|
||||
#endif
|
||||
__x86.get_pc_thunk.bx:
|
||||
.cfi_startproc
|
||||
movl (%esp), %ebx
|
||||
ret
|
||||
.cfi_endproc
|
||||
#ifdef __ELF__
|
||||
.size __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# The exception table. This tells the personality routine to execute
|
||||
# the exception handler.
|
||||
|
||||
.section .gcc_except_table,"a",@progbits
|
||||
.align 4
|
||||
.LLSDA1:
|
||||
.byte 0xff # @LPStart format (omit)
|
||||
.byte 0xff # @TType format (omit)
|
||||
.byte 0x1 # call-site format (uleb128)
|
||||
.uleb128 .LLSDACSE1-.LLSDACSB1 # Call-site table length
|
||||
.LLSDACSB1:
|
||||
.uleb128 .LEHB0-.LFB1 # region 0 start
|
||||
.uleb128 .LEHE0-.LEHB0 # length
|
||||
.uleb128 .L1-.LFB1 # landing pad
|
||||
.uleb128 0 # action
|
||||
.LLSDACSE1:
|
||||
|
||||
|
||||
.global __gcc_personality_v0
|
||||
#ifdef __PIC__
|
||||
# Build a position independent reference to the basic
|
||||
# personality function.
|
||||
.hidden DW.ref.__gcc_personality_v0
|
||||
.weak DW.ref.__gcc_personality_v0
|
||||
.section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat
|
||||
.type DW.ref.__gcc_personality_v0, @object
|
||||
DW.ref.__gcc_personality_v0:
|
||||
#ifndef __LP64__
|
||||
.align 4
|
||||
.size DW.ref.__gcc_personality_v0, 4
|
||||
.long __gcc_personality_v0
|
||||
#else
|
||||
.align 8
|
||||
.size DW.ref.__gcc_personality_v0, 8
|
||||
.quad __gcc_personality_v0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined __x86_64__ && defined __LP64__
|
||||
|
||||
# This entry point is used for the large model. With this entry point
|
||||
# the upper 32 bits of %r10 hold the argument size and the lower 32
|
||||
# bits hold the new stack frame size. There doesn't seem to be a way
|
||||
# to know in the assembler code that we are assembling for the large
|
||||
# model, and there doesn't seem to be a large model multilib anyhow.
|
||||
# If one is developed, then the non-PIC code is probably OK since we
|
||||
# will probably be close to the morestack code, but the PIC code
|
||||
# almost certainly needs to be changed. FIXME.
|
||||
|
||||
.text
|
||||
.global __morestack_large_model
|
||||
.hidden __morestack_large_model
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack_large_model,@function
|
||||
#endif
|
||||
|
||||
__morestack_large_model:
|
||||
|
||||
.cfi_startproc
|
||||
|
||||
movq %r10, %r11
|
||||
andl $0xffffffff, %r10d
|
||||
sarq $32, %r11
|
||||
jmp __morestack
|
||||
|
||||
.cfi_endproc
|
||||
#ifdef __ELF__
|
||||
.size __morestack_large_model, . - __morestack_large_model
|
||||
#endif
|
||||
|
||||
#endif /* __x86_64__ && __LP64__ */
|
||||
|
||||
# Initialize the stack test value when the program starts or when a
|
||||
# new thread starts. We don't know how large the main stack is, so we
|
||||
# guess conservatively. We might be able to use getrlimit here.
|
||||
|
||||
.text
|
||||
.global __stack_split_initialize
|
||||
.hidden __stack_split_initialize
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __stack_split_initialize, @function
|
||||
#endif
|
||||
|
||||
__stack_split_initialize:
|
||||
|
||||
#ifndef __x86_64__
|
||||
|
||||
leal -16000(%esp),%eax # We should have at least 16K.
|
||||
movl %eax,%gs:0x30
|
||||
subl $4,%esp # Align stack.
|
||||
pushl $16000
|
||||
pushl %esp
|
||||
#ifdef __PIC__
|
||||
call __generic_morestack_set_initial_sp@PLT
|
||||
#else
|
||||
call __generic_morestack_set_initial_sp
|
||||
#endif
|
||||
addl $12,%esp
|
||||
ret
|
||||
|
||||
#else /* defined(__x86_64__) */
|
||||
|
||||
leaq -16000(%rsp),%rax # We should have at least 16K.
|
||||
X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
|
||||
subq $8,%rsp # Align stack.
|
||||
movq %rsp,%rdi
|
||||
movq $16000,%rsi
|
||||
#ifdef __PIC__
|
||||
call __generic_morestack_set_initial_sp@PLT
|
||||
#else
|
||||
call __generic_morestack_set_initial_sp
|
||||
#endif
|
||||
addq $8,%rsp
|
||||
ret
|
||||
|
||||
#endif /* defined(__x86_64__) */
|
||||
|
||||
#ifdef __ELF__
|
||||
.size __stack_split_initialize, . - __stack_split_initialize
|
||||
#endif
|
||||
|
||||
# Routines to get and set the guard, for __splitstack_getcontext,
|
||||
# __splitstack_setcontext, and __splitstack_makecontext.
|
||||
|
||||
# void *__morestack_get_guard (void) returns the current stack guard.
|
||||
.text
|
||||
.global __morestack_get_guard
|
||||
.hidden __morestack_get_guard
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack_get_guard,@function
|
||||
#endif
|
||||
|
||||
__morestack_get_guard:
|
||||
|
||||
#ifndef __x86_64__
|
||||
movl %gs:0x30,%eax
|
||||
#else
|
||||
#ifdef __LP64__
|
||||
movq %fs:0x70,%rax
|
||||
#else
|
||||
movl %fs:0x40,%eax
|
||||
#endif
|
||||
#endif
|
||||
ret
|
||||
|
||||
#ifdef __ELF__
|
||||
.size __morestack_get_guard, . - __morestack_get_guard
|
||||
#endif
|
||||
|
||||
# void __morestack_set_guard (void *) sets the stack guard.
|
||||
.global __morestack_set_guard
|
||||
.hidden __morestack_set_guard
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack_set_guard,@function
|
||||
#endif
|
||||
|
||||
__morestack_set_guard:
|
||||
|
||||
#ifndef __x86_64__
|
||||
movl 4(%esp),%eax
|
||||
movl %eax,%gs:0x30
|
||||
#else
|
||||
X86_64_SAVE_NEW_STACK_BOUNDARY (di)
|
||||
#endif
|
||||
ret
|
||||
|
||||
#ifdef __ELF__
|
||||
.size __morestack_set_guard, . - __morestack_set_guard
|
||||
#endif
|
||||
|
||||
# void *__morestack_make_guard (void *, size_t) returns the stack
|
||||
# guard value for a stack.
|
||||
.global __morestack_make_guard
|
||||
.hidden __morestack_make_guard
|
||||
|
||||
#ifdef __ELF__
|
||||
.type __morestack_make_guard,@function
|
||||
#endif
|
||||
|
||||
__morestack_make_guard:
|
||||
|
||||
#ifndef __x86_64__
|
||||
movl 4(%esp),%eax
|
||||
subl 8(%esp),%eax
|
||||
addl $BACKOFF,%eax
|
||||
#else
|
||||
subq %rsi,%rdi
|
||||
addq $BACKOFF,%rdi
|
||||
movq %rdi,%rax
|
||||
#endif
|
||||
ret
|
||||
|
||||
#ifdef __ELF__
|
||||
.size __morestack_make_guard, . - __morestack_make_guard
|
||||
#endif
|
||||
|
||||
# Make __stack_split_initialize a high priority constructor. FIXME:
|
||||
# This is ELF specific.
|
||||
|
||||
.section .ctors.65535,"aw",@progbits
|
||||
|
||||
#ifndef __LP64__
|
||||
.align 4
|
||||
.long __stack_split_initialize
|
||||
.long __morestack_load_mmap
|
||||
#else
|
||||
.align 8
|
||||
.quad __stack_split_initialize
|
||||
.quad __morestack_load_mmap
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
.section .note.GNU-split-stack,"",@progbits
|
||||
.section .note.GNU-no-split-stack,"",@progbits
|
||||
#endif
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 3, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* Under Section 7 of GPL version 3, you are granted additional
|
||||
* permissions described in the GCC Runtime Library Exception, version
|
||||
* 3.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License and
|
||||
* a copy of the GCC Runtime Library Exception along with this program;
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#include "sfp-machine.h"
|
||||
|
||||
struct fenv
|
||||
{
|
||||
unsigned short int __control_word;
|
||||
unsigned short int __unused1;
|
||||
unsigned short int __status_word;
|
||||
unsigned short int __unused2;
|
||||
unsigned short int __tags;
|
||||
unsigned short int __unused3;
|
||||
unsigned int __eip;
|
||||
unsigned short int __cs_selector;
|
||||
unsigned int __opcode:11;
|
||||
unsigned int __unused4:5;
|
||||
unsigned int __data_offset;
|
||||
unsigned short int __data_selector;
|
||||
unsigned short int __unused5;
|
||||
};
|
||||
|
||||
void
|
||||
__sfp_handle_exceptions (int _fex)
|
||||
{
|
||||
if (_fex & FP_EX_INVALID)
|
||||
{
|
||||
float f = 0.0f;
|
||||
#ifdef __SSE_MATH__
|
||||
volatile float r __attribute__ ((unused));
|
||||
asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
|
||||
r = f; /* Needed to trigger exception. */
|
||||
#else
|
||||
asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
|
||||
/* No need for fwait, exception is triggered by emitted fstp. */
|
||||
#endif
|
||||
}
|
||||
if (_fex & FP_EX_DENORM)
|
||||
{
|
||||
struct fenv temp;
|
||||
asm volatile ("fnstenv\t%0" : "=m" (temp));
|
||||
temp.__status_word |= FP_EX_DENORM;
|
||||
asm volatile ("fldenv\t%0" : : "m" (temp));
|
||||
asm volatile ("fwait");
|
||||
}
|
||||
if (_fex & FP_EX_DIVZERO)
|
||||
{
|
||||
float f = 1.0f, g = 0.0f;
|
||||
#ifdef __SSE_MATH__
|
||||
volatile float r __attribute__ ((unused));
|
||||
asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
|
||||
r = f; /* Needed to trigger exception. */
|
||||
#else
|
||||
asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
|
||||
/* No need for fwait, exception is triggered by emitted fstp. */
|
||||
#endif
|
||||
}
|
||||
if (_fex & FP_EX_OVERFLOW)
|
||||
{
|
||||
struct fenv temp;
|
||||
asm volatile ("fnstenv\t%0" : "=m" (temp));
|
||||
temp.__status_word |= FP_EX_OVERFLOW;
|
||||
asm volatile ("fldenv\t%0" : : "m" (temp));
|
||||
asm volatile ("fwait");
|
||||
}
|
||||
if (_fex & FP_EX_UNDERFLOW)
|
||||
{
|
||||
struct fenv temp;
|
||||
asm volatile ("fnstenv\t%0" : "=m" (temp));
|
||||
temp.__status_word |= FP_EX_UNDERFLOW;
|
||||
asm volatile ("fldenv\t%0" : : "m" (temp));
|
||||
asm volatile ("fwait");
|
||||
}
|
||||
if (_fex & FP_EX_INEXACT)
|
||||
{
|
||||
float f = 1.0f, g = 3.0f;
|
||||
#ifdef __SSE_MATH__
|
||||
volatile float r __attribute__ ((unused));
|
||||
asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
|
||||
r = f; /* Needed to trigger exception. */
|
||||
#else
|
||||
asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
|
||||
/* No need for fwait, exception is triggered by emitted fstp. */
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,85 @@
|
|||
#ifdef __MINGW32__
|
||||
/* Make sure we are using gnu-style bitfield handling. */
|
||||
#define _FP_STRUCT_LAYOUT __attribute__ ((gcc_struct))
|
||||
#endif
|
||||
|
||||
/* The type of the result of a floating point comparison. This must
|
||||
match `__libgcc_cmp_return__' in GCC for the target. */
|
||||
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
|
||||
#define CMPtype __gcc_CMPtype
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "config/i386/64/sfp-machine.h"
|
||||
#else
|
||||
#include "config/i386/32/sfp-machine.h"
|
||||
#endif
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
#define _FP_NANSIGN_S 1
|
||||
#define _FP_NANSIGN_D 1
|
||||
#define _FP_NANSIGN_E 1
|
||||
#define _FP_NANSIGN_Q 1
|
||||
|
||||
/* Here is something Intel misdesigned: the specs don't define
|
||||
the case where we have two NaNs with same mantissas, but
|
||||
different sign. Different operations pick up different NaNs. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
do { \
|
||||
if (_FP_FRAC_GT_##wc(X, Y) \
|
||||
|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
|
||||
{ \
|
||||
R##_s = X##_s; \
|
||||
_FP_FRAC_COPY_##wc(R,X); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
R##_s = Y##_s; \
|
||||
_FP_FRAC_COPY_##wc(R,Y); \
|
||||
} \
|
||||
R##_c = FP_CLS_NAN; \
|
||||
} while (0)
|
||||
|
||||
#ifndef _SOFT_FLOAT
|
||||
#define FP_EX_INVALID 0x01
|
||||
#define FP_EX_DENORM 0x02
|
||||
#define FP_EX_DIVZERO 0x04
|
||||
#define FP_EX_OVERFLOW 0x08
|
||||
#define FP_EX_UNDERFLOW 0x10
|
||||
#define FP_EX_INEXACT 0x20
|
||||
#define FP_EX_ALL \
|
||||
(FP_EX_INVALID | FP_EX_DENORM | FP_EX_DIVZERO | FP_EX_OVERFLOW \
|
||||
| FP_EX_UNDERFLOW | FP_EX_INEXACT)
|
||||
|
||||
void __sfp_handle_exceptions (int);
|
||||
|
||||
#define FP_HANDLE_EXCEPTIONS \
|
||||
do { \
|
||||
if (__builtin_expect (_fex, 0)) \
|
||||
__sfp_handle_exceptions (_fex); \
|
||||
} while (0);
|
||||
|
||||
#define FP_TRAPPING_EXCEPTIONS ((~_fcw >> FP_EX_SHIFT) & FP_EX_ALL)
|
||||
|
||||
#define FP_ROUNDMODE (_fcw & FP_RND_MASK)
|
||||
#endif
|
||||
|
||||
#define _FP_TININESS_AFTER_ROUNDING 1
|
||||
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
|
||||
/* Define ALIASNAME as a strong alias for NAME. */
|
||||
#if defined __MACH__
|
||||
/* Mach-O doesn't support aliasing. If these functions ever return
|
||||
anything but CMPtype we need to revisit this... */
|
||||
#define strong_alias(name, aliasname) \
|
||||
CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
|
||||
#else
|
||||
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
||||
# define _strong_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
/* crt1.s for Solaris 2, x86
|
||||
|
||||
Copyright (C) 1993-2017 Free Software Foundation, Inc.
|
||||
Written By Fred Fish, Nov 1992
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This file takes control of the process from the kernel, as specified
|
||||
in section 3 of the System V Application Binary Interface, Intel386
|
||||
Processor Supplement. It has been constructed from information obtained
|
||||
from the ABI, information obtained from single stepping existing
|
||||
Solaris executables through their startup code with gdb, and from
|
||||
information obtained by single stepping executables on other i386 SVR4
|
||||
implementations. This file is the first thing linked into any
|
||||
executable. */
|
||||
|
||||
#ifndef GCRT1
|
||||
.ident "GNU C crt1.s"
|
||||
#define CLEANUP _cleanup
|
||||
#else
|
||||
/* This is a modified crt1.s by J.W.Hawtin <oolon@ankh.org> 15/8/96,
|
||||
to allow program profiling, by calling monstartup on entry and _mcleanup
|
||||
on exit. */
|
||||
.ident "GNU C gcrt1.s"
|
||||
#define CLEANUP _mcleanup
|
||||
#endif
|
||||
.weak _cleanup
|
||||
.weak _DYNAMIC
|
||||
.text
|
||||
|
||||
/* Start creating the initial frame by pushing a NULL value for the return
|
||||
address of the initial frame, and mark the end of the stack frame chain
|
||||
(the innermost stack frame) with a NULL value, per page 3-32 of the ABI.
|
||||
Initialize the first stack frame pointer in %ebp (the contents of which
|
||||
are unspecified at process initialization). */
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
pushl $0x0
|
||||
pushl $0x0
|
||||
movl %esp,%ebp
|
||||
|
||||
/* As specified per page 3-32 of the ABI, %edx contains a function
|
||||
pointer that should be registered with atexit(), for proper
|
||||
shared object termination. Just push it onto the stack for now
|
||||
to preserve it. We want to register _cleanup() first. */
|
||||
|
||||
pushl %edx
|
||||
|
||||
/* Check to see if there is an _cleanup() function linked in, and if
|
||||
so, register it with atexit() as the last thing to be run by
|
||||
atexit(). */
|
||||
|
||||
movl $CLEANUP,%eax
|
||||
testl %eax,%eax
|
||||
je .L1
|
||||
pushl $CLEANUP
|
||||
call atexit
|
||||
addl $0x4,%esp
|
||||
.L1:
|
||||
|
||||
/* Now check to see if we have an _DYNAMIC table, and if so then
|
||||
we need to register the function pointer previously in %edx, but
|
||||
now conveniently saved on the stack as the argument to pass to
|
||||
atexit(). */
|
||||
|
||||
movl $_DYNAMIC,%eax
|
||||
testl %eax,%eax
|
||||
je .L2
|
||||
call atexit
|
||||
.L2:
|
||||
|
||||
/* Register _fini() with atexit(). We will take care of calling _init()
|
||||
directly. */
|
||||
|
||||
pushl $_fini
|
||||
call atexit
|
||||
|
||||
#ifdef GCRT1
|
||||
/* Start profiling. */
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl $_etext
|
||||
pushl $_start
|
||||
call monstartup
|
||||
addl $8,%esp
|
||||
popl %ebp
|
||||
#endif
|
||||
|
||||
/* Compute the address of the environment vector on the stack and load
|
||||
it into the global variable _environ. Currently argc is at 8 off
|
||||
the frame pointer. Fetch the argument count into %eax, scale by the
|
||||
size of each arg (4 bytes) and compute the address of the environment
|
||||
vector which is 16 bytes (the two zero words we pushed, plus argc,
|
||||
plus the null word terminating the arg vector) further up the stack,
|
||||
off the frame pointer (whew!). */
|
||||
|
||||
movl 8(%ebp),%eax
|
||||
leal 16(%ebp,%eax,4),%edx
|
||||
movl %edx,_environ
|
||||
|
||||
/* Push the environment vector pointer, the argument vector pointer,
|
||||
and the argument count on to the stack to set up the arguments
|
||||
for _init(), _fpstart(), and main(). Note that the environment
|
||||
vector pointer and the arg count were previously loaded into
|
||||
%edx and %eax respectively. The only new value we need to compute
|
||||
is the argument vector pointer, which is at a fixed address off
|
||||
the initial frame pointer. */
|
||||
|
||||
/* Make sure the stack is properly aligned. */
|
||||
andl $0xfffffff0,%esp
|
||||
subl $4,%esp
|
||||
|
||||
pushl %edx
|
||||
leal 12(%ebp),%edx
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
|
||||
/* Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and
|
||||
main(argc, argv, environ). */
|
||||
|
||||
call _init
|
||||
call __fpstart
|
||||
call main
|
||||
|
||||
/* Pop the argc, argv, and environ arguments off the stack, push the
|
||||
value returned from main(), and call exit(). */
|
||||
|
||||
addl $12,%esp
|
||||
pushl %eax
|
||||
call exit
|
||||
|
||||
/* An inline equivalent of _exit, as specified in Figure 3-26 of the ABI. */
|
||||
|
||||
pushl $0x0
|
||||
movl $0x1,%eax
|
||||
lcall $7,$0
|
||||
|
||||
/* If all else fails, just try a halt! */
|
||||
|
||||
hlt
|
||||
.type _start,@function
|
||||
.size _start,.-_start
|
||||
|
||||
#ifndef GCRT1
|
||||
/* A dummy profiling support routine for non-profiling executables,
|
||||
in case we link in some objects that have been compiled for profiling. */
|
||||
|
||||
.weak _mcount
|
||||
_mcount:
|
||||
ret
|
||||
.type _mcount,@function
|
||||
.size _mcount,.-_mcount
|
||||
#endif
|
|
@ -0,0 +1,244 @@
|
|||
/* DWARF2 EH unwinding support for AMD x86-64 and x86.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#include <ucontext.h>
|
||||
#include <sys/frame.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_64_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
mcontext_t *mctx;
|
||||
long new_cfa;
|
||||
|
||||
if (/* Solaris 10+
|
||||
------------
|
||||
<__sighndlr+0>: push %rbp
|
||||
<__sighndlr+1>: mov %rsp,%rbp
|
||||
<__sighndlr+4>: callq *%rcx
|
||||
<__sighndlr+6>: leaveq <--- PC
|
||||
<__sighndlr+7>: retq */
|
||||
*(unsigned long *)(pc - 6) == 0xc3c9d1ffe5894855)
|
||||
|
||||
/* We need to move up three frames:
|
||||
|
||||
<signal handler> <-- context->cfa
|
||||
__sighndlr
|
||||
call_user_handler
|
||||
sigacthandler
|
||||
<kernel>
|
||||
|
||||
context->cfa points into the frame after the saved frame pointer and
|
||||
saved pc (struct frame).
|
||||
|
||||
The ucontext_t structure is in the kernel frame after the signal
|
||||
number and a siginfo_t *. Since the frame sizes vary even within
|
||||
Solaris 10 updates, we need to walk the stack to get there. */
|
||||
{
|
||||
struct frame *fp = (struct frame *) context->cfa - 1;
|
||||
struct handler_args {
|
||||
int signo;
|
||||
siginfo_t *sip;
|
||||
ucontext_t ucontext;
|
||||
} *handler_args;
|
||||
ucontext_t *ucp;
|
||||
|
||||
/* Next frame: __sighndlr frame pointer. */
|
||||
fp = (struct frame *) fp->fr_savfp;
|
||||
/* call_user_handler frame pointer. */
|
||||
fp = (struct frame *) fp->fr_savfp;
|
||||
/* sigacthandler frame pointer. */
|
||||
fp = (struct frame *) fp->fr_savfp;
|
||||
|
||||
/* The argument area precedes the struct frame. */
|
||||
handler_args = (struct handler_args *) (fp + 1);
|
||||
ucp = &handler_args->ucontext;
|
||||
mctx = &ucp->uc_mcontext;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
new_cfa = mctx->gregs[REG_RSP];
|
||||
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = 7;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&mctx->gregs[REG_RAX] - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&mctx->gregs[REG_RDX] - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&mctx->gregs[REG_RCX] - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&mctx->gregs[REG_RBX] - new_cfa;
|
||||
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[4].loc.offset = (long)&mctx->gregs[REG_RSI] - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&mctx->gregs[REG_RDI] - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&mctx->gregs[REG_RBP] - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&mctx->gregs[REG_R8] - new_cfa;
|
||||
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[9].loc.offset = (long)&mctx->gregs[REG_R9] - new_cfa;
|
||||
fs->regs.reg[10].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[10].loc.offset = (long)&mctx->gregs[REG_R10] - new_cfa;
|
||||
fs->regs.reg[11].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[11].loc.offset = (long)&mctx->gregs[REG_R11] - new_cfa;
|
||||
fs->regs.reg[12].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[12].loc.offset = (long)&mctx->gregs[REG_R12] - new_cfa;
|
||||
fs->regs.reg[13].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[13].loc.offset = (long)&mctx->gregs[REG_R13] - new_cfa;
|
||||
fs->regs.reg[14].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[14].loc.offset = (long)&mctx->gregs[REG_R14] - new_cfa;
|
||||
fs->regs.reg[15].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[15].loc.offset = (long)&mctx->gregs[REG_R15] - new_cfa;
|
||||
fs->regs.reg[16].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[16].loc.offset = (long)&mctx->gregs[REG_RIP] - new_cfa;
|
||||
fs->retaddr_column = 16;
|
||||
fs->signal_frame = 1;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
x86_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
unsigned char *pc = context->ra;
|
||||
mcontext_t *mctx;
|
||||
long new_cfa;
|
||||
|
||||
if (/* Solaris 10
|
||||
-----------
|
||||
<__sighndlr+0>: push %ebp
|
||||
<__sighndlr+1>: mov %esp,%ebp
|
||||
<__sighndlr+3>: pushl 0x10(%ebp)
|
||||
<__sighndlr+6>: pushl 0xc(%ebp)
|
||||
<__sighndlr+9>: pushl 0x8(%ebp)
|
||||
<__sighndlr+12>: call *0x14(%ebp)
|
||||
<__sighndlr+15>: add $0xc,%esp <--- PC
|
||||
<__sighndlr+18>: leave
|
||||
<__sighndlr+19>: ret */
|
||||
(*(unsigned long *)(pc - 15) == 0xffec8b55
|
||||
&& *(unsigned long *)(pc - 11) == 0x75ff1075
|
||||
&& *(unsigned long *)(pc - 7) == 0x0875ff0c
|
||||
&& *(unsigned long *)(pc - 3) == 0x831455ff
|
||||
&& *(unsigned long *)(pc + 1) == 0xc3c90cc4)
|
||||
|
||||
|| /* Solaris 11 before snv_125
|
||||
--------------------------
|
||||
<__sighndlr+0> push %ebp
|
||||
<__sighndlr+1> mov %esp,%ebp
|
||||
<__sighndlr+4> pushl 0x10(%ebp)
|
||||
<__sighndlr+6> pushl 0xc(%ebp)
|
||||
<__sighndlr+9> pushl 0x8(%ebp)
|
||||
<__sighndlr+12> call *0x14(%ebp)
|
||||
<__sighndlr+15> add $0xc,%esp
|
||||
<__sighndlr+18> leave <--- PC
|
||||
<__sighndlr+19> ret */
|
||||
(*(unsigned long *)(pc - 18) == 0xffec8b55
|
||||
&& *(unsigned long *)(pc - 14) == 0x7fff107f
|
||||
&& *(unsigned long *)(pc - 10) == 0x0875ff0c
|
||||
&& *(unsigned long *)(pc - 6) == 0x83145fff
|
||||
&& *(unsigned long *)(pc - 1) == 0xc3c90cc4)
|
||||
|
||||
|| /* Solaris 11 since snv_125
|
||||
-------------------------
|
||||
<__sighndlr+0> push %ebp
|
||||
<__sighndlr+1> mov %esp,%ebp
|
||||
<__sighndlr+3> and $0xfffffff0,%esp
|
||||
<__sighndlr+6> sub $0x4,%esp
|
||||
<__sighndlr+9> pushl 0x10(%ebp)
|
||||
<__sighndlr+12> pushl 0xc(%ebp)
|
||||
<__sighndlr+15> pushl 0x8(%ebp)
|
||||
<__sighndlr+18> call *0x14(%ebp)
|
||||
<__sighndlr+21> leave <--- PC
|
||||
<__sighndlr+22> ret */
|
||||
(*(unsigned long *)(pc - 21) == 0x83ec8b55
|
||||
&& *(unsigned long *)(pc - 17) == 0xec83f0e4
|
||||
&& *(unsigned long *)(pc - 13) == 0x1075ff04
|
||||
&& *(unsigned long *)(pc - 9) == 0xff0c75ff
|
||||
&& *(unsigned long *)(pc - 5) == 0x55ff0875
|
||||
&& (*(unsigned long *)(pc - 1) & 0x00ffffff) == 0x00c3c914))
|
||||
{
|
||||
struct handler_args {
|
||||
int signo;
|
||||
siginfo_t *sip;
|
||||
ucontext_t *ucontext;
|
||||
} *handler_args = context->cfa;
|
||||
mctx = &handler_args->ucontext->uc_mcontext;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
new_cfa = mctx->gregs[UESP];
|
||||
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = 4;
|
||||
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
|
||||
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&mctx->gregs[EAX] - new_cfa;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&mctx->gregs[EBX] - new_cfa;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&mctx->gregs[ECX] - new_cfa;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&mctx->gregs[EDX] - new_cfa;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&mctx->gregs[ESI] - new_cfa;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&mctx->gregs[EDI] - new_cfa;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&mctx->gregs[EBP] - new_cfa;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa;
|
||||
fs->retaddr_column = 8;
|
||||
|
||||
/* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
|
||||
rather than before it, so don't set fs->signal_frame in that case.
|
||||
We test whether the ES field of the Status Register is zero. */
|
||||
if ((mctx->fpregs.fp_reg_set.fpchip_state.status & 0x80) == 0)
|
||||
fs->signal_frame = 1;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
LIB1ASMSRC = i386/cygwin.S
|
||||
LIB1ASMFUNCS = _chkstk _chkstk_ms
|
|
@ -0,0 +1 @@
|
|||
LIB2ADD += $(srcdir)/config/i386/cpuinfo.c
|
|
@ -0,0 +1,4 @@
|
|||
# If the compatibility cpuinfo symbols in shared libgcc_s are not needed
|
||||
# then they can be added to the static library only.
|
||||
|
||||
LIB2ADD_ST += $(srcdir)/config/i386/cpuinfo.c
|
|
@ -0,0 +1,8 @@
|
|||
crtprec32.o: $(srcdir)/config/i386/crtprec.c
|
||||
$(gcc_compile) -D__PREC=32 -c $<
|
||||
|
||||
crtprec64.o: $(srcdir)/config/i386/crtprec.c
|
||||
$(gcc_compile) -D__PREC=64 -c $<
|
||||
|
||||
crtprec80.o: $(srcdir)/config/i386/crtprec.c
|
||||
$(gcc_compile) -D__PREC=80 -c $<
|
|
@ -0,0 +1,7 @@
|
|||
# The pushl in CTOR initialization interferes with frame pointer elimination.
|
||||
# crtend*.o cannot be compiled without -fno-asynchronous-unwind-tables,
|
||||
# because then __FRAME_END__ might not be the last thing in .eh_frame
|
||||
# section. -fno-asynchronous-unwind-tables is off by default for i386
|
||||
# and is on by default for x86-64. We turn it off for both i386 and
|
||||
# x86-64.
|
||||
CRTSTUFF_T_CFLAGS += -fno-omit-frame-pointer -fno-asynchronous-unwind-tables
|
|
@ -0,0 +1,17 @@
|
|||
# If we are building next to winsup, this will let us find the real
|
||||
# limits.h when building libgcc2. Otherwise, winsup must be installed
|
||||
# first.
|
||||
LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/w32api/include
|
||||
|
||||
CUSTOM_CRTSTUFF = yes
|
||||
|
||||
crtbegin.o: $(srcdir)/config/i386/cygming-crtbegin.c
|
||||
$(crt_compile) -fno-omit-frame-pointer -c $<
|
||||
|
||||
crtbeginS.o: $(srcdir)/config/i386/cygming-crtbegin.c
|
||||
$(crt_compile) -fno-omit-frame-pointer -c $< -DCRTSTUFFS_O
|
||||
|
||||
# We intentionally use a implementation-reserved init priority of 0,
|
||||
# so allow the warning.
|
||||
crtend.o: $(srcdir)/config/i386/cygming-crtend.c
|
||||
$(crt_compile) -fno-omit-frame-pointer -Wno-error -c $<
|
|
@ -0,0 +1,19 @@
|
|||
# If we are building next to winsup, this will let us find the real
|
||||
# limits.h when building libgcc2. Otherwise, winsup must be installed
|
||||
# first.
|
||||
LIBGCC2_INCLUDES += -I$(srcdir)/../winsup/include \
|
||||
-I$(srcdir)/../winsup/cygwin/include
|
||||
|
||||
# Cygwin-specific parts of LIB_SPEC
|
||||
SHLIB_LC = -lcygwin -ladvapi32 -lshell32 -luser32 -lkernel32
|
||||
|
||||
# We have already included one of the t-{dw2,sjlj}-eh fragments for EH_MODEL
|
||||
SHLIB_EH_EXTENSION = $(subst -dw2,,-$(EH_MODEL))
|
||||
|
||||
# Cygwin uses different conventions than MinGW; override generic SHLIB_ def'ns here.
|
||||
SHLIB_IMPLIB = @shlib_base_name@$(SHLIB_EXT).a
|
||||
SHLIB_SONAME = cyggcc_s$(SHLIB_EH_EXTENSION)-$(SHLIB_SOVERSION)$(SHLIB_EXT)
|
||||
# This must match the definitions of SHLIB_SONAME/SHLIB_SOVERSION and LIBGCC_SONAME.
|
||||
# We'd like to use SHLIB_SONAME here too, and we can, since
|
||||
# we don't rely on shlib_base_name substitution for it.
|
||||
SHLIB_MKMAP_OPTS = -v pe_dll=$(SHLIB_SONAME)
|
|
@ -0,0 +1,3 @@
|
|||
LIB2_SIDITI_CONV_FUNCS = yes
|
||||
LIB2ADD = $(srcdir)/config/darwin-64.c
|
||||
LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf
|
|
@ -0,0 +1,2 @@
|
|||
# In a native build, target DLLs go in bindir, where they can be executed.
|
||||
SHLIB_DLLDIR = $(bindir)
|
|
@ -0,0 +1,3 @@
|
|||
# In a cross build, bindir contains host not target binaries, so target DLLs
|
||||
# instead go in toolexeclibdir, alongside other target binaries and static libs.
|
||||
SHLIB_DLLDIR = $(toolexeclibdir)
|
|
@ -0,0 +1,2 @@
|
|||
# Required for -fcilkplus support
|
||||
SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-bsd.ver
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
# We are using Dwarf-2 EH.
|
||||
EH_MODEL = dw2
|
|
@ -0,0 +1,2 @@
|
|||
# Add support for the introduction of 128-bit long double.
|
||||
SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-bsd.ver
|
|
@ -0,0 +1,2 @@
|
|||
# We hide calls to w32api needed for w32 thread support here:
|
||||
LIB2ADD = $(srcdir)/config/i386/gthr-win32.c
|
|
@ -0,0 +1,6 @@
|
|||
# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
|
||||
# Need to support TImode for x86. Override the settings from
|
||||
# t-slibgcc-elf-ver and t-linux
|
||||
SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-glibc.ver
|
||||
|
||||
HOST_LIBGCC2_CFLAGS += -mlong-double-80 -DUSE_ELF_SYMVER
|
|
@ -0,0 +1,2 @@
|
|||
SHLIB_PTHREAD_CFLAG = -pthread
|
||||
SHLIB_PTHREAD_LDFLAG = -Wl,-lpthread
|
|
@ -0,0 +1,2 @@
|
|||
# MinGW-specific parts of LIB_SPEC
|
||||
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32
|
|
@ -0,0 +1,3 @@
|
|||
HOST_LIBGCC2_CFLAGS += -fexceptions
|
||||
|
||||
CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer $(PICFLAG)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
# We are using SEH EH.
|
||||
EH_MODEL = seh
|
||||
|
||||
# Use SEH exception handling.
|
||||
LIB2ADDEH = $(srcdir)/unwind-seh.c $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
# We are using SjLj EH.
|
||||
EH_MODEL = sjlj
|
|
@ -0,0 +1,58 @@
|
|||
# Build a shared libgcc library for PECOFF with a DEF file
|
||||
# with the GNU linker.
|
||||
#
|
||||
# mkmap-flat.awk is used with the pe_dll option to produce a DEF instead
|
||||
# of an ELF map file.
|
||||
#
|
||||
# Warning: If SHLIB_SOVERSION or SHLIB_SONAME are updated, LIBGCC_SONAME
|
||||
# in mingw32.h and SHLIB_MKMAP_OPTS below must be updated also.
|
||||
|
||||
SHLIB_EXT = .dll
|
||||
SHLIB_IMPLIB = @shlib_base_name@.a
|
||||
SHLIB_SOVERSION = 1
|
||||
SHLIB_SONAME = @shlib_base_name@_$(EH_MODEL)-$(SHLIB_SOVERSION)$(SHLIB_EXT)
|
||||
SHLIB_MAP = @shlib_map_file@
|
||||
SHLIB_OBJS = @shlib_objs@
|
||||
SHLIB_DIR = @multilib_dir@/shlib
|
||||
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
|
||||
# SHLIB_DLLDIR is defined by including one of either t-dlldir or t-dlldir-x
|
||||
# (native/cross build respectively) in the tmake_file list in
|
||||
# libgcc/config.host.
|
||||
ifndef SHLIB_DLLDIR
|
||||
$(error SHLIB_DLLDIR must be defined)
|
||||
endif
|
||||
ifndef SHLIB_PTHREAD_CFLAG
|
||||
SHLIB_PTHREAD_CFLAG =
|
||||
endif
|
||||
ifndef SHLIB_PTHREAD_LDFLAG
|
||||
SHLIB_PTHREAD_LDFLAG =
|
||||
endif
|
||||
|
||||
SHLIB_LINK = $(LN_S) -f $(SHLIB_MAP) $(SHLIB_MAP).def && \
|
||||
if [ ! -d $(SHLIB_DIR) ]; then \
|
||||
mkdir $(SHLIB_DIR); \
|
||||
else true; fi && \
|
||||
$(CC) $(LIBGCC2_CFLAGS) $(SHLIB_PTHREAD_CFLAG) \
|
||||
-shared -nodefaultlibs \
|
||||
$(SHLIB_MAP).def \
|
||||
-Wl,--out-implib,$(SHLIB_DIR)/$(SHLIB_IMPLIB).tmp \
|
||||
-o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
|
||||
$(SHLIB_OBJS) ${SHLIB_PTHREAD_LDFLAG} $(SHLIB_LC) && \
|
||||
if [ -f $(SHLIB_DIR)/$(SHLIB_SONAME) ]; then \
|
||||
mv -f $(SHLIB_DIR)/$(SHLIB_SONAME) \
|
||||
$(SHLIB_DIR)/$(SHLIB_SONAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_DIR)/$(SHLIB_SONAME).tmp $(SHLIB_DIR)/$(SHLIB_SONAME) && \
|
||||
mv $(SHLIB_DIR)/$(SHLIB_IMPLIB).tmp $(SHLIB_DIR)/$(SHLIB_IMPLIB)
|
||||
SHLIB_INSTALL = \
|
||||
$(mkinstalldirs) $(DESTDIR)$(SHLIB_DLLDIR) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
|
||||
$(INSTALL) $(SHLIB_DIR)/$(SHLIB_SONAME) \
|
||||
$(DESTDIR)$(SHLIB_DLLDIR)/$(SHLIB_SONAME); \
|
||||
$(INSTALL_DATA) $(SHLIB_DIR)/$(SHLIB_IMPLIB) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_IMPLIB)
|
||||
SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
|
||||
# We'd like to use SHLIB_SONAME here too, but shlib_base_name
|
||||
# does not get substituted before mkmap-flat.awk is run.
|
||||
SHLIB_MKMAP_OPTS = -v pe_dll=libgcc_s_$(EH_MODEL)-$(SHLIB_SOVERSION)$(SHLIB_EXT)
|
||||
SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-cygming.ver
|
|
@ -0,0 +1 @@
|
|||
LIB2ADD += $(srcdir)/config/i386/sfp-exceptions.c
|
|
@ -0,0 +1,13 @@
|
|||
# We need to use -fPIC when we are using gcc to compile the routines in
|
||||
# crtstuff.c. This is only really needed when we are going to use gcc/g++
|
||||
# to produce a shared library, but since we don't know ahead of time when
|
||||
# we will be doing that, we just always use -fPIC when compiling the
|
||||
# routines in crtstuff.c.
|
||||
#
|
||||
# We must also enable optimization to avoid having any code appear after
|
||||
# the call & alignment statement, but before we switch back to the
|
||||
# .text section.
|
||||
CRTSTUFF_T_CFLAGS = $(PICFLAG) -O2
|
||||
|
||||
# Add support for the introduction of 128-bit long double.
|
||||
SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-sol2.ver
|
|
@ -0,0 +1,2 @@
|
|||
# Makefile fragment to support -fsplit-stack for x86.
|
||||
LIB2ADD_ST += $(srcdir)/config/i386/morestack.S
|
|
@ -0,0 +1,25 @@
|
|||
/* Store register values as _Unwind_Word type in DWARF2 EH unwind context.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define this macro if the target stores register values as _Unwind_Word
|
||||
type in unwind context. Only enable it for x32. */
|
||||
#if defined __x86_64 && !defined __LP64__
|
||||
# define REG_VALUE_IN_UNWIND_CONTEXT
|
||||
#endif
|
|
@ -0,0 +1,207 @@
|
|||
/* Definitions for Dwarf2 EH unwind support for Windows32 targets
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
Contributed by Pascal Obry <obry@adacore.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
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.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This file implements the md_fallback_frame_state_for routine for
|
||||
Windows, triggered when the GCC table based unwinding process hits a
|
||||
frame for which no unwind info has been registered. This typically
|
||||
occurs when raising an exception from a signal handler, because the
|
||||
handler is actually called from the OS kernel.
|
||||
|
||||
The basic idea is to detect that we are indeed trying to unwind past a
|
||||
signal handler and to fill out the GCC internal unwinding structures for
|
||||
the OS kernel frame as if it had been directly called from the
|
||||
interrupted context.
|
||||
|
||||
This is all assuming that the code to set the handler asked the kernel
|
||||
to pass a pointer to such context information.
|
||||
|
||||
There is three main parts.
|
||||
|
||||
1) The first thing to do is to check if we are in a signal context. If
|
||||
not we can just return as there is nothing to do. We are probably on
|
||||
some foreign code for which no unwind frame can be found. If this is
|
||||
a call from the Windows signal handler, then:
|
||||
|
||||
2) We must get the signal context information.
|
||||
|
||||
* With the standard exception filter:
|
||||
|
||||
This is on Windows pointed to by an EXCEPTION_POINTERS. We know that
|
||||
the signal handle will call an UnhandledExceptionFilter with this
|
||||
parameter. The spec for this routine is:
|
||||
|
||||
LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS*);
|
||||
|
||||
So the pointer to struct _EXCEPTION_POINTERS must be somewhere on the
|
||||
stack.
|
||||
|
||||
This was found experimentally to always be at offset 0 of the context
|
||||
frame in all cases handled by this implementation.
|
||||
|
||||
* With the SEH exception handler:
|
||||
|
||||
In this case the signal context is directly on the stack as the SEH
|
||||
exception handler has the following prototype:
|
||||
|
||||
DWORD
|
||||
SEH_error_handler (PEXCEPTION_RECORD ExceptionRecord,
|
||||
PVOID EstablisherFrame,
|
||||
PCONTEXT ContextRecord,
|
||||
PVOID DispatcherContext)
|
||||
|
||||
This was found experimentally to always be at offset 56 of the
|
||||
context frame in all cases handled by this implementation.
|
||||
|
||||
3) When we have the signal context we just have to save some registers
|
||||
and set the return address based on the program counter (Eip).
|
||||
|
||||
Note that this implementation follows closely the same principles as the
|
||||
GNU/Linux and OSF ones. */
|
||||
|
||||
#ifndef __MINGW64__
|
||||
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <windows.h>
|
||||
/* Patterns found experimentally to be on a Windows signal handler */
|
||||
|
||||
/* In a standard exception filter */
|
||||
|
||||
#define SIG_PAT1 \
|
||||
(pc_[-2] == 0xff && pc_[-1] == 0xd0 /* call %eax */ \
|
||||
&& pc_[0] == 0x83 && pc_[1] == 0xf8) /* cmp 0xdepl,%eax */
|
||||
|
||||
#define SIG_PAT2 \
|
||||
(pc_[-5] == 0xe8 && pc_[-4] == 0x68 /* call (depl16) */ \
|
||||
&& pc_[0] == 0xc3) /* ret */
|
||||
|
||||
/* In a Win32 SEH handler */
|
||||
|
||||
#define SIG_SEH1 \
|
||||
(pc_[-5] == 0xe8 /* call addr */ \
|
||||
&& pc_[0] == 0x83 && pc_[1] == 0xc4 /* add 0xval,%esp */ \
|
||||
&& pc_[3] == 0xb8) /* mov 0xval,%eax */
|
||||
|
||||
#define SIG_SEH2 \
|
||||
(pc_[-5] == 0x8b && pc_[-4] == 0x4d /* mov depl(%ebp),%ecx */ \
|
||||
&& pc_[0] == 0x64 && pc_[1] == 0x8b) /* mov %fs:(0),<reg> */ \
|
||||
|
||||
/* In the GCC alloca (stack probing) */
|
||||
|
||||
#define SIG_ALLOCA \
|
||||
(pc_[-1] == 0x83 /* orl $0x0,(%ecx) */ \
|
||||
&& pc_[0] == 0x9 && pc_[1] == 0 \
|
||||
&& pc_[2] == 0x2d && pc_[3] == 0 /* subl $0x1000,%eax */ \
|
||||
&& pc_[4] == 0x10 && pc_[5] == 0)
|
||||
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR i386_w32_fallback_frame_state
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
i386_w32_fallback_frame_state (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
|
||||
{
|
||||
void * ctx_ra_ = (void *)(context->ra); /* return address */
|
||||
void * ctx_cfa_ = (void *)(context->cfa); /* context frame address */
|
||||
unsigned char * pc_ = (unsigned char *) ctx_ra_;
|
||||
|
||||
/* In the test below we look for two specific patterns found
|
||||
experimentally to be in the Windows signal handler. */
|
||||
if (SIG_PAT1 || SIG_PAT2 || SIG_SEH1 || SIG_SEH2)
|
||||
{
|
||||
PEXCEPTION_POINTERS weinfo_;
|
||||
PCONTEXT proc_ctx_;
|
||||
long new_cfa_;
|
||||
|
||||
if (SIG_SEH1)
|
||||
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 56));
|
||||
else if (SIG_SEH2)
|
||||
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 8));
|
||||
else
|
||||
{
|
||||
weinfo_ = (PEXCEPTION_POINTERS) (*(int*)ctx_cfa_);
|
||||
proc_ctx_ = weinfo_->ContextRecord;
|
||||
}
|
||||
|
||||
/* The new context frame address is the stack pointer. */
|
||||
new_cfa_ = proc_ctx_->Esp;
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||
|
||||
/* Restore registers. */
|
||||
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[0].loc.offset = (long)&proc_ctx_->Eax - new_cfa_;
|
||||
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[3].loc.offset = (long)&proc_ctx_->Ebx - new_cfa_;
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = (long)&proc_ctx_->Ecx - new_cfa_;
|
||||
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[2].loc.offset = (long)&proc_ctx_->Edx - new_cfa_;
|
||||
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[6].loc.offset = (long)&proc_ctx_->Esi - new_cfa_;
|
||||
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[7].loc.offset = (long)&proc_ctx_->Edi - new_cfa_;
|
||||
fs->regs.reg[5].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[5].loc.offset = (long)&proc_ctx_->Ebp - new_cfa_;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&proc_ctx_->Eip - new_cfa_;
|
||||
fs->retaddr_column = 8;
|
||||
fs->signal_frame = 1;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
/* Unwinding through _alloca, propagating from a trap triggered by
|
||||
one of it's probes prior to the real SP adjustment. The only
|
||||
operations of interest performed is "pushl %ecx", followed by
|
||||
ecx clobbering. */
|
||||
else if (SIG_ALLOCA)
|
||||
{
|
||||
/* Only one push between entry in _alloca and the probe trap. */
|
||||
long new_cfa_ = (long) ctx_cfa_ + 4;
|
||||
|
||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||
|
||||
/* The saved value of %ecx is at CFA - 4 */
|
||||
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[1].loc.offset = -4;
|
||||
|
||||
/* and what is stored at the CFA is the return address. */
|
||||
fs->retaddr_column = 8;
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = 0;
|
||||
fs->signal_frame = 1;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
else
|
||||
return _URC_END_OF_STACK;
|
||||
}
|
||||
|
||||
#endif /* !__MINGW64__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
|||
# aclocal && autoconf && autoheader && automake
|
||||
|
||||
AC_PREREQ(2.64)
|
||||
AC_INIT([GNU Fortran Runtime Library], 0.3,,[libgfortran])
|
||||
AC_INIT([GNU Fortran Runtime Library], 0.3,,[liblfortran])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
GCC_TOPLEV_SUBDIRS
|
||||
|
||||
|
@ -70,55 +70,15 @@ AC_SUBST(target_alias)
|
|||
AM_INIT_AUTOMAKE([1.9.6 no-define foreign no-dist -Wall -Wno-portability])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
AM_ENABLE_MULTILIB(, ..)
|
||||
|
||||
# Handy for debugging:
|
||||
#AC_MSG_NOTICE($build / $host / $target / $host_alias / $target_alias); sleep 5
|
||||
toolexecdir='$(libdir)'
|
||||
toolexeclibdir='$(toolexecdir)'
|
||||
|
||||
# Are we being configured with some form of cross compiler?
|
||||
# NB: We don't actually need to know this just now, but when, say, a test
|
||||
# suite is included, we'll have to know.
|
||||
if test "$build" != "$host"; then
|
||||
LIBGFOR_IS_NATIVE=false
|
||||
GCC_NO_EXECUTABLES
|
||||
else
|
||||
LIBGFOR_IS_NATIVE=true
|
||||
fi
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
# Calculate toolexeclibdir
|
||||
# Also toolexecdir, though it's only used in toolexeclibdir
|
||||
case ${version_specific_libs} in
|
||||
yes)
|
||||
# Need the gcc compiler version to know where to install libraries
|
||||
# and header files if --enable-version-specific-runtime-libs option
|
||||
# is selected.
|
||||
toolexecdir='$(libdir)/gcc/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
|
||||
;;
|
||||
no)
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
# Install a library built with a cross compiler in tooldir, not libdir.
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
|
||||
# Create a spec file, so that compile/link tests don't fail
|
||||
test -f libgfortran.spec || touch libgfortran.spec
|
||||
test -f liblfortran.spec || touch liblfortran.spec
|
||||
|
||||
AC_LANG_C
|
||||
# Check the compiler.
|
||||
|
@ -138,14 +98,26 @@ AM_PROG_CC_C_O
|
|||
|
||||
# Add -Wall -fno-repack-arrays -fno-underscoring if we are using GCC.
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AM_FCFLAGS="-I . -Wall -Werror -fimplicit-none -fno-repack-arrays -fno-underscoring"
|
||||
AM_FCFLAGS="-I. -I${srcdir} -Wall -Werror -fimplicit-none"
|
||||
stdf=
|
||||
case "${FORTRAN}" in
|
||||
*gfortran*)
|
||||
AM_FCFLAGS="$AM_FCFLAGS -fno-underscoring -Wno-unused-dummy-argument -Wno-c-binding-type -fallow-leading-underscore"
|
||||
stdf="-std=gnu99"
|
||||
## stdf="-std=gnu11"
|
||||
;;
|
||||
*)
|
||||
AM_FCFLAGS="$AM_FCFLAGS -Wf,-fno-underscoring -Wf,-fallow-leading-underscore -Wf,-Wno-unused-dummy-argument -Wf,-Wno-c-binding-type"
|
||||
stdf="-std=gnu99"
|
||||
;;
|
||||
esac
|
||||
## We like to use C11 and C99 routines when available. This makes
|
||||
## sure that
|
||||
## __STDC_VERSION__ is set such that libc includes make them available.
|
||||
AM_CFLAGS="-std=gnu11 -Wall -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wextra -Wwrite-strings -Werror=implicit-function-declaration -Werror=vla"
|
||||
AM_CFLAGS="$stdf -Wall -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wextra -Wwrite-strings -Werror=implicit-function-declaration -Wno-unknown-pragmas"
|
||||
## Compile the following tests with the same system header contents
|
||||
## that we'll encounter when compiling our own source files.
|
||||
CFLAGS="-std=gnu11 $CFLAGS"
|
||||
CFLAGS="$stdf $CFLAGS"
|
||||
fi
|
||||
AC_SUBST(AM_FCFLAGS)
|
||||
AC_SUBST(AM_CFLAGS)
|
||||
|
@ -155,7 +127,7 @@ AC_SUBST(CFLAGS)
|
|||
AC_MSG_CHECKING([whether symbol versioning is supported])
|
||||
AC_ARG_ENABLE(symvers,
|
||||
AS_HELP_STRING([--disable-symvers],
|
||||
[disable symbol versioning for libgfortran]),
|
||||
[disable symbol versioning for liblfortran]),
|
||||
gfortran_use_symver=$enableval,
|
||||
gfortran_use_symver=yes)
|
||||
if test "x$gfortran_use_symver" != xno; then
|
||||
|
@ -184,11 +156,6 @@ EOF
|
|||
fi
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
fi
|
||||
AC_MSG_RESULT($gfortran_use_symver)
|
||||
AM_CONDITIONAL(LIBGFOR_USE_SYMVER, [test "x$gfortran_use_symver" != xno])
|
||||
AM_CONDITIONAL(LIBGFOR_USE_SYMVER_GNU, [test "x$gfortran_use_symver" = xgnu])
|
||||
AM_CONDITIONAL(LIBGFOR_USE_SYMVER_SUN, [test "x$gfortran_use_symver" = xsun])
|
||||
|
||||
# For GPU offloading, not everything in libfortran can be supported.
|
||||
# Currently, the only target that has this problem is nvptx. The
|
||||
# following is a (partial) list of features that are unsupportable on
|
||||
|
@ -222,9 +189,6 @@ fi
|
|||
AC_MSG_RESULT($ac_fdsections)
|
||||
AC_SUBST(SECTION_FLAGS)
|
||||
|
||||
# Check linker hardware capability support.
|
||||
GCC_CHECK_LINKER_HWCAP
|
||||
|
||||
# Find other programs we need.
|
||||
AC_CHECK_TOOL(AS, as)
|
||||
AC_CHECK_TOOL(AR, ar)
|
||||
|
@ -236,25 +200,14 @@ AC_PROG_INSTALL
|
|||
#AC_MSG_NOTICE([====== Starting libtool configuration])
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AM_PROG_LIBTOOL
|
||||
ACX_LT_HOST_FLAGS
|
||||
AC_SUBST(enable_shared)
|
||||
AC_SUBST(enable_static)
|
||||
#AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10
|
||||
|
||||
# We need gfortran to compile parts of the library
|
||||
#AC_PROG_FC(gfortran)
|
||||
FC="$GFORTRAN"
|
||||
# We need fortran to compile parts of the library
|
||||
FC="$FORTRAN"
|
||||
AC_PROG_FC(gfortran)
|
||||
|
||||
# extra LD Flags which are required for targets
|
||||
case "${host}" in
|
||||
*-darwin*)
|
||||
# Darwin needs -single_module when linking libgfortran
|
||||
extra_ldflags_libgfortran=-Wl,-single_module
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(extra_ldflags_libgfortran)
|
||||
|
||||
# We need a working compiler at that point, otherwise give a clear
|
||||
# error message and bail out.
|
||||
LIBGFOR_WORKING_GFORTRAN
|
||||
|
@ -525,7 +478,7 @@ AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENA
|
|||
# At least for glibc, clock_gettime is in librt. But don't
|
||||
# pull that in if it still doesn't give us the function we want. This
|
||||
# test is copied from libgomp, and modified to not link in -lrt as
|
||||
# libgfortran calls clock_gettime via a weak reference if it's found
|
||||
# liblfortran calls clock_gettime via a weak reference if it's found
|
||||
# in librt.
|
||||
if test "$ac_cv_func_clock_gettime" = no; then
|
||||
AC_CHECK_LIB(rt, clock_gettime,
|
||||
|
@ -616,7 +569,7 @@ LIBGFOR_CHECK_UNLINK_OPEN_FILE
|
|||
LIBGFOR_CHECK_CRLF
|
||||
|
||||
# Check whether we support AVX extensions
|
||||
LIBGFOR_CHECK_AVX
|
||||
## LIBGFOR_CHECK_AVX
|
||||
|
||||
# Check wether we support AVX2 extensions
|
||||
LIBGFOR_CHECK_AVX2
|
||||
|
@ -638,6 +591,6 @@ fi
|
|||
# Write our Makefile and spec file.
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
libgfortran.spec
|
||||
liblfortran.spec
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
/* this file must be the same as in liblfortran/liblfortran (for fixing Bug 654) */
|
||||
|
||||
/* Flags to specify which standard/extension contains a feature.
|
||||
Note that no features were obsoleted nor deleted in F2003.
|
||||
Please remember to keep those definitions in sync with
|
||||
gfortran.texi. */
|
||||
/* For now, use F2015 = FTN_STD_GNU. */
|
||||
#define FTN_STD_F2015 (1<<5) /* PLACEHOLDER for Fortran 2015. */
|
||||
#define FTN_STD_F2008_TS (1<<9) /* POST-F2008 technical reports. */
|
||||
#define FTN_STD_F2008_OBS (1<<8) /* Obsolescent in F2008. */
|
||||
#define FTN_STD_F2008 (1<<7) /* New in F2008. */
|
||||
#define FTN_STD_LEGACY (1<<6) /* Backward compatibility. */
|
||||
#define FTN_STD_GNU (1<<5) /* GNU Fortran extension. */
|
||||
#define FTN_STD_F2003 (1<<4) /* New in F2003. */
|
||||
#define FTN_STD_F95 (1<<3) /* New in F95. */
|
||||
#define FTN_STD_F95_DEL (1<<2) /* Deleted in F95. */
|
||||
#define FTN_STD_F95_OBS (1<<1) /* Obsolescent in F95. */
|
||||
#define FTN_STD_F77 (1<<0) /* Included in F77, but not deleted or obsolescent in later standards. */
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_COMPLEX_10)
|
||||
#ifdef HAVE_CABSL
|
||||
|
||||
elemental function _gfortran_specific__abs_c10 (parm)
|
||||
elemental function _lfortran_specific__abs_c10 (parm)
|
||||
complex (kind=10), intent (in) :: parm
|
||||
real (kind=10) :: _gfortran_specific__abs_c10
|
||||
real (kind=10) :: _lfortran_specific__abs_c10
|
||||
|
||||
_gfortran_specific__abs_c10 = abs (parm)
|
||||
_lfortran_specific__abs_c10 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_COMPLEX_16)
|
||||
#ifdef HAVE_CABSL
|
||||
|
||||
elemental function _gfortran_specific__abs_c16 (parm)
|
||||
elemental function _lfortran_specific__abs_c16 (parm)
|
||||
complex (kind=16), intent (in) :: parm
|
||||
real (kind=16) :: _gfortran_specific__abs_c16
|
||||
real (kind=16) :: _lfortran_specific__abs_c16
|
||||
|
||||
_gfortran_specific__abs_c16 = abs (parm)
|
||||
_lfortran_specific__abs_c16 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_COMPLEX_4)
|
||||
#ifdef HAVE_CABSF
|
||||
|
||||
elemental function _gfortran_specific__abs_c4 (parm)
|
||||
elemental function _lfortran_specific__abs_c4 (parm)
|
||||
complex (kind=4), intent (in) :: parm
|
||||
real (kind=4) :: _gfortran_specific__abs_c4
|
||||
real (kind=4) :: _lfortran_specific__abs_c4
|
||||
|
||||
_gfortran_specific__abs_c4 = abs (parm)
|
||||
_lfortran_specific__abs_c4 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_COMPLEX_8)
|
||||
#ifdef HAVE_CABS
|
||||
|
||||
elemental function _gfortran_specific__abs_c8 (parm)
|
||||
elemental function _lfortran_specific__abs_c8 (parm)
|
||||
complex (kind=8), intent (in) :: parm
|
||||
real (kind=8) :: _gfortran_specific__abs_c8
|
||||
real (kind=8) :: _lfortran_specific__abs_c8
|
||||
|
||||
_gfortran_specific__abs_c8 = abs (parm)
|
||||
_lfortran_specific__abs_c8 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_INTEGER_16)
|
||||
|
||||
|
||||
elemental function _gfortran_specific__abs_i16 (parm)
|
||||
elemental function _lfortran_specific__abs_i16 (parm)
|
||||
integer (kind=16), intent (in) :: parm
|
||||
integer (kind=16) :: _gfortran_specific__abs_i16
|
||||
integer (kind=16) :: _lfortran_specific__abs_i16
|
||||
|
||||
_gfortran_specific__abs_i16 = abs (parm)
|
||||
_lfortran_specific__abs_i16 = abs (parm)
|
||||
end function
|
||||
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_INTEGER_4)
|
||||
|
||||
|
||||
elemental function _gfortran_specific__abs_i4 (parm)
|
||||
elemental function _lfortran_specific__abs_i4 (parm)
|
||||
integer (kind=4), intent (in) :: parm
|
||||
integer (kind=4) :: _gfortran_specific__abs_i4
|
||||
integer (kind=4) :: _lfortran_specific__abs_i4
|
||||
|
||||
_gfortran_specific__abs_i4 = abs (parm)
|
||||
_lfortran_specific__abs_i4 = abs (parm)
|
||||
end function
|
||||
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_INTEGER_8)
|
||||
|
||||
|
||||
elemental function _gfortran_specific__abs_i8 (parm)
|
||||
elemental function _lfortran_specific__abs_i8 (parm)
|
||||
integer (kind=8), intent (in) :: parm
|
||||
integer (kind=8) :: _gfortran_specific__abs_i8
|
||||
integer (kind=8) :: _lfortran_specific__abs_i8
|
||||
|
||||
_gfortran_specific__abs_i8 = abs (parm)
|
||||
_lfortran_specific__abs_i8 = abs (parm)
|
||||
end function
|
||||
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_10)
|
||||
#ifdef HAVE_FABSL
|
||||
|
||||
elemental function _gfortran_specific__abs_r10 (parm)
|
||||
elemental function _lfortran_specific__abs_r10 (parm)
|
||||
real (kind=10), intent (in) :: parm
|
||||
real (kind=10) :: _gfortran_specific__abs_r10
|
||||
real (kind=10) :: _lfortran_specific__abs_r10
|
||||
|
||||
_gfortran_specific__abs_r10 = abs (parm)
|
||||
_lfortran_specific__abs_r10 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_16)
|
||||
#ifdef HAVE_FABSL
|
||||
|
||||
elemental function _gfortran_specific__abs_r16 (parm)
|
||||
elemental function _lfortran_specific__abs_r16 (parm)
|
||||
real (kind=16), intent (in) :: parm
|
||||
real (kind=16) :: _gfortran_specific__abs_r16
|
||||
real (kind=16) :: _lfortran_specific__abs_r16
|
||||
|
||||
_gfortran_specific__abs_r16 = abs (parm)
|
||||
_lfortran_specific__abs_r16 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_4)
|
||||
#ifdef HAVE_FABSF
|
||||
|
||||
elemental function _gfortran_specific__abs_r4 (parm)
|
||||
elemental function _lfortran_specific__abs_r4 (parm)
|
||||
real (kind=4), intent (in) :: parm
|
||||
real (kind=4) :: _gfortran_specific__abs_r4
|
||||
real (kind=4) :: _lfortran_specific__abs_r4
|
||||
|
||||
_gfortran_specific__abs_r4 = abs (parm)
|
||||
_lfortran_specific__abs_r4 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_8)
|
||||
#ifdef HAVE_FABS
|
||||
|
||||
elemental function _gfortran_specific__abs_r8 (parm)
|
||||
elemental function _lfortran_specific__abs_r8 (parm)
|
||||
real (kind=8), intent (in) :: parm
|
||||
real (kind=8) :: _gfortran_specific__abs_r8
|
||||
real (kind=8) :: _lfortran_specific__abs_r8
|
||||
|
||||
_gfortran_specific__abs_r8 = abs (parm)
|
||||
_lfortran_specific__abs_r8 = abs (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_10)
|
||||
#ifdef HAVE_ACOSL
|
||||
|
||||
elemental function _gfortran_specific__acos_r10 (parm)
|
||||
elemental function _lfortran_specific__acos_r10 (parm)
|
||||
real (kind=10), intent (in) :: parm
|
||||
real (kind=10) :: _gfortran_specific__acos_r10
|
||||
real (kind=10) :: _lfortran_specific__acos_r10
|
||||
|
||||
_gfortran_specific__acos_r10 = acos (parm)
|
||||
_lfortran_specific__acos_r10 = acos (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_16)
|
||||
#ifdef HAVE_ACOSL
|
||||
|
||||
elemental function _gfortran_specific__acos_r16 (parm)
|
||||
elemental function _lfortran_specific__acos_r16 (parm)
|
||||
real (kind=16), intent (in) :: parm
|
||||
real (kind=16) :: _gfortran_specific__acos_r16
|
||||
real (kind=16) :: _lfortran_specific__acos_r16
|
||||
|
||||
_gfortran_specific__acos_r16 = acos (parm)
|
||||
_lfortran_specific__acos_r16 = acos (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_4)
|
||||
#ifdef HAVE_ACOSF
|
||||
|
||||
elemental function _gfortran_specific__acos_r4 (parm)
|
||||
elemental function _lfortran_specific__acos_r4 (parm)
|
||||
real (kind=4), intent (in) :: parm
|
||||
real (kind=4) :: _gfortran_specific__acos_r4
|
||||
real (kind=4) :: _lfortran_specific__acos_r4
|
||||
|
||||
_gfortran_specific__acos_r4 = acos (parm)
|
||||
_lfortran_specific__acos_r4 = acos (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_8)
|
||||
#ifdef HAVE_ACOS
|
||||
|
||||
elemental function _gfortran_specific__acos_r8 (parm)
|
||||
elemental function _lfortran_specific__acos_r8 (parm)
|
||||
real (kind=8), intent (in) :: parm
|
||||
real (kind=8) :: _gfortran_specific__acos_r8
|
||||
real (kind=8) :: _lfortran_specific__acos_r8
|
||||
|
||||
_gfortran_specific__acos_r8 = acos (parm)
|
||||
_lfortran_specific__acos_r8 = acos (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_10)
|
||||
#ifdef HAVE_ACOSHL
|
||||
|
||||
elemental function _gfortran_specific__acosh_r10 (parm)
|
||||
elemental function _lfortran_specific__acosh_r10 (parm)
|
||||
real (kind=10), intent (in) :: parm
|
||||
real (kind=10) :: _gfortran_specific__acosh_r10
|
||||
real (kind=10) :: _lfortran_specific__acosh_r10
|
||||
|
||||
_gfortran_specific__acosh_r10 = acosh (parm)
|
||||
_lfortran_specific__acosh_r10 = acosh (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
#if defined (HAVE_GFC_REAL_16)
|
||||
#ifdef HAVE_ACOSHL
|
||||
|
||||
elemental function _gfortran_specific__acosh_r16 (parm)
|
||||
elemental function _lfortran_specific__acosh_r16 (parm)
|
||||
real (kind=16), intent (in) :: parm
|
||||
real (kind=16) :: _gfortran_specific__acosh_r16
|
||||
real (kind=16) :: _lfortran_specific__acosh_r16
|
||||
|
||||
_gfortran_specific__acosh_r16 = acosh (parm)
|
||||
_lfortran_specific__acosh_r16 = acosh (parm)
|
||||
end function
|
||||
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue