Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.

This commit is contained in:
David E. O'Brien 2002-05-09 20:02:13 +00:00
parent 1952e2e1c1
commit 909b401074
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=96263
373 changed files with 77192 additions and 11531 deletions

File diff suppressed because it is too large Load Diff

3781
contrib/gcc/ChangeLog.lib Normal file

File diff suppressed because it is too large Load Diff

10110
contrib/gcc/FSFChangeLog.10 Normal file

File diff suppressed because it is too large Load Diff

14493
contrib/gcc/FSFChangeLog.11 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -356,11 +356,8 @@ LIBGCC = libgcc.a
INSTALL_LIBGCC = install-libgcc
# Options to use when compiling libgcc2.a.
# -g1 causes output of debug info only for file-scope entities.
# we use this here because that should be enough, and also
# so that -g1 will be tested.
#
LIBGCC2_DEBUG_CFLAGS = -g1
LIBGCC2_DEBUG_CFLAGS = -g
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED @inhibit_libc@
# Additional options to use when compiling libgcc2.a.
@ -543,7 +540,8 @@ HCONFIG_H = hconfig.h $(build_xm_file_list)
CONFIG_H = $(GCONFIG_H) insn-constants.h insn-flags.h
TCONFIG_H = tconfig.h $(xm_file_list)
TARGET_H = target.h
TARGET_DEF_H = target-def.h
HOOKS_H = hooks.h
TARGET_DEF_H = target-def.h $(HOOKS_H)
TM_P_H = tm_p.h $(tm_p_file_list) tm-preds.h
MACHMODE_H = machmode.h machmode.def
@ -718,7 +716,7 @@ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
df.o diagnostic.o doloop.o dominance.o dwarf2asm.o dwarf2out.o dwarfout.o \
emit-rtl.o except.o explow.o expmed.o expr.o final.o flow.o \
fold-const.o function.o gcse.o genrtl.o ggc-common.o global.o graph.o \
haifa-sched.o hash.o hashtable.o ifcvt.o insn-attrtab.o insn-emit.o \
haifa-sched.o hash.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o \
@ -1001,8 +999,10 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext
SHLIB_EXT='$(SHLIB_EXT)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)' \
SHLIB_MKMAP='$(SHLIB_MKMAP)' \
SHLIB_MKMAP_OPTS='$(SHLIB_MKMAP_OPTS)' \
SHLIB_MAPFILES='$(SHLIB_MAPFILES)' \
SHLIB_NM_FLAGS='$(SHLIB_NM_FLAGS)' \
SHLIB_SLIBDIR_SUFFIXES='$(SHLIB_SLIBDIR_SUFFIXES)' \
mkinstalldirs='$(SHELL) $(srcdir)/mkinstalldirs' \
$(SHELL) mklibgcc > tmp-libgcc.mk
mv tmp-libgcc.mk libgcc.mk
@ -1036,14 +1036,18 @@ libgcc.a: $(LIBGCC_DEPS)
# switches.
multilib.h: s-mlib; @true
s-mlib: $(srcdir)/genmultilib Makefile
$(SHELL) $(srcdir)/genmultilib \
"`test @enable_multilib@ != yes || echo $(MULTILIB_OPTIONS)`" \
"`test @enable_multilib@ != yes || echo $(MULTILIB_DIRNAMES)`" \
"`test @enable_multilib@ != yes || echo $(MULTILIB_MATCHES)`" \
"`test @enable_multilib@ != yes || echo $(MULTILIB_EXCEPTIONS)`" \
"`test @enable_multilib@ != yes || echo $(MULTILIB_EXTRA_OPTS)`" \
"`test @enable_multilib@ != yes || echo $(MULTILIB_EXCLUSIONS)`" \
> tmp-mlib.h
if test @enable_multilib@ = yes; then \
$(SHELL) $(srcdir)/genmultilib \
"$(MULTILIB_OPTIONS)" \
"$(MULTILIB_DIRNAMES)" \
"$(MULTILIB_MATCHES)" \
"$(MULTILIB_EXCEPTIONS)" \
"$(MULTILIB_EXTRA_OPTS)" \
"$(MULTILIB_EXCLUSIONS)" \
> tmp-mlib.h; \
else \
$(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' > tmp-mlib.h; \
fi
$(SHELL) $(srcdir)/move-if-change tmp-mlib.h multilib.h
$(STAMP) s-mlib
@ -1146,7 +1150,7 @@ $(srcdir)/c-parse.y: c-parse.in
c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
$(GGC_H) $(TARGET_H) c-lex.h flags.h function.h output.h $(EXPR_H) \
debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H)
debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
@ -1163,7 +1167,7 @@ c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h
c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H)
c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H)
mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
@ -1322,7 +1326,8 @@ prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h
convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h convert.h toplev.h
langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h langhooks-def.h
tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h \
langhooks-def.h flags.h
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
$(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
@ -1335,7 +1340,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H) \
langhooks.h
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H)
function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H)
fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H)
diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \
@ -1445,7 +1450,7 @@ cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h
$(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H)
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h \
flags.h real.h insn-config.h ggc.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
function.h output.h toplev.h $(TM_P_H) $(PARAMS_H)
function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) except.h
sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) function.h \
hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
@ -1488,14 +1493,14 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H) $(TM_P_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(GGC_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h insn-config.h $(RECOG_H) $(GGC_H) $(TM_P_H)
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H)
cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TIMEVAR_H)\
$(BASIC_BLOCK_H) hard-reg-set.h output.h flags.h $(RECOG_H) toplev.h \
$(GGC_H) insn-config.h cselib.h $(TM_P_H)
$(GGC_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H)
cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
@ -1523,7 +1528,7 @@ reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h output.h \
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) real.h flags.h \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
$(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h cselib.h $(TM_P_H) \
except.h
except.h $(TREE_H)
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
$(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
$(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
@ -1564,8 +1569,8 @@ predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H)
lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) $(GGC_H)
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
$(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
flags.h $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h $(TARGET_H)
cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h function.h \
cfglayout.h
@ -1575,10 +1580,11 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
resource.h $(OBSTACK_H) flags.h $(TM_P_H)
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
output.h $(TM_P_H)
output.h except.h $(TM_P_H)
dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
$(C_COMMON_H) flags.h varray.h $(EXPR_H)
params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) $(HOOKS_H)
$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) $(GGC_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
@ -2010,7 +2016,7 @@ $(srcdir)/tradcif.c: $(srcdir)/tradcif.y
proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X
PROTO_OBJS = intl.o version.o
PROTO_OBJS = intl.o version.o cppdefault.o
protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS)
@ -2023,16 +2029,16 @@ protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) $(SYSTEM_H) \
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(DRIVER_DEFINES) $(PREPROCESSOR_DEFINES) \
$(DRIVER_DEFINES) \
$(srcdir)/protoize.c $(OUTPUT_OPTION))
unprotoize.o: unprotoize.c protoize.c $(srcdir)/../include/getopt.h \
unprotoize.o: protoize.c $(srcdir)/../include/getopt.h \
$(CONFIG_H) $(SYSTEM_H) Makefile version.h
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(DRIVER_DEFINES) $(PREPROCESSOR_DEFINES) \
$(srcdir)/unprotoize.c $(OUTPUT_OPTION))
$(CC) -c -DUNPROTOIZE $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(DRIVER_DEFINES) \
$(srcdir)/protoize.c $(OUTPUT_OPTION))
# This info describes the target machine, so compile with GCC just built.
SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \
@ -2257,7 +2263,8 @@ docdir = $(srcdir)/doc
doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug
info: $(docdir)/cpp.info $(docdir)/gcc.info $(docdir)/gccint.info lang.info $(docdir)/cppinternals.info
$(docdir)/cpp.info: $(docdir)/cpp.texi $(docdir)/include/fdl.texi
$(docdir)/cpp.info: $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
$(docdir)/cppenv.texi $(docdir)/cppopts.texi
cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cpp.info doc/cpp.texi
$(docdir)/gcc.info: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
@ -2268,7 +2275,7 @@ $(docdir)/gcc.info: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
$(docdir)/contribute.texi $(docdir)/vms.texi \
$(docdir)/include/funding.texi $(docdir)/gnu.texi \
$(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
$(docdir)/contrib.texi
$(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gcc.info doc/gcc.texi
$(docdir)/gccint.info: $(docdir)/gccint.texi \
@ -2292,7 +2299,8 @@ $(docdir)/cppinternals.info: $(docdir)/cppinternals.texi
dvi: gcc.dvi gccint.dvi cpp.dvi lang.dvi cppinternals.dvi
# This works with GNU Make's default rule.
cpp.dvi: $(docdir)/cpp.texi $(docdir)/include/fdl.texi
cpp.dvi: $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
$(docdir)/cppenv.texi $(docdir)/cppopts.texi
$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cpp.texi
gcc.dvi: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
@ -2303,7 +2311,7 @@ gcc.dvi: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
$(docdir)/contribute.texi $(docdir)/vms.texi \
$(docdir)/include/funding.texi $(docdir)/gnu.texi \
$(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
$(docdir)/contrib.texi
$(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
$(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gcc.texi
gccint.dvi: $(docdir)/gccint.texi \
@ -2329,23 +2337,25 @@ generated-manpages: $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1 \
$(docdir)/gcov.1: $(docdir)/gcov.texi
$(STAMP) $(docdir)/gcov.1
-$(TEXI2POD) < $(docdir)/gcov.texi > gcov.pod
-$(TEXI2POD) $(docdir)/gcov.texi > gcov.pod
-($(POD2MAN) --section=1 gcov.pod > $(docdir)/gcov.1.T$$$$ && \
mv -f $(docdir)/gcov.1.T$$$$ $(docdir)/gcov.1) || \
(rm -f $(docdir)/gcov.1.T$$$$ && exit 1)
-rm -f gcov.pod
$(docdir)/cpp.1: $(docdir)/cpp.texi
$(docdir)/cpp.1: $(docdir)/cpp.texi $(docdir)/cppenv.texi \
$(docdir)/cppopts.texi
$(STAMP) $(docdir)/cpp.1
-$(TEXI2POD) < $(docdir)/cpp.texi > cpp.pod
-$(TEXI2POD) $(docdir)/cpp.texi > cpp.pod
-($(POD2MAN) --section=1 cpp.pod > $(docdir)/cpp.1.T$$$$ && \
mv -f $(docdir)/cpp.1.T$$$$ $(docdir)/cpp.1) || \
(rm -f $(docdir)/cpp.1.T$$$$ && exit 1)
-rm -f cpp.pod
$(docdir)/gcc.1: $(docdir)/invoke.texi
$(docdir)/gcc.1: $(docdir)/invoke.texi $(docdir)/cppenv.texi \
$(docdir)/cppopts.texi
$(STAMP) $(docdir)/gcc.1
-$(TEXI2POD) < $(docdir)/invoke.texi > gcc.pod
-$(TEXI2POD) $(docdir)/invoke.texi > gcc.pod
-($(POD2MAN) --section=1 gcc.pod > $(docdir)/gcc.1.T$$$$ && \
mv -f $(docdir)/gcc.1.T$$$$ $(docdir)/gcc.1) || \
(rm -f $(docdir)/gcc.1.T$$$$ && exit 1)
@ -2353,7 +2363,7 @@ $(docdir)/gcc.1: $(docdir)/invoke.texi
$(docdir)/gfdl.7: $(docdir)/include/fdl.texi
$(STAMP) $(docdir)/gfdl.7
-$(TEXI2POD) < $(docdir)/include/fdl.texi > gfdl.pod
-$(TEXI2POD) $(docdir)/include/fdl.texi > gfdl.pod
-($(POD2MAN) --section=7 gfdl.pod > $(docdir)/gfdl.7.T$$$$ && \
mv -f $(docdir)/gfdl.7.T$$$$ $(docdir)/gfdl.7) || \
(rm -f $(docdir)/gfdl.7.T$$$$ && exit 1)
@ -2361,7 +2371,7 @@ $(docdir)/gfdl.7: $(docdir)/include/fdl.texi
$(docdir)/gpl.7: $(docdir)/include/gpl.texi
$(STAMP) $(docdir)/gpl.7
-$(TEXI2POD) < $(docdir)/include/gpl.texi > gpl.pod
-$(TEXI2POD) $(docdir)/include/gpl.texi > gpl.pod
-($(POD2MAN) --section=7 gpl.pod > $(docdir)/gpl.7.T$$$$ && \
mv -f $(docdir)/gpl.7.T$$$$ $(docdir)/gpl.7) || \
(rm -f $(docdir)/gpl.7.T$$$$ && exit 1)
@ -2369,7 +2379,7 @@ $(docdir)/gpl.7: $(docdir)/include/gpl.texi
$(docdir)/fsf-funding.7: $(docdir)/include/funding.texi
$(STAMP) $(docdir)/fsf-funding.7
-$(TEXI2POD) < $(docdir)/include/funding.texi > fsf-funding.pod
-$(TEXI2POD) $(docdir)/include/funding.texi > fsf-funding.pod
-($(POD2MAN) --section=7 fsf-funding.pod \
> $(docdir)/fsf-funding.7.T$$$$ && \
mv -f $(docdir)/fsf-funding.7.T$$$$ $(docdir)/fsf-funding.7) || \
@ -2467,7 +2477,7 @@ distclean: clean $(INTL_DISTCLEAN) lang.distclean
-rm -f testsuite/{gcc,g++}.{log,sum}
-rm -f intl/libintl.h libintl.h
-rm -f cxxmain.c
-rm -f mklibgcc libgcc.map gccbug .gdbinit configargs.h
-rm -f mklibgcc gccbug .gdbinit configargs.h
-rm -f gcov.pod
-rm -f fixinc/Makefile
-rmdir ada cp f java objc fixinc intl po 2>/dev/null
@ -2871,12 +2881,17 @@ site.exp: ./config.status Makefile
-e '1,/^## All variables above are.*##/ d' >> site.exp
-@rm -f ./tmp?
CHECK_TARGETS = check-gcc @check_languages@
CHECK_TARGETS = check-gcc check-fixinc @check_languages@
check-c++ : check-g++
check-f77 : check-g77
check-java :
check-fixinc :
if (autogen --ver=v) > /dev/null 2>&1 ; \
then cd fixinc && $(MAKE) check ; \
else true ; fi
check: $(CHECK_TARGETS)
# The idea is to parallelize testing of multilibs, for example:

View File

@ -728,6 +728,7 @@ find_base_value (src)
rtx src;
{
unsigned int regno;
switch (GET_CODE (src))
{
case SYMBOL_REF:
@ -744,12 +745,12 @@ find_base_value (src)
return new_reg_base_value[regno];
/* If a pseudo has a known base value, return it. Do not do this
for hard regs since it can result in a circular dependency
chain for registers which have values at function entry.
for non-fixed hard regs since it can result in a circular
dependency chain for registers which have values at function entry.
The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if (regno >= FIRST_PSEUDO_REGISTER
if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
&& regno < reg_base_value_size
&& reg_base_value[regno])
return reg_base_value[regno];
@ -846,8 +847,6 @@ find_base_value (src)
if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
break;
/* Fall through. */
case ZERO_EXTEND:
case SIGN_EXTEND: /* used for NT/Alpha pointers */
case HIGH:
case PRE_INC:
case PRE_DEC:
@ -857,6 +856,19 @@ find_base_value (src)
case POST_MODIFY:
return find_base_value (XEXP (src, 0));
case ZERO_EXTEND:
case SIGN_EXTEND: /* used for NT/Alpha pointers */
{
rtx temp = find_base_value (XEXP (src, 0));
#ifdef POINTERS_EXTEND_UNSIGNED
if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
temp = convert_memory_address (Pmode, temp);
#endif
return temp;
}
default:
break;
}
@ -1230,8 +1242,6 @@ find_base_term (x)
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
return 0;
/* Fall through. */
case ZERO_EXTEND:
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
case HIGH:
case PRE_INC:
case PRE_DEC:
@ -1241,6 +1251,19 @@ find_base_term (x)
case POST_MODIFY:
return find_base_term (XEXP (x, 0));
case ZERO_EXTEND:
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
{
rtx temp = find_base_term (XEXP (x, 0));
#ifdef POINTERS_EXTEND_UNSIGNED
if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
temp = convert_memory_address (Pmode, temp);
#endif
return temp;
}
case VALUE:
val = CSELIB_VAL_PTR (x);
for (l = val->locs; l; l = l->next)
@ -1999,6 +2022,13 @@ true_dependence (mem, mem_mode, x, varies)
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
This is used in epilogue deallocation functions. */
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
return 1;
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
return 1;
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
@ -2074,6 +2104,13 @@ canon_true_dependence (mem, mem_mode, mem_addr, x, varies)
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
This is used in epilogue deallocation functions. */
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
return 1;
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
return 1;
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
@ -2133,6 +2170,13 @@ write_dependence_p (mem, x, writep)
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything.
This is used in epilogue deallocation functions. */
if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
return 1;
if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
return 1;
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
@ -2253,6 +2297,7 @@ nonlocal_mentioned_p (x)
case CC0:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case LABEL_REF:
return 0;

View File

@ -1,5 +1,6 @@
/* ANSI and traditional C compatability macros
Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
@ -20,144 +21,275 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
ANSI C is assumed if __STDC__ is #defined.
Macro ANSI C definition Traditional C definition
----- ---- - ---------- ----------- - ----------
PTR `void *' `char *'
LONG_DOUBLE `long double' `double'
VOLATILE `volatile' `'
SIGNED `signed' `'
PTRCONST `void *const' `char *'
ANSI_PROTOTYPES 1 not defined
Macro ANSI C definition Traditional C definition
----- ---- - ---------- ----------- - ----------
ANSI_PROTOTYPES 1 not defined
PTR `void *' `char *'
PTRCONST `void *const' `char *'
LONG_DOUBLE `long double' `double'
const not defined `'
volatile not defined `'
signed not defined `'
VA_START(ap, var) va_start(ap, var) va_start(ap)
CONST is also defined, but is obsolete. Just use const.
Note that it is safe to write "void foo();" indicating a function
with no return value, in all K+R compilers we have been able to test.
obsolete -- DEFUN (name, arglist, args)
For declaring functions with prototypes, we also provide these:
Defines function NAME.
PARAMS ((prototype))
-- for functions which take a fixed number of arguments. Use this
when declaring the function. When defining the function, write a
K+R style argument list. For example:
ARGLIST lists the arguments, separated by commas and enclosed in
parentheses. ARGLIST becomes the argument list in traditional C.
char *strcpy PARAMS ((char *dest, char *source));
...
char *
strcpy (dest, source)
char *dest;
char *source;
{ ... }
ARGS list the arguments with their types. It becomes a prototype in
ANSI C, and the type declarations in traditional C. Arguments should
be separated with `AND'. For functions with a variable number of
arguments, the last thing listed should be `DOTS'.
obsolete -- DEFUN_VOID (name)
VPARAMS ((prototype, ...))
-- for functions which take a variable number of arguments. Use
PARAMS to declare the function, VPARAMS to define it. For example:
Defines a function NAME, which takes no arguments.
int printf PARAMS ((const char *format, ...));
...
int
printf VPARAMS ((const char *format, ...))
{
...
}
obsolete -- EXFUN (name, (prototype)) -- obsolete.
For writing functions which take variable numbers of arguments, we
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
thoroughly than the simple VA_START() macro mentioned above.
Replaced by PARAMS. Do not use; will disappear someday soon.
Was used in external function declarations.
In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
parentheses). In traditional C it is `NAME()'.
For a function that takes no arguments, PROTOTYPE should be `(void)'.
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
corresponding to the list of fixed arguments. Then use va_arg
normally to get the variable arguments, or pass your va_list object
around. You do not declare the va_list yourself; VA_OPEN does it
for you.
obsolete -- PROTO (type, name, (prototype) -- obsolete.
Here is a complete example:
This one has also been replaced by PARAMS. Do not use.
int
printf VPARAMS ((const char *format, ...))
{
int result;
PARAMS ((args))
VA_OPEN (ap, format);
VA_FIXEDARG (ap, const char *, format);
We could use the EXFUN macro to handle prototype declarations, but
the name is misleading and the result is ugly. So we just define a
simple macro to handle the parameter lists, as in:
result = vfprintf (stdout, format, ap);
VA_CLOSE (ap);
static int foo PARAMS ((int, char));
return result;
}
This produces: `static int foo();' or `static int foo (int, char);'
EXFUN would have done it like this:
You can declare variables either before or after the VA_OPEN,
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
and end of a block. They must appear at the same nesting level,
and any variables declared after VA_OPEN go out of scope at
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
pairs in a single function in case you need to traverse the
argument list more than once.
static int EXFUN (foo, (int, char));
For ease of writing code which uses GCC extensions but needs to be
portable to other compilers, we provide the GCC_VERSION macro that
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
wrappers around __attribute__. Also, __extension__ will be #defined
to nothing if it doesn't work. See below.
but the function is not external...and it's hard to visually parse
the function name out of the mess. EXFUN should be considered
obsolete; new code should be written to use PARAMS.
DOTS is also obsolete.
Examples:
extern int printf PARAMS ((const char *format, ...));
*/
This header also defines a lot of obsolete macros:
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
AND, DOTS, NOARGS. Don't use them. */
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1
#define _ANSIDECL_H 1
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
older preprocessors. Thus we can't define something like this:
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
and then test "#if HAVE_GCC_VERSION(2,7)".
So instead we use the macro below and test it against specific values. */
/* This macro simplifies testing whether we are using gcc, and if it
is of a particular minimum version. (Both major & minor numbers are
significant.) This macro will evaluate to 0 if we are not using
gcc at all. */
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
/* All known AIX compilers implement these things (but don't always
define __STDC__). The RISC/OS MIPS compiler defines these things
in SVR4 mode, but does not define __STDC__. */
#define PTR void *
#define PTRCONST void *CONST
#define LONG_DOUBLE long double
#define ANSI_PROTOTYPES 1
#define PTR void *
#define PTRCONST void *const
#define LONG_DOUBLE long double
#ifndef IN_GCC
#define AND ,
#define NOARGS void
#define VOLATILE volatile
#define SIGNED signed
#endif /* ! IN_GCC */
#define PARAMS(ARGS) ARGS
#define VPARAMS(ARGS) ARGS
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
#define PARAMS(paramlist) paramlist
#define ANSI_PROTOTYPES 1
/* variadic function helper macros */
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
use without inhibiting further decls and without declaring an
actual variable. */
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
#define VA_CLOSE(AP) } va_end(AP); }
#define VA_FIXEDARG(AP, T, N) struct Qdmy
#undef const
#undef volatile
#undef signed
#define VPARAMS(ARGS) ARGS
#define VA_START(va_list,var) va_start(va_list,var)
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
#if __STDC_VERSION__ > 199901L
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
# else
# define inline /* nothing */
# endif
#endif
/* These are obsolete. Do not use. */
#ifndef IN_GCC
#define CONST const
#define DOTS , ...
#define CONST const
#define VOLATILE volatile
#define SIGNED signed
#define PROTO(type, name, arglist) type name arglist
#define EXFUN(name, proto) name proto
#define DEFUN(name, arglist, args) name(args)
#define DEFUN_VOID(name) name(void)
#define AND ,
#define DOTS , ...
#define NOARGS void
#endif /* ! IN_GCC */
#else /* Not ANSI C. */
#define PTR char *
#define PTRCONST PTR
#define LONG_DOUBLE double
#undef ANSI_PROTOTYPES
#define PTR char *
#define PTRCONST PTR
#define LONG_DOUBLE double
#ifndef IN_GCC
#define AND ;
#define NOARGS
#define VOLATILE
#define SIGNED
#endif /* !IN_GCC */
#define PARAMS(args) ()
#define VPARAMS(args) (va_alist) va_dcl
#define VA_START(va_list, var) va_start(va_list)
#ifndef const /* some systems define it in header files for non-ansi mode */
#define const
#endif
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
#define VA_CLOSE(AP) } va_end(AP); }
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
#define PARAMS(paramlist) ()
/* some systems define these in header files for non-ansi mode */
#undef const
#undef volatile
#undef signed
#undef inline
#define const
#define volatile
#define signed
#define inline
#define VPARAMS(ARGS) (va_alist) va_dcl
#define VA_START(va_list,var) va_start(va_list)
/* These are obsolete. Do not use. */
#ifndef IN_GCC
#define CONST
#define DOTS
#define VOLATILE
#define SIGNED
#define PROTO(type, name, arglist) type name ()
#define EXFUN(name, proto) name()
#define DEFUN(name, arglist, args) name arglist args;
#define DEFUN_VOID(name) name()
#define AND ;
#define DOTS
#define NOARGS
#endif /* ! IN_GCC */
#endif /* ANSI C. */
/* Define macros for some gcc attributes. This permits us to use the
macros freely, and know that they will come into play for the
version of gcc in which they are supported. */
#if (GCC_VERSION < 2007)
# define __attribute__(x)
#endif
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
#ifndef ATTRIBUTE_MALLOC
# if (GCC_VERSION >= 2096)
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
# else
# define ATTRIBUTE_MALLOC
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */
/* Attributes on labels were valid as of gcc 2.93. */
#ifndef ATTRIBUTE_UNUSED_LABEL
# if (GCC_VERSION >= 2093)
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif /* GNUC >= 2.93 */
#endif /* ATTRIBUTE_UNUSED_LABEL */
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif /* ATTRIBUTE_UNUSED */
#ifndef ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
#endif /* ATTRIBUTE_NORETURN */
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */
#if GCC_VERSION < 2008
#define __extension__
#endif
/* Bootstrap support: Adjust certain macros defined by Autoconf,
which are only valid for the stage1 compiler. If we detect
a modern version of GCC, we are probably in stage2 or beyond,
so unconditionally reset the values. Note that const, inline,
etc. have been dealt with above. */
#if (GCC_VERSION >= 2007)
# ifndef HAVE_LONG_DOUBLE
# define HAVE_LONG_DOUBLE 1
# endif
#endif /* GCC >= 2.7 */
#endif /* ansidecl.h */

View File

@ -51,6 +51,8 @@ static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_used_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int,
@ -109,6 +111,8 @@ static const struct attribute_spec c_common_attribute_table[] =
handle_noreturn_attribute },
{ "noinline", 0, 0, true, false, false,
handle_noinline_attribute },
{ "always_inline", 0, 0, true, false, false,
handle_always_inline_attribute },
{ "used", 0, 0, true, false, false,
handle_used_attribute },
{ "unused", 0, 0, false, false, false,
@ -382,7 +386,9 @@ decl_attributes (node, attributes, flags)
/* Layout the decl in case anything changed. */
if (spec->type_required && DECL_P (*node)
&& TREE_CODE (*node) == VAR_DECL)
&& (TREE_CODE (*node) == VAR_DECL
|| TREE_CODE (*node) == PARM_DECL
|| TREE_CODE (*node) == RESULT_DECL))
{
/* Force a recalculation of mode and size. */
DECL_MODE (*node) = VOIDmode;
@ -563,6 +569,31 @@ handle_noinline_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
/* Handle a "always_inline" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
tree *node;
tree name;
tree args ATTRIBUTE_UNUSED;
int flags ATTRIBUTE_UNUSED;
bool *no_add_attrs;
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
/* Do nothing else, just set the attribute. We'll get at
it later with lookup_attribute. */
}
else
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
return NULL_TREE;
}
/* Handle a "used" attribute; arguments as in
struct attribute_spec.handler. */
@ -1431,3 +1462,4 @@ strip_attrs (specs_attrs)
return specs;
}

View File

@ -1,5 +1,5 @@
/* Define control and data flow tables, and regsets.
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GCC.
@ -311,6 +311,7 @@ extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx));
extern basic_block create_basic_block PARAMS ((int, rtx, rtx));
extern int flow_delete_block PARAMS ((basic_block));
extern int flow_delete_block_noexpunge PARAMS ((basic_block));
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
basic_block));
@ -629,6 +630,7 @@ extern void debug_regset PARAMS ((regset));
extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void));
extern void expunge_block PARAMS ((basic_block));
extern void expunge_block_nocompact PARAMS ((basic_block));
extern basic_block alloc_block PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void));
extern void delete_noop_moves PARAMS ((rtx));
@ -689,6 +691,7 @@ extern conflict_graph conflict_graph_compute
partition));
extern bool mark_dfs_back_edges PARAMS ((void));
extern void update_br_prob_note PARAMS ((basic_block));
extern void fixup_abnormal_edges PARAMS ((void));
/* In dominance.c */

View File

@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
Copyright (C) 2000 Free Software Foundation, Inc.
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@ -89,6 +89,7 @@
#include "flags.h"
#include "output.h"
#include "cfglayout.h"
#include "target.h"
/* Local function prototypes. */
static void make_reorder_chain PARAMS ((void));
@ -260,6 +261,9 @@ reorder_basic_blocks ()
if (n_basic_blocks <= 1)
return;
if ((* targetm.cannot_modify_jumps_p) ())
return;
cfg_layout_initialize ();
make_reorder_chain ();

View File

@ -2991,37 +2991,54 @@ rtx
std_expand_builtin_va_arg (valist, type)
tree valist, type;
{
tree addr_tree, t;
HOST_WIDE_INT align;
HOST_WIDE_INT rounded_size;
tree addr_tree, t, type_size = NULL;
tree align, alignm1;
tree rounded_size;
rtx addr;
/* Compute the rounded size of the type. */
align = PARM_BOUNDARY / BITS_PER_UNIT;
rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))
rounded_size = size_zero_node;
else
rounded_size = fold (build (MULT_EXPR, sizetype,
fold (build (TRUNC_DIV_EXPR, sizetype,
fold (build (PLUS_EXPR, sizetype,
type_size, alignm1)),
align)),
align));
/* Get AP. */
addr_tree = valist;
if (PAD_VARARGS_DOWN)
if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
{
/* Small args are padded downward. */
HOST_WIDE_INT adj
= rounded_size > align ? rounded_size : int_size_in_bytes (type);
addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
build_int_2 (rounded_size - adj, 0));
addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
fold (build (COND_EXPR, sizetype,
fold (build (GT_EXPR, sizetype,
rounded_size,
align)),
size_zero_node,
fold (build (MINUS_EXPR, sizetype,
rounded_size,
type_size))))));
}
addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
addr = copy_to_reg (addr);
/* Compute new value for AP. */
t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
build (PLUS_EXPR, TREE_TYPE (valist), valist,
build_int_2 (rounded_size, 0)));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
if (! integer_zerop (rounded_size))
{
t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
build (PLUS_EXPR, TREE_TYPE (valist), valist,
rounded_size));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
return addr;
}
@ -3064,7 +3081,7 @@ expand_builtin_va_arg (valist, type)
else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
{
const char *name = "<anonymous type>", *pname = 0;
static int gave_help;
static bool gave_help;
if (TYPE_NAME (type))
{
@ -3083,13 +3100,24 @@ expand_builtin_va_arg (valist, type)
pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
}
error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
/* Unfortunately, this is merely undefined, rather than a constraint
violation, so we cannot make this an error. If this call is never
executed, the program is still strictly conforming. */
warning ("`%s' is promoted to `%s' when passed through `...'",
name, pname);
if (! gave_help)
{
gave_help = 1;
error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
gave_help = true;
warning ("(so you should pass `%s' not `%s' to `va_arg')",
pname, name);
}
/* We can, however, treat "undefined" any way we please.
Call abort to encourage the user to fix the program. */
expand_builtin_trap ();
/* This is dead code, but go ahead and finish so that the
mode of the result comes out right. */
addr = const0_rtx;
}
else
@ -3541,6 +3569,18 @@ expand_builtin_expect_jump (exp, if_false_label, if_true_label)
return ret;
}
void
expand_builtin_trap ()
{
#ifdef HAVE_trap
if (HAVE_trap)
emit_insn (gen_trap ());
else
#endif
emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
emit_barrier ();
}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@ -3875,13 +3915,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
}
case BUILT_IN_TRAP:
#ifdef HAVE_trap
if (HAVE_trap)
emit_insn (gen_trap ());
else
#endif
error ("__builtin_trap not supported by this target");
emit_barrier ();
expand_builtin_trap ();
return const0_rtx;
case BUILT_IN_PUTCHAR:

View File

@ -587,7 +587,7 @@ combine_strings (strings)
{
length += (TREE_STRING_LENGTH (t) - 1);
if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
warning ("concatenation of string literals with __FUNCTION__ is deprecated. This feature will be removed in future");
warning ("concatenation of string literals with __FUNCTION__ is deprecated");
}
}
@ -596,7 +596,7 @@ combine_strings (strings)
if (wide_flag)
length = length * wchar_bytes + wide_length;
p = alloca (length);
p = xmalloc (length);
/* Copy the individual strings into the new combined string.
If the combined string is wide, convert the chars to ints
@ -643,6 +643,7 @@ combine_strings (strings)
*q = 0;
value = build_string (length, p);
free (p);
}
else
{
@ -702,6 +703,7 @@ constant_expression_warning (value)
tree value;
{
if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
|| TREE_CODE (value) == VECTOR_CST
|| TREE_CODE (value) == COMPLEX_CST)
&& TREE_CONSTANT_OVERFLOW (value) && pedantic)
pedwarn ("overflow in constant expression");
@ -736,6 +738,12 @@ overflow_warning (value)
if (skip_evaluation == 0)
warning ("floating point overflow in expression");
}
else if (TREE_CODE (value) == VECTOR_CST && TREE_OVERFLOW (value))
{
TREE_OVERFLOW (value) = 0;
if (skip_evaluation == 0)
warning ("vector overflow in expression");
}
}
/* Print a warning if a large constant is truncated to unsigned,
@ -1408,6 +1416,8 @@ type_for_mode (mode, unsignedp)
return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
case V8QImode:
return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
case V16SFmode:
return V16SF_type_node;
case V4SFmode:
return V4SF_type_node;
case V2SFmode:
@ -1973,6 +1983,107 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
return 0;
}
/* Return a tree for the sum or difference (RESULTCODE says which)
of pointer PTROP and integer INTOP. */
tree
pointer_int_sum (resultcode, ptrop, intop)
enum tree_code resultcode;
tree ptrop, intop;
{
tree size_exp;
tree result;
tree folded;
/* The result is a pointer of the same type that is being added. */
tree result_type = TREE_TYPE (ptrop);
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer of type `void *' used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer to a function used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer to member function used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer to a member used in arithmetic");
size_exp = integer_one_node;
}
else
size_exp = size_in_bytes (TREE_TYPE (result_type));
/* If what we are about to multiply by the size of the elements
contains a constant term, apply distributive law
and multiply that constant term separately.
This helps produce common subexpressions. */
if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
&& ! TREE_CONSTANT (intop)
&& TREE_CONSTANT (TREE_OPERAND (intop, 1))
&& TREE_CONSTANT (size_exp)
/* If the constant comes from pointer subtraction,
skip this optimization--it would cause an error. */
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
/* If the constant is unsigned, and smaller than the pointer size,
then we must skip this optimization. This is because it could cause
an overflow error if the constant is negative but INTOP is not. */
&& (! TREE_UNSIGNED (TREE_TYPE (intop))
|| (TYPE_PRECISION (TREE_TYPE (intop))
== TYPE_PRECISION (TREE_TYPE (ptrop)))))
{
enum tree_code subcode = resultcode;
tree int_type = TREE_TYPE (intop);
if (TREE_CODE (intop) == MINUS_EXPR)
subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
/* Convert both subexpression types to the type of intop,
because weird cases involving pointer arithmetic
can result in a sum or difference with different type args. */
ptrop = build_binary_op (subcode, ptrop,
convert (int_type, TREE_OPERAND (intop, 1)), 1);
intop = convert (int_type, TREE_OPERAND (intop, 0));
}
/* Convert the integer argument to a type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|| TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
intop = convert (type_for_size (TYPE_PRECISION (sizetype),
TREE_UNSIGNED (sizetype)), intop);
/* Replace the integer argument with a suitable product by the object size.
Do this multiplication as signed, then convert to the appropriate
pointer type (actually unsigned integral). */
intop = convert (result_type,
build_binary_op (MULT_EXPR, intop,
convert (TREE_TYPE (intop), size_exp), 1));
/* Create the sum or difference. */
result = build (resultcode, result_type, ptrop, intop);
folded = fold (result);
if (folded == result)
TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
return folded;
}
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
or validate its data type for an `if' or `while' statement or ?..: exp.
@ -3096,6 +3207,7 @@ statement_code_p (code)
{
switch (code)
{
case CLEANUP_STMT:
case EXPR_STMT:
case COMPOUND_STMT:
case DECL_STMT:
@ -3455,6 +3567,7 @@ c_expand_expr (exp, target, tmode, modifier)
{
tree rtl_expr;
rtx result;
bool preserve_result = false;
/* Since expand_expr_stmt calls free_temp_slots after every
expression statement, we must call push_temp_slots here.
@ -3462,7 +3575,7 @@ c_expand_expr (exp, target, tmode, modifier)
out-of-scope after the first EXPR_STMT from within the
STMT_EXPR. */
push_temp_slots ();
rtl_expr = expand_start_stmt_expr ();
rtl_expr = expand_start_stmt_expr (!STMT_EXPR_NO_SCOPE (exp));
/* If we want the result of this expression, find the last
EXPR_STMT in the COMPOUND_STMT and mark it as addressable. */
@ -3481,12 +3594,30 @@ c_expand_expr (exp, target, tmode, modifier)
if (TREE_CODE (last) == SCOPE_STMT
&& TREE_CODE (expr) == EXPR_STMT)
TREE_ADDRESSABLE (expr) = 1;
{
TREE_ADDRESSABLE (expr) = 1;
preserve_result = true;
}
}
expand_stmt (STMT_EXPR_STMT (exp));
expand_end_stmt_expr (rtl_expr);
result = expand_expr (rtl_expr, target, tmode, modifier);
if (preserve_result && GET_CODE (result) == MEM)
{
if (GET_MODE (result) != BLKmode)
result = copy_to_reg (result);
else
preserve_temp_slots (result);
}
/* If the statment-expression does not have a scope, then the
new temporaries we created within it must live beyond the
statement-expression. */
if (STMT_EXPR_NO_SCOPE (exp))
preserve_temp_slots (NULL_RTX);
pop_temp_slots ();
return result;
}
@ -3557,8 +3688,10 @@ int
c_unsafe_for_reeval (exp)
tree exp;
{
/* Statement expressions may not be reevaluated. */
if (TREE_CODE (exp) == STMT_EXPR)
/* Statement expressions may not be reevaluated, likewise compound
literals. */
if (TREE_CODE (exp) == STMT_EXPR
|| TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
return 2;
/* Walk all other expressions. */
@ -3997,15 +4130,14 @@ c_common_post_options ()
{
cpp_post_options (parse_in);
flag_inline_trees = 1;
/* Use tree inlining if possible. Function instrumentation is only
done in the RTL level, so we disable tree inlining. */
if (! flag_instrument_function_entry_exit)
{
if (!flag_no_inline)
{
flag_inline_trees = 1;
flag_no_inline = 1;
}
flag_no_inline = 1;
if (flag_inline_functions)
{
flag_inline_trees = 2;

View File

@ -71,8 +71,8 @@ DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
/* Used to represent a 'switch' statement. The operands are
SWITCH_COND and SWITCH_BODY, respectively. */
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 2)
SWITCH_COND, SWITCH_BODY and SWITCH_TYPE, respectively. */
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 3)
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
@ -113,6 +113,11 @@ DEFTREECODE (STMT_EXPR, "stmt_expr", 'e', 1)
the compound literal. */
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1)
/* A CLEANUP_STMT marks the point at which a declaration is fully
constructed. If, after this point, the CLEANUP_DECL goes out of
scope, the CLEANUP_EXPR must be run. */
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
/*
Local variables:
mode:c

View File

@ -33,6 +33,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
DECL_PRETTY_FUNCTION_P (in VAR_DECL)
NEW_FOR_SCOPE_P (in FOR_STMT)
ASM_INPUT_P (in ASM_STMT)
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
1: C_DECLARED_LABEL_FLAG (in LABEL_DECL)
STMT_IS_FULL_EXPR_P (in _STMT)
2: STMT_LINENO_FOR_FN_P (in _STMT)
@ -538,6 +539,7 @@ extern char *get_directive_line PARAMS ((void));
and, if so, perhaps change them both back to their original type. */
extern tree shorten_compare PARAMS ((tree *, tree *, tree *, enum tree_code *));
extern tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
extern unsigned int min_precision PARAMS ((tree, int));
/* Add qualifiers to a type, in the fashion for C. */
@ -603,10 +605,12 @@ extern tree strip_array_types PARAMS ((tree));
#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
/* SWITCH_STMT accessors. These give access to the condition and body
/* SWITCH_STMT accessors. These give access to the condition, body and
original condition type (before any compiler conversions)
of the switch statement, respectively. */
#define SWITCH_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
#define SWITCH_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
#define SWITCH_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
/* CASE_LABEL accessors. These give access to the high and low values
of a case label, respectively. */
@ -643,6 +647,10 @@ extern tree strip_array_types PARAMS ((tree));
/* STMT_EXPR accessor. */
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
/* Nonzero if this statement-expression does not have an associated scope. */
#define STMT_EXPR_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
/* LABEL_STMT accessor. This gives access to the label associated with
the given label statement. */
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND (LABEL_STMT_CHECK (NODE), 0)
@ -694,6 +702,13 @@ extern tree strip_array_types PARAMS ((tree));
#define ASM_VOLATILE_P(NODE) \
(ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
/* The VAR_DECL to clean up in a CLEANUP_STMT. */
#define CLEANUP_DECL(NODE) \
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
/* The cleanup to run in a CLEANUP_STMT. */
#define CLEANUP_EXPR(NODE) \
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
/* The filename we are changing to as of this FILE_STMT. */
#define FILE_STMT_FILENAME_NODE(NODE) \
(TREE_OPERAND (FILE_STMT_CHECK (NODE), 0))
@ -749,7 +764,7 @@ extern void genrtl_compound_stmt PARAMS ((tree));
extern void genrtl_asm_stmt PARAMS ((tree, tree,
tree, tree,
tree, int));
extern void genrtl_decl_cleanup PARAMS ((tree, tree));
extern void genrtl_decl_cleanup PARAMS ((tree));
extern int stmts_are_full_exprs_p PARAMS ((void));
extern int anon_aggr_type_p PARAMS ((tree));

View File

@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "timevar.h"
#include "c-common.h"
#include "c-pragma.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@ -53,6 +54,7 @@ enum decl_context
FUNCDEF, /* Function definition */
PARM, /* Declaration of parm before function body */
FIELD, /* Declaration inside struct or union */
BITFIELD, /* Likewise but with specified width */
TYPENAME}; /* Typename (inside cast or sizeof) */
@ -133,6 +135,11 @@ int current_function_returns_value;
int current_function_returns_null;
/* Set to 0 at beginning of a function definition, set to 1 if
a call to a noreturn function is seen. */
int current_function_returns_abnormally;
/* Set to nonzero by `grokdeclarator' for a function
whose return type is defaulted, if warnings for this are desired. */
@ -275,13 +282,12 @@ static tree lookup_tag PARAMS ((enum tree_code, tree,
struct binding_level *, int));
static tree lookup_tag_reverse PARAMS ((tree));
static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
int, tree));
int));
static tree grokparms PARAMS ((tree, int));
static void layout_array_type PARAMS ((tree));
static tree c_make_fname_decl PARAMS ((tree, int));
static void c_expand_body PARAMS ((tree, int, int));
static void warn_if_shadowing PARAMS ((tree, tree));
static tree build_bitfield_integer_type PARAMS ((tree, tree, const char *));
/* C-specific option variables. */
@ -319,7 +325,7 @@ int flag_noniso_default_format_attributes = 1;
being traditional. */
int flag_allow_single_precision = 0;
/* Nonzero means to treat bit-fields as signed unless they say `unsigned'. */
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
@ -1543,6 +1549,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
}
else if (TYPE_ARG_TYPES (oldtype) == NULL
&& TYPE_ARG_TYPES (newtype) != NULL)
{
/* For bcmp, bzero, fputs the builtin type has arguments not
specified. Use the ones from the prototype so that type checking
is done for them. */
tree trytype
= build_function_type (TREE_TYPE (oldtype),
TYPE_ARG_TYPES (newtype));
trytype = build_type_attribute_variant (trytype,
TYPE_ATTRIBUTES (oldtype));
oldtype = trytype;
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
}
if (!types_match)
{
/* If types don't match for a built-in, throw away the built-in. */
@ -1669,6 +1691,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& current_binding_level == global_binding_level)
? "`%s' previously defined here"
: "`%s' previously declared here"));
return 0;
}
else if (TREE_CODE (newdecl) == TYPE_DECL
&& (DECL_IN_SYSTEM_HEADER (olddecl)
@ -1932,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
}
/* Merge the storage class information. */
DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
merge_weak (newdecl, olddecl);
/* For functions, static overrides non-static. */
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@ -2177,11 +2201,13 @@ pushdecl (x)
not errors. X11 for instance depends on this. */
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
{
t = lookup_name (name);
t = IDENTIFIER_GLOBAL_VALUE (name);
/* Type decls at global scope don't conflict with externs declared
inside lexical blocks. */
if (t && TREE_CODE (t) == TYPE_DECL)
t = 0;
if (! t || TREE_CODE (t) == TYPE_DECL)
/* If there's no visible global declaration, try for an
invisible one. */
t = IDENTIFIER_LIMBO_VALUE (name);
different_binding_level = 1;
}
if (t != 0 && t == error_mark_node)
@ -3053,8 +3079,7 @@ c_init_decl_processing ()
boolean_true_node = integer_one_node;
boolean_false_node = integer_zero_node;
/* With GCC, C99's _Bool is always of size 1. */
c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
@ -3214,6 +3239,10 @@ builtin_function (name, type, function_code, class, library_name)
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = function_code;
/* The return builtins leave the current function. */
if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
TREE_THIS_VOLATILE (decl) = 1;
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
if (name[0] != '_' || name[1] != '_')
@ -3390,8 +3419,7 @@ groktypename (typename)
split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
NULL_TREE);
typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
/* Apply attributes. */
decl_attributes (&typename, attrs, 0);
@ -3409,7 +3437,7 @@ groktypename_in_parm_context (typename)
return typename;
return grokdeclarator (TREE_VALUE (typename),
TREE_PURPOSE (typename),
PARM, 0, NULL_TREE);
PARM, 0);
}
/* Decode a declarator in an ordinary declaration or data definition.
@ -3442,7 +3470,7 @@ start_decl (declarator, declspecs, initialized, attributes)
deprecated_state = DEPRECATED_SUPPRESS;
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized, NULL_TREE);
NORMAL, initialized);
deprecated_state = DEPRECATED_NORMAL;
@ -3551,6 +3579,10 @@ start_decl (declarator, declspecs, initialized, attributes)
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl);
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
@ -3596,6 +3628,8 @@ finish_decl (decl, init, asmspec_tree)
const char *asmspec = 0;
/* If a name was specified, get the string. */
if (current_binding_level == global_binding_level)
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
@ -3820,8 +3854,7 @@ push_parm_decl (parm)
immediate_size_expand = 0;
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
TREE_PURPOSE (TREE_PURPOSE (parm)),
PARM, 0, NULL_TREE);
TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
decl_attributes (&decl, TREE_VALUE (parm), 0);
#if 0
@ -3981,92 +4014,6 @@ complete_array_type (type, initial_value, do_default)
return value;
}
/* A bit-field NAME should have an integer type whose precision
accurately reflects its WIDTH. If TYPE is good for that, return
it, otherwise create and return the appropriate type.
This routine also performs sanity checks on the bit-field's type
and width, and uses appropriate values if they are invalid. */
static tree
build_bitfield_integer_type (type, width, orig_name)
tree type, width;
const char *orig_name;
{
tree type_mv;
unsigned int max_width;
unsigned HOST_WIDE_INT w;
const char *name = orig_name ? orig_name: _("<anonymous>");
/* Necessary? */
STRIP_NOPS (width);
/* Detect and ignore out of range field width and process valid
field widths. */
if (TREE_CODE (width) != INTEGER_CST)
{
error ("bit-field `%s' width not an integer constant", name);
width = integer_one_node;
}
else
{
constant_expression_warning (width);
if (tree_int_cst_sgn (width) < 0)
{
error ("negative width in bit-field `%s'", name);
width = integer_one_node;
}
else if (integer_zerop (width) && orig_name)
{
error ("zero width for bit-field `%s'", name);
width = integer_one_node;
}
}
/* Detect invalid bit-field type. */
if (TREE_CODE (type) != INTEGER_TYPE
&& TREE_CODE (type) != BOOLEAN_TYPE
&& TREE_CODE (type) != ENUMERAL_TYPE)
{
error ("bit-field `%s' has invalid type", name);
type = unsigned_type_node;
}
type_mv = TYPE_MAIN_VARIANT (type);
if (pedantic
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
&& type_mv != c_bool_type_node
/* Accept an enum that's equivalent to int or unsigned int. */
&& (TREE_CODE (type) != ENUMERAL_TYPE
|| TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)))
pedwarn ("type of bit-field `%s' is a GCC extension", name);
if (type_mv == c_bool_type_node)
max_width = CHAR_TYPE_SIZE;
else
max_width = TYPE_PRECISION (type);
if (0 < compare_tree_int (width, max_width))
{
error ("width of `%s' exceeds its type", name);
w = max_width;
}
else
w = tree_low_cst (width, 1);
if (TREE_CODE (type) == ENUMERAL_TYPE
&& (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type))
|| w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type))))
warning ("`%s' is narrower than values of its type", name);
/* The type of a bit-field should have precision the same as the
bit-field's width. */
if (w != TYPE_PRECISION (type))
type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type));
return type;
}
/* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@ -4086,9 +4033,8 @@ build_bitfield_integer_type (type, width, orig_name)
TYPENAME if for a typename (in a cast or sizeof).
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
BITFIELD for a field with specified width.
INITIALIZED is 1 if the decl has an initializer.
WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing
the width of the bit-field.
In the TYPENAME case, DECLARATOR is really an absolute declarator.
It may also be so in the PARM case, for a prototype where the
@ -4098,12 +4044,11 @@ build_bitfield_integer_type (type, width, orig_name)
and `extern' are interpreted. */
static tree
grokdeclarator (declarator, declspecs, decl_context, initialized, width)
grokdeclarator (declarator, declspecs, decl_context, initialized)
tree declspecs;
tree declarator;
enum decl_context decl_context;
int initialized;
tree width;
{
int specbits = 0;
tree spec;
@ -4118,16 +4063,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
const char *name, *orig_name;
const char *name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
int bitfield = 0;
int size_varies = 0;
tree decl_attr = NULL_TREE;
tree array_ptr_quals = NULL_TREE;
int array_parm_static = 0;
tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL_TREE;
if (decl_context == BITFIELD)
bitfield = 1, decl_context = FIELD;
if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL;
@ -4160,7 +4108,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
default:
abort ();
}
orig_name = name;
if (name == 0)
name = "type name";
}
@ -4377,9 +4324,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
/* Decide whether an integer type is signed or not.
Optionally treat bit-fields as signed by default. */
Optionally treat bitfields as signed by default. */
if (specbits & 1 << (int) RID_UNSIGNED
/* Traditionally, all bit-fields are unsigned. */
/* Traditionally, all bitfields are unsigned. */
|| (bitfield && flag_traditional
&& (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
|| (bitfield && ! flag_signed_bitfields
@ -4452,11 +4399,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
}
/* A bit-field needs its type to have precision equal to its width,
rather than the precision of the specified standard type. */
if (bitfield)
type = build_bitfield_integer_type (type, width, orig_name);
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
like `const int i' where the `const' is explicit. Another is
@ -4602,9 +4544,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
if (inner_decl == NULL_TREE
|| TREE_CODE (inner_decl) == IDENTIFIER_NODE)
attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
if (TREE_CODE (inner_decl) == CALL_EXPR)
else if (TREE_CODE (inner_decl) == CALL_EXPR)
attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
if (TREE_CODE (inner_decl) == ARRAY_REF)
else if (TREE_CODE (inner_decl) == ARRAY_REF)
attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
returned_attrs = decl_attributes (&type,
chainon (returned_attrs, attrs),
@ -4723,10 +4665,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
else if (decl_context == FIELD)
{
/* ??? Need to check somewhere that this is a structure
and not a union, that this field is last, and that
this structure has at least one other named member. */
if (pedantic && !flag_isoc99 && !in_system_header)
pedwarn ("ISO C89 does not support flexible array members");
@ -5106,6 +5044,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
else if (decl_context == FIELD)
{
/* Structure field. It may not be a function. */
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error ("field `%s' declared as a function", name);
@ -5129,29 +5068,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
#endif
}
decl = build_decl (FIELD_DECL, declarator, type);
if (bitfield)
{
DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type));
DECL_BIT_FIELD (decl) = 1;
SET_DECL_C_BIT_FIELD (decl);
/* Bit-field width 0 => force desired amount of alignment. */
if (TYPE_PRECISION (type) == 0)
{
#ifdef EMPTY_FIELD_BOUNDARY
DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
{
DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
TYPE_ALIGN (type));
DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type);
}
#endif
}
}
DECL_NONADDRESSABLE_P (decl) = bitfield;
if (size_varies)
@ -5201,6 +5117,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
TREE_PUBLIC (decl)
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
if (defaulted_int)
C_FUNCTION_IMPLICIT_INT (decl) = 1;
/* Record presence of `inline', if it is reasonable. */
if (MAIN_NAME_P (declarator))
{
@ -5654,7 +5573,7 @@ start_struct (code, name)
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
of a structure component, returning a FIELD_DECL node.
WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
This is done during the parsing of the struct declaration.
The FIELD_DECL nodes are chained together and the lot of them
@ -5680,9 +5599,10 @@ grokfield (filename, line, declarator, declspecs, width)
}
}
value = grokdeclarator (declarator, declspecs, FIELD, 0, width);
value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
finish_decl (value, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
maybe_objc_check_decl (value);
return value;
@ -5734,7 +5654,10 @@ finish_struct (t, fieldlist, attributes)
fieldlist ? _("named members") : _("members"));
}
/* Install struct as DECL_CONTEXT of each field decl. */
/* Install struct as DECL_CONTEXT of each field decl.
Also process specified field sizes,m which is found in the DECL_INITIAL.
Store 0 there, except for ": 0" fields (so we can find them
and delete them, below). */
saw_named_field = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
@ -5770,7 +5693,94 @@ finish_struct (t, fieldlist, attributes)
error ("nested redefinition of `%s'",
IDENTIFIER_POINTER (TYPE_NAME (t)));
if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x))
/* Detect invalid bit-field size. */
if (DECL_INITIAL (x))
STRIP_NOPS (DECL_INITIAL (x));
if (DECL_INITIAL (x))
{
if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
constant_expression_warning (DECL_INITIAL (x));
else
{
error_with_decl (x,
"bit-field `%s' width not an integer constant");
DECL_INITIAL (x) = NULL;
}
}
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
&& TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
&& TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
{
error_with_decl (x, "bit-field `%s' has invalid type");
DECL_INITIAL (x) = NULL;
}
if (DECL_INITIAL (x) && pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
/* Accept an enum that's equivalent to int or unsigned int. */
&& !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (x))
== TYPE_PRECISION (integer_type_node))))
pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
/* Detect and ignore out of range field width and process valid
field widths. */
if (DECL_INITIAL (x))
{
int max_width
= (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
error_with_decl (x, "negative width in bit-field `%s'");
else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
pedwarn_with_decl (x, "width of `%s' exceeds its type");
else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
error_with_decl (x, "zero width for bit-field `%s'");
else
{
/* The test above has assured us that TREE_INT_CST_HIGH is 0. */
unsigned HOST_WIDE_INT width
= tree_low_cst (DECL_INITIAL (x), 1);
if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
TREE_UNSIGNED (TREE_TYPE (x)))
|| (width
< min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
TREE_UNSIGNED (TREE_TYPE (x))))))
warning_with_decl (x,
"`%s' is narrower than values of its type");
DECL_SIZE (x) = bitsize_int (width);
DECL_BIT_FIELD (x) = 1;
SET_DECL_C_BIT_FIELD (x);
if (width == 0
&& ! (* targetm.ms_bitfield_layout_p) (t))
{
/* field size 0 => force desired amount of alignment. */
#ifdef EMPTY_FIELD_BOUNDARY
DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
{
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
TYPE_ALIGN (TREE_TYPE (x)));
DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
}
#endif
}
}
}
else if (TREE_TYPE (x) != error_mark_node)
{
unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
: TYPE_ALIGN (TREE_TYPE (x)));
@ -5782,6 +5792,8 @@ finish_struct (t, fieldlist, attributes)
DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
}
DECL_INITIAL (x) = 0;
/* Detect flexible array member in an invalid context. */
if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
&& TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
@ -6197,6 +6209,7 @@ start_function (declspecs, declarator, attributes)
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
current_function_returns_abnormally = 0;
warn_about_return_type = 0;
current_extern_inline = 0;
c_function_varargs = 0;
@ -6206,7 +6219,7 @@ start_function (declspecs, declarator, attributes)
/* Don't expand any sizes in the return type of the function. */
immediate_size_expand = 0;
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
@ -6218,6 +6231,10 @@ start_function (declspecs, declarator, attributes)
decl_attributes (&decl1, attributes, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl1);
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
@ -6874,17 +6891,21 @@ store_parm_decls ()
This is called after parsing the body of the function definition.
NESTED is nonzero if the function being finished is nested in another. */
NESTED is nonzero if the function being finished is nested in another.
CAN_DEFER_P is nonzero if the function may be deferred. */
void
finish_function (nested)
finish_function (nested, can_defer_p)
int nested;
int can_defer_p;
{
tree fndecl = current_function_decl;
/* TREE_READONLY (fndecl) = 1;
This caused &foo to be of type ptr-to-const-function
which then got a warning when stored in a ptr-to-function variable. */
#if 0
/* This caused &foo to be of type ptr-to-const-function which then
got a warning when stored in a ptr-to-function variable. */
TREE_READONLY (fndecl) = 1;
#endif
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
@ -6926,6 +6947,22 @@ finish_function (nested)
/* Tie off the statement tree for this function. */
finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
/* Complain if there's just no return statement. */
if (warn_return_type
&& TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
&& !current_function_returns_value && !current_function_returns_null
/* Don't complain if we abort. */
&& !current_function_returns_abnormally
/* Don't warn for main(). */
&& !MAIN_NAME_P (DECL_NAME (fndecl))
/* Or if they didn't actually specify a return type. */
&& !C_FUNCTION_IMPLICIT_INT (fndecl)
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
&& DECL_INLINE (fndecl))
warning ("no return statement in function returning non-void");
/* Clear out memory we no longer need. */
free_after_parsing (cfun);
/* Since we never call rest_of_compilation, we never clear
@ -6936,7 +6973,8 @@ finish_function (nested)
if (! nested)
{
/* Generate RTL for the body of this function. */
c_expand_body (fndecl, nested, 1);
c_expand_body (fndecl, nested, can_defer_p);
/* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in
pop_c_function_context and then reset via pop_function_context. */
@ -7215,6 +7253,7 @@ struct c_language_function
tree shadowed_labels;
int returns_value;
int returns_null;
int returns_abnormally;
int warn_about_return_type;
int extern_inline;
struct binding_level *binding_level;
@ -7238,6 +7277,7 @@ push_c_function_context (f)
p->shadowed_labels = shadowed_labels;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
p->returns_abnormally = current_function_returns_abnormally;
p->warn_about_return_type = warn_about_return_type;
p->extern_inline = current_extern_inline;
p->binding_level = current_binding_level;
@ -7275,6 +7315,7 @@ pop_c_function_context (f)
shadowed_labels = p->shadowed_labels;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
current_function_returns_abnormally = p->returns_abnormally;
warn_about_return_type = p->warn_about_return_type;
current_extern_inline = p->extern_inline;
current_binding_level = p->binding_level;

View File

@ -1,6 +1,6 @@
/* Check calls to formatted I/O functions (-Wformat).
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@ -1516,13 +1516,12 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num)
res->number_non_literal++;
return;
}
if (!host_integerp (arg1, 1))
if (!host_integerp (arg1, 0)
|| (offset = tree_low_cst (arg1, 0)) < 0)
{
res->number_non_literal++;
return;
}
offset = TREE_INT_CST_LOW (arg1);
}
if (TREE_CODE (format_tree) != ADDR_EXPR)
{

View File

@ -65,6 +65,9 @@ static void c_post_options PARAMS ((void));
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
/* ### When changing hooks, consider if ObjC needs changing too!! ### */

View File

@ -85,7 +85,8 @@ static int ignore_escape_flag;
static void parse_float PARAMS ((PTR));
static tree lex_number PARAMS ((const char *, unsigned int));
static tree lex_string PARAMS ((const char *, unsigned int, int));
static tree lex_string PARAMS ((const unsigned char *, unsigned int,
int));
static tree lex_charconst PARAMS ((const cpp_token *));
static void update_header_times PARAMS ((const char *));
static int dump_one_header PARAMS ((splay_tree_node, void *));
@ -239,7 +240,7 @@ cb_ident (pfile, line, str)
if (! flag_no_ident)
{
/* Convert escapes in the string. */
tree value = lex_string ((const char *)str->text, str->len, 0);
tree value = lex_string (str->text, str->len, 0);
ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
}
#endif
@ -271,10 +272,12 @@ cb_file_change (pfile, new_map)
main_input_filename = new_map->to_file;
else
{
lineno = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
lineno = included_at;
push_srcloc (new_map->to_file, 1);
input_file_stack->indent_level = indent_level;
(*debug_hooks->start_source_file) (lineno, new_map->to_file);
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
++c_header_level;
@ -807,8 +810,8 @@ c_lex (value)
case CPP_STRING:
case CPP_WSTRING:
*value = lex_string ((const char *)tok->val.str.text,
tok->val.str.len, tok->type == CPP_WSTRING);
*value = lex_string (tok->val.str.text, tok->val.str.len,
tok->type == CPP_WSTRING);
break;
/* These tokens should not be visible outside cpplib. */
@ -1297,14 +1300,14 @@ lex_number (str, len)
static tree
lex_string (str, len, wide)
const char *str;
const unsigned char *str;
unsigned int len;
int wide;
{
tree value;
char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1));
char *q = buf;
const char *p = str, *limit = str + len;
const unsigned char *p = str, *limit = str + len;
unsigned int c;
unsigned width = wide ? WCHAR_TYPE_SIZE
: TYPE_PRECISION (char_type_node);
@ -1320,7 +1323,7 @@ lex_string (str, len, wide)
wchar_t wc;
int char_len;
char_len = local_mbtowc (&wc, p, limit - p);
char_len = local_mbtowc (&wc, (const char *) p, limit - p);
if (char_len == -1)
{
warning ("ignoring invalid multibyte character");
@ -1344,8 +1347,7 @@ lex_string (str, len, wide)
mask = ((unsigned int) 1 << width) - 1;
else
mask = ~0;
c = cpp_parse_escape (parse_in, (const unsigned char **) &p,
(const unsigned char *) limit,
c = cpp_parse_escape (parse_in, &p, limit,
mask, flag_traditional);
}
@ -1405,7 +1407,7 @@ lex_charconst (token)
const cpp_token *token;
{
HOST_WIDE_INT result;
tree value;
tree type, value;
unsigned int chars_seen;
result = cpp_interpret_charconst (parse_in, token, warn_multichar,
@ -1413,7 +1415,7 @@ lex_charconst (token)
if (token->type == CPP_WCHAR)
{
value = build_int_2 (result, 0);
TREE_TYPE (value) = wchar_type_node;
type = wchar_type_node;
}
else
{
@ -1425,10 +1427,24 @@ lex_charconst (token)
/* In C, a character constant has type 'int'.
In C++ 'char', but multi-char charconsts have type 'int'. */
if (c_language == clk_cplusplus && chars_seen <= 1)
TREE_TYPE (value) = char_type_node;
type = char_type_node;
else
TREE_TYPE (value) = integer_type_node;
type = integer_type_node;
}
/* cpp_interpret_charconst issues a warning if the constant
overflows, but if the number fits in HOST_WIDE_INT anyway, it
will return it un-truncated, which may cause problems down the
line. So set the type to widest_integer_literal_type, call
convert to truncate it to the proper type, then clear
TREE_OVERFLOW so we don't get a second warning.
FIXME: cpplib's assessment of overflow may not be accurate on a
platform where the final type can change at (compiler's) runtime. */
TREE_TYPE (value) = widest_integer_literal_type_node;
value = convert (type, value);
TREE_OVERFLOW (value) = 0;
return value;
}

View File

@ -59,6 +59,9 @@ int
c_disregard_inline_limits (fn)
tree fn;
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
}
@ -142,6 +145,10 @@ c_cannot_inline_tree_fn (fnp)
tree fn = *fnp;
tree t;
if (flag_really_no_inline
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
if (! function_attribute_inlinable_p (fn))
{
DECL_UNINLINABLE (fn) = 1;
@ -317,7 +324,7 @@ finish_cdtor (body)
RECHAIN_STMTS (body, COMPOUND_BODY (body));
finish_function (0);
finish_function (0, 0);
}
/* Called at end of parsing, but before end-of-file processing. */

View File

@ -395,7 +395,7 @@ fndef:
save_filename save_lineno compstmt_or_error
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
finish_function (0, 1);
POP_DECLSPEC_STACK; }
| declspecs_ts setspecs declarator error
{ POP_DECLSPEC_STACK; }
@ -409,7 +409,7 @@ fndef:
save_filename save_lineno compstmt_or_error
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
finish_function (0, 1);
POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator error
{ POP_DECLSPEC_STACK; }
@ -423,7 +423,7 @@ fndef:
save_filename save_lineno compstmt_or_error
{ DECL_SOURCE_FILE (current_function_decl) = $6;
DECL_SOURCE_LINE (current_function_decl) = $7;
finish_function (0);
finish_function (0, 1);
POP_DECLSPEC_STACK; }
| setspecs notype_declarator error
{ POP_DECLSPEC_STACK; }
@ -1582,7 +1582,7 @@ nested_function:
{ tree decl = current_function_decl;
DECL_SOURCE_FILE (decl) = $5;
DECL_SOURCE_LINE (decl) = $6;
finish_function (1);
finish_function (1, 1);
pop_function_context ();
add_decl_stmt (decl); }
;
@ -1612,7 +1612,7 @@ notype_nested_function:
{ tree decl = current_function_decl;
DECL_SOURCE_FILE (decl) = $5;
DECL_SOURCE_LINE (decl) = $6;
finish_function (1);
finish_function (1, 1);
pop_function_context ();
add_decl_stmt (decl); }
;
@ -2067,6 +2067,7 @@ end ifobjc
poplevel: /* empty */
{ $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
;
/* Start and end blocks created for the new scopes of C99. */
c99_block_start: /* empty */
@ -2137,7 +2138,8 @@ compstmt_or_error:
;
compstmt_start: '{' { compstmt_count++;
$$ = c_begin_compound_stmt (); }
$$ = c_begin_compound_stmt (); }
;
compstmt_nostart: '}'
{ $$ = convert (void_type_node, integer_zero_node); }
@ -2169,9 +2171,11 @@ compstmt_primary_start:
compstmt_count++;
$$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree));
}
;
compstmt: compstmt_start compstmt_nostart
{ RECHAIN_STMTS ($1, COMPOUND_BODY ($1));
last_expr_type = NULL_TREE;
$$ = $1; }
;

View File

@ -1,5 +1,5 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GCC.
@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "ggc.h"
#include "c-lex.h"
#include "c-common.h"
#include "output.h"
#include "tm_p.h"
@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL;
maximum_field_alignment in effect. When the final pop_alignment()
happens, we restore the value to this, not to a value of 0 for
maximum_field_alignment. Value is in bits. */
static int default_alignment;
static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
(default_alignment = maximum_field_alignment = (ALIGN))
(default_alignment = maximum_field_alignment = (ALIGN))
static void push_alignment PARAMS ((int, tree));
static void pop_alignment PARAMS ((tree));
@ -69,7 +70,6 @@ push_alignment (alignment, id)
int alignment;
tree id;
{
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
|| id != NULL_TREE)
@ -274,14 +274,57 @@ handle_pragma_pack (dummy)
#endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_WEAK
static void apply_pragma_weak PARAMS ((tree, tree));
static void handle_pragma_weak PARAMS ((cpp_reader *));
static tree pending_weaks;
static void
apply_pragma_weak (decl, value)
tree decl, value;
{
if (value)
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
build_tree_list (NULL, value)),
0);
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
declare_weak (decl);
}
void
maybe_apply_pragma_weak (decl)
tree decl;
{
tree *p, t, id;
/* Copied from the check in set_decl_assembler_name. */
if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl)
|| DECL_EXTERNAL (decl)
|| TREE_PUBLIC (decl))))
id = DECL_ASSEMBLER_NAME (decl);
else
return;
for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
if (id == TREE_PURPOSE (t))
{
apply_pragma_weak (decl, TREE_VALUE (t));
*p = TREE_CHAIN (t);
break;
}
}
/* #pragma weak name [= value] */
static void
handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree name, value, x;
tree name, value, x, decl;
enum cpp_ttype t;
value = 0;
@ -298,10 +341,149 @@ handle_pragma_weak (dummy)
if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0);
decl = identifier_global_value (name);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
apply_pragma_weak (decl, value);
else
pending_weaks = tree_cons (name, value, pending_weaks);
}
#else
void
maybe_apply_pragma_weak (decl)
tree decl ATTRIBUTE_UNUSED;
{
}
#endif /* HANDLE_PRAGMA_WEAK */
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
static tree pending_redefine_extname;
/* #pragma redefined_extname oldname newname */
static void
handle_pragma_redefine_extname (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree oldname, newname, decl, x;
enum cpp_ttype t;
if (c_lex (&oldname) != CPP_NAME)
{
warning ("malformed #pragma redefine_extname, ignored");
return;
}
if (c_lex (&newname) != CPP_NAME)
{
warning ("malformed #pragma redefine_extname, ignored");
return;
}
t = c_lex (&x);
if (t != CPP_EOF)
warning ("junk at end of #pragma redefine_extname");
decl = identifier_global_value (oldname);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
{
if (DECL_ASSEMBLER_NAME_SET_P (decl)
&& DECL_ASSEMBLER_NAME (decl) != newname)
warning ("#pragma redefine_extname conflicts with declaration");
SET_DECL_ASSEMBLER_NAME (decl, newname);
}
else
pending_redefine_extname
= tree_cons (oldname, newname, pending_redefine_extname);
}
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
static tree pragma_extern_prefix;
/* #pragma extern_prefix "prefix" */
static void
handle_pragma_extern_prefix (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree prefix, x;
enum cpp_ttype t;
if (c_lex (&prefix) != CPP_STRING)
{
warning ("malformed #pragma extern_prefix, ignored");
return;
}
t = c_lex (&x);
if (t != CPP_EOF)
warning ("junk at end of #pragma extern_prefix");
/* Note that the length includes the null terminator. */
pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
}
#endif
/* Hook from the front ends to apply the results of one of the preceeding
pragmas that rename variables. */
tree
maybe_apply_renaming_pragma (decl, asmname)
tree decl, asmname;
{
tree oldname;
/* Copied from the check in set_decl_assembler_name. */
if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl)
|| DECL_EXTERNAL (decl)
|| TREE_PUBLIC (decl))))
oldname = DECL_ASSEMBLER_NAME (decl);
else
return asmname;
/* If the name begins with a *, that's a sign of an asmname attached to
a previous declaration. */
if (IDENTIFIER_POINTER (oldname)[0] == '*')
{
const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
warning ("asm declaration conficts with previous rename");
asmname = build_string (strlen (oldasmname), oldasmname);
}
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
{
tree *p, t;
for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
if (oldname == TREE_PURPOSE (t))
{
const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
warning ("#pragma redefine_extname conflicts with declaration");
*p = TREE_CHAIN (t);
return build_string (strlen (newname), newname);
}
}
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
if (pragma_extern_prefix && !asmname)
{
char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
IDENTIFIER_POINTER (oldname), NULL);
asmname = build_string (strlen (x), x);
free (x);
return asmname;
}
#endif
return asmname;
}
void
init_pragma ()
{
@ -310,7 +492,19 @@ init_pragma ()
#endif
#ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
ggc_add_tree_root (&pending_weaks, 1);
#endif
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
cpp_register_pragma (parse_in, 0, "redefine_extname",
handle_pragma_redefine_extname);
ggc_add_tree_root (&pending_redefine_extname, 1);
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
cpp_register_pragma (parse_in, 0, "extern_prefix",
handle_pragma_extern_prefix);
ggc_add_tree_root (&pragma_extern_prefix, 1);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);
#endif

View File

@ -23,9 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define GCC_C_PRAGMA_H
#ifdef HANDLE_SYSV_PRAGMA
/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_WEAK_ALIAS are
defined. */
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)
#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
|| defined (ASM_WEAKEN_DECL))
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
#endif
@ -54,4 +53,7 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *,
void (*) PARAMS ((cpp_reader *))));
#endif
extern void maybe_apply_pragma_weak PARAMS ((tree));
extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
#endif /* GCC_C_PRAGMA_H */

View File

@ -644,7 +644,7 @@ genrtl_switch_stmt (t)
emit_line_note (input_filename, lineno);
expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
expand_stmt (SWITCH_BODY (t));
expand_end_case (cond);
expand_end_case_type (cond, SWITCH_TYPE (t));
}
/* Create a CASE_LABEL tree node and return it. */
@ -737,12 +737,12 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
/* Generate the RTL for a DECL_CLEANUP. */
void
genrtl_decl_cleanup (decl, cleanup)
tree decl;
tree cleanup;
genrtl_decl_cleanup (t)
tree t;
{
tree decl = CLEANUP_DECL (t);
if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
expand_decl_cleanup (decl, cleanup);
expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
}
/* We're about to expand T, a statement. Set up appropriate context
@ -847,6 +847,10 @@ expand_stmt (t)
genrtl_scope_stmt (t);
break;
case CLEANUP_STMT:
genrtl_decl_cleanup (t);
break;
default:
if (lang_expand_stmt)
(*lang_expand_stmt) (t);

View File

@ -132,6 +132,10 @@ struct lang_type
/* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
/* For a FUNCTION_DECL, nonzero if it was defined without an explicit
return type. */
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
/* Nonzero for a declaration of a built in function if there has been no
occasion that would declare the function in ordinary C.
Using the function draws a pedantic warning in this case. */
@ -177,7 +181,7 @@ extern tree define_label PARAMS ((const char *, int,
tree));
extern void finish_decl PARAMS ((tree, tree, tree));
extern tree finish_enum PARAMS ((tree, tree, tree));
extern void finish_function PARAMS ((int));
extern void finish_function PARAMS ((int, int));
extern tree finish_struct PARAMS ((tree, tree, tree));
extern tree get_parm_info PARAMS ((int));
extern tree grokfield PARAMS ((const char *, int, tree, tree, tree));
@ -266,6 +270,7 @@ extern void c_finish_case PARAMS ((void));
extern tree simple_asm_stmt PARAMS ((tree));
extern tree build_asm_stmt PARAMS ((tree, tree, tree,
tree, tree));
extern tree c_convert_parm_for_inlining PARAMS ((tree, tree, tree));
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
@ -277,6 +282,11 @@ extern int current_function_returns_value;
extern int current_function_returns_null;
/* Set to 0 at beginning of a function definition, set to 1 if
a call to a noreturn function is seen. */
extern int current_function_returns_abnormally;
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */

View File

@ -58,7 +58,6 @@ static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
static tree default_function_array_conversion PARAMS ((tree));
static tree lookup_field PARAMS ((tree, tree));
static tree convert_arguments PARAMS ((tree, tree, tree, tree));
static tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
static tree pointer_diff PARAMS ((tree, tree));
static tree unary_complex_lvalue PARAMS ((enum tree_code, tree, int));
static void pedantic_lvalue_warning PARAMS ((enum tree_code));
@ -149,6 +148,11 @@ incomplete_type_error (value, type)
case ARRAY_TYPE:
if (TYPE_DOMAIN (type))
{
if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
{
error ("invalid use of flexible array member");
return;
}
type = TREE_TYPE (type);
goto retry;
}
@ -1547,6 +1551,9 @@ build_function_call (function, params)
return error_mark_node;
}
if (fundecl && TREE_THIS_VOLATILE (fundecl))
current_function_returns_abnormally = 1;
/* fntype now gets the type of function pointed to. */
fntype = TREE_TYPE (fntype);
@ -2052,29 +2059,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case BIT_XOR_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
shorten = -1;
/* If one operand is a constant, and the other is a short type
that has been converted to an int,
really do the work in the short type and then convert the
result to int. If we are lucky, the constant will be 0 or 1
in the short type, making the entire operation go away. */
if (TREE_CODE (op0) == INTEGER_CST
&& TREE_CODE (op1) == NOP_EXPR
&& TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
{
final_type = result_type;
op1 = TREE_OPERAND (op1, 0);
result_type = TREE_TYPE (op1);
}
if (TREE_CODE (op1) == INTEGER_CST
&& TREE_CODE (op0) == NOP_EXPR
&& TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
{
final_type = result_type;
op0 = TREE_OPERAND (op0, 0);
result_type = TREE_TYPE (op0);
}
break;
case TRUNC_MOD_EXPR:
@ -2652,95 +2636,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
}
/* Return a tree for the sum or difference (RESULTCODE says which)
of pointer PTROP and integer INTOP. */
static tree
pointer_int_sum (resultcode, ptrop, intop)
enum tree_code resultcode;
tree ptrop, intop;
{
tree size_exp;
tree result;
tree folded;
/* The result is a pointer of the same type that is being added. */
tree result_type = TREE_TYPE (ptrop);
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer of type `void *' used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("pointer to a function used in arithmetic");
size_exp = integer_one_node;
}
else
size_exp = c_size_in_bytes (TREE_TYPE (result_type));
/* If what we are about to multiply by the size of the elements
contains a constant term, apply distributive law
and multiply that constant term separately.
This helps produce common subexpressions. */
if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
&& ! TREE_CONSTANT (intop)
&& TREE_CONSTANT (TREE_OPERAND (intop, 1))
&& TREE_CONSTANT (size_exp)
/* If the constant comes from pointer subtraction,
skip this optimization--it would cause an error. */
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
/* If the constant is unsigned, and smaller than the pointer size,
then we must skip this optimization. This is because it could cause
an overflow error if the constant is negative but INTOP is not. */
&& (! TREE_UNSIGNED (TREE_TYPE (intop))
|| (TYPE_PRECISION (TREE_TYPE (intop))
== TYPE_PRECISION (TREE_TYPE (ptrop)))))
{
enum tree_code subcode = resultcode;
tree int_type = TREE_TYPE (intop);
if (TREE_CODE (intop) == MINUS_EXPR)
subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
/* Convert both subexpression types to the type of intop,
because weird cases involving pointer arithmetic
can result in a sum or difference with different type args. */
ptrop = build_binary_op (subcode, ptrop,
convert (int_type, TREE_OPERAND (intop, 1)), 1);
intop = convert (int_type, TREE_OPERAND (intop, 0));
}
/* Convert the integer argument to a type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|| TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
intop = convert (type_for_size (TYPE_PRECISION (sizetype),
TREE_UNSIGNED (sizetype)), intop);
/* Replace the integer argument with a suitable product by the object size.
Do this multiplication as signed, then convert to the appropriate
pointer type (actually unsigned integral). */
intop = convert (result_type,
build_binary_op (MULT_EXPR, intop,
convert (TREE_TYPE (intop), size_exp), 1));
/* Create the sum or difference. */
result = build (resultcode, result_type, ptrop, intop);
folded = fold (result);
if (folded == result)
TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
return folded;
}
/* Return a tree for the difference of pointers OP0 and OP1.
The resulting tree has type int. */
@ -3819,7 +3714,8 @@ build_c_cast (type, expr)
{
tree in_type = type;
tree in_otype = otype;
int warn = 0;
int added = 0;
int discarded = 0;
/* Check that the qualifiers on IN_TYPE are a superset of
the qualifiers of IN_OTYPE. The outermost level of
@ -3829,12 +3725,24 @@ build_c_cast (type, expr)
{
in_otype = TREE_TYPE (in_otype);
in_type = TREE_TYPE (in_type);
warn |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
/* GNU C allows cv-qualified function types. 'const'
means the function is very pure, 'volatile' means it
can't return. We need to warn when such qualifiers
are added, not when they're taken away. */
if (TREE_CODE (in_otype) == FUNCTION_TYPE
&& TREE_CODE (in_type) == FUNCTION_TYPE)
added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
else
discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
}
while (TREE_CODE (in_type) == POINTER_TYPE
&& TREE_CODE (in_otype) == POINTER_TYPE);
if (warn)
if (added)
warning ("cast adds new qualifiers to function type");
if (discarded)
/* There are qualifiers present in IN_OTYPE that are not
present in IN_TYPE. */
warning ("cast discards qualifiers from pointer target type");
@ -4372,6 +4280,30 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
return error_mark_node;
}
/* Convert VALUE for assignment into inlined parameter PARM. */
tree
c_convert_parm_for_inlining (parm, value, fn)
tree parm, value, fn;
{
tree ret, type;
/* If FN was prototyped, the value has been converted already
in convert_arguments. */
if (! value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
return value;
type = TREE_TYPE (parm);
ret = convert_for_assignment (type, value,
(char *) 0 /* arg passing */, fn,
DECL_NAME (fn), 0);
if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
ret = default_conversion (ret);
return ret;
}
/* Print a warning using MSGID.
It gets OPNAME as its one parameter.
If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
@ -4809,6 +4741,8 @@ digest_init (type, init, require_constant, constructor_constant)
TYPE_MAIN_VARIANT (type))
|| (code == ARRAY_TYPE
&& comptypes (TREE_TYPE (inside_init), type))
|| (code == VECTOR_TYPE
&& comptypes (TREE_TYPE (inside_init), type))
|| (code == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
@ -5320,6 +5254,14 @@ really_start_incremental_init (type)
constructor_unfilled_index = constructor_index;
}
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
{
/* Vectors are like simple fixed-size arrays. */
constructor_max_index =
build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
constructor_index = convert (bitsizetype, integer_zero_node);
constructor_unfilled_index = constructor_index;
}
else
{
/* Handle the case of int x = {5}; */
@ -5466,6 +5408,14 @@ push_init_level (implicit)
constructor_unfilled_fields = constructor_fields;
constructor_bit_index = bitsize_zero_node;
}
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
{
/* Vectors are like simple fixed-size arrays. */
constructor_max_index =
build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
constructor_index = convert (bitsizetype, integer_zero_node);
constructor_unfilled_index = constructor_index;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
if (TYPE_DOMAIN (constructor_type))
@ -5602,7 +5552,8 @@ pop_init_level (implicit)
;
else if (TREE_CODE (constructor_type) != RECORD_TYPE
&& TREE_CODE (constructor_type) != UNION_TYPE
&& TREE_CODE (constructor_type) != ARRAY_TYPE)
&& TREE_CODE (constructor_type) != ARRAY_TYPE
&& TREE_CODE (constructor_type) != VECTOR_TYPE)
{
/* A nonincremental scalar initializer--just return
the element, after verifying there is just one. */
@ -6648,6 +6599,16 @@ process_init_element (value)
fieldtype = TYPE_MAIN_VARIANT (fieldtype);
fieldcode = TREE_CODE (fieldtype);
/* Error for non-static initialization of a flexible array member. */
if (fieldcode == ARRAY_TYPE
&& !require_constant_value
&& TYPE_SIZE (fieldtype) == NULL_TREE
&& TREE_CHAIN (constructor_fields) == NULL_TREE)
{
error_init ("non-static initialization of a flexible array member");
break;
}
/* Accept a string constant to initialize a subarray. */
if (value != 0
&& fieldcode == ARRAY_TYPE
@ -6811,6 +6772,31 @@ process_init_element (value)
constructor_unfilled_index. */
constructor_unfilled_index = constructor_index;
}
else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
{
tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
/* Do a basic check of initializer size. Note that vectors
always have a fixed size derived from their type. */
if (tree_int_cst_lt (constructor_max_index, constructor_index))
{
pedwarn_init ("excess elements in vector initializer");
break;
}
/* Now output the actual element. */
if (value)
output_init_element (value, elttype, constructor_index, 1);
constructor_index
= size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
if (! value)
/* If we are doing the bookkeeping for an element that was
directly output as a constructor, we must update
constructor_unfilled_index. */
constructor_unfilled_index = constructor_index;
}
/* Handle the sole element allowed in a braced initializer
for a scalar variable. */
@ -7071,6 +7057,7 @@ c_expand_return (retval)
tree res = DECL_RESULT (current_function_decl);
tree inner;
current_function_returns_value = 1;
if (t == error_mark_node)
return NULL_TREE;
@ -7128,7 +7115,6 @@ c_expand_return (retval)
}
retval = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
current_function_returns_value = 1;
}
return add_stmt (build_return_stmt (retval));
@ -7163,15 +7149,15 @@ c_start_case (exp)
tree exp;
{
enum tree_code code;
tree type;
tree type, orig_type = error_mark_node;
struct c_switch *cs;
if (exp != error_mark_node)
{
code = TREE_CODE (TREE_TYPE (exp));
type = TREE_TYPE (exp);
orig_type = TREE_TYPE (exp);
if (! INTEGRAL_TYPE_P (type)
if (! INTEGRAL_TYPE_P (orig_type)
&& code != ERROR_MARK)
{
error ("switch quantity not an integer");
@ -7193,7 +7179,7 @@ c_start_case (exp)
/* Add this new SWITCH_STMT to the stack. */
cs = (struct c_switch *) xmalloc (sizeof (*cs));
cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, NULL_TREE);
cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type);
cs->cases = splay_tree_new (case_compare, NULL, NULL);
cs->next = switch_stack;
switch_stack = cs;

View File

@ -181,7 +181,8 @@ static int calls_function_1 PARAMS ((tree, int));
static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
HOST_WIDE_INT, HOST_WIDE_INT, rtx,
rtx, int, rtx, int));
rtx, int, rtx, int,
CUMULATIVE_ARGS *));
static void precompute_register_parameters PARAMS ((int,
struct arg_data *,
int *));
@ -444,7 +445,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
static void
emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
call_fusage, ecf_flags)
call_fusage, ecf_flags, args_so_far)
rtx funexp;
tree fndecl ATTRIBUTE_UNUSED;
tree funtype ATTRIBUTE_UNUSED;
@ -456,6 +457,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
int old_inhibit_defer_pop;
rtx call_fusage;
int ecf_flags;
CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED;
{
rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
rtx call_insn;
@ -466,6 +468,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
struct_value_size_rtx = GEN_INT (struct_value_size);
#endif
#ifdef CALL_POPS_ARGS
n_popped += CALL_POPS_ARGS (* args_so_far);
#endif
/* Ensure address is valid. SYMBOL_REF is already valid, so no need,
and we don't want to load it into a register as an optimization,
because prepare_call_address already did it if it should be done. */
@ -1505,14 +1511,9 @@ precompute_arguments (flags, num_actuals, args)
if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
abort ();
push_temp_slots ();
args[i].value
= expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
preserve_temp_slots (args[i].value);
pop_temp_slots ();
/* ANSI doesn't require a sequence point here,
but PCC has one, so this will avoid some problems. */
emit_queue ();
@ -2675,10 +2676,6 @@ expand_call (exp, target, ignore)
if (pass && (flags & ECF_LIBCALL_BLOCK))
NO_DEFER_POP;
/* Push the temporary stack slot level so that we can free any
temporaries we make. */
push_temp_slots ();
#ifdef FINAL_REG_PARM_STACK_SPACE
reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
args_size.var);
@ -3055,7 +3052,7 @@ expand_call (exp, target, ignore)
emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
adjusted_args_size.constant, struct_value_size,
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags);
flags, & args_so_far);
/* Verify that we've deallocated all the stack we used. */
if (pass
@ -3328,8 +3325,6 @@ expand_call (exp, target, ignore)
if ((flags & ECF_MAY_BE_ALLOCA) && nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
pop_temp_slots ();
/* Free up storage we no longer need. */
for (i = 0; i < num_actuals; ++i)
if (args[i].aligned_regs)
@ -4053,7 +4048,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
struct_value_size,
FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
valreg,
old_inhibit_defer_pop + 1, call_fusage, flags);
old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
/* For calls to `setjmp', etc., inform flow.c it should complain
if nonvolatile values are live. For functions that cannot return,
@ -4361,7 +4356,13 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
/* If this isn't going to be placed on both the stack and in registers,
set up the register and number of words. */
if (! arg->pass_on_stack)
reg = arg->reg, partial = arg->partial;
{
if (flags & ECF_SIBCALL)
reg = arg->tail_call_reg;
else
reg = arg->reg;
partial = arg->partial;
}
if (reg != 0 && partial == 0)
/* Being passed entirely in a register. We shouldn't be called in
@ -4459,6 +4460,11 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
partial, reg, used - size, argblock,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack. */
if (partial == 0)
arg->value = arg->stack;
}
else
{
@ -4558,17 +4564,19 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
argblock, ARGS_SIZE_RTX (arg->offset),
reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack.
??? Unlike the case above, in which we want the actual
address of the data, so that we can load it directly into a
register, here we want the address of the stack slot, so that
it's properly aligned for word-by-word copying or something
like that. It's not clear that this is always correct. */
if (partial == 0)
arg->value = arg->stack_slot;
}
/* Unless this is a partially-in-register argument, the argument is now
in the stack.
??? Note that this can change arg->value from arg->stack to
arg->stack_slot and it matters when they are not the same.
It isn't totally clear that this is correct in all cases. */
if (partial == 0)
arg->value = arg->stack_slot;
/* Once we have pushed something, pops can't safely
be deferred during the rest of the arguments. */
NO_DEFER_POP;

View File

@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@ -221,6 +221,17 @@ alloc_block ()
/* Remove block B from the basic block array and compact behind it. */
void
expunge_block_nocompact (b)
basic_block b;
{
/* Invalidate data to make bughunting easier. */
memset (b, 0, sizeof *b);
b->index = -3;
b->succ = (edge) first_deleted_block;
first_deleted_block = (basic_block) b;
}
void
expunge_block (b)
basic_block b;
@ -234,13 +245,10 @@ expunge_block (b)
x->index = i;
}
/* Invalidate data to make bughunting easier. */
memset (b, 0, sizeof *b);
b->index = -3;
basic_block_info->num_elements--;
n_basic_blocks--;
b->succ = (edge) first_deleted_block;
first_deleted_block = (basic_block) b;
basic_block_info->num_elements--;
expunge_block_nocompact (b);
}
/* Create an edge connecting SRC and DST with FLAGS optionally using

View File

@ -25,9 +25,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
#include "recog.h"
#include "toplev.h"
#include "obstack.h"
#include "tm_p.h"
/* Store the data structures necessary for depth-first search. */
struct depth_first_search_dsS {
@ -53,6 +55,7 @@ static void flow_dfs_compute_reverse_finish
PARAMS ((depth_first_search_ds));
static void remove_fake_successors PARAMS ((basic_block));
static bool need_fake_edge_p PARAMS ((rtx));
static bool keep_with_call_p PARAMS ((rtx));
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
@ -209,6 +212,32 @@ need_fake_edge_p (insn)
|| GET_CODE (PATTERN (insn)) == ASM_INPUT);
}
/* Return true if INSN should be kept in the same block as a preceding call.
This is done for a single-set whose destination is a fixed register or
whose source is the function return value. This is a helper function for
flow_call_edges_add. */
static bool
keep_with_call_p (insn)
rtx insn;
{
rtx set;
if (INSN_P (insn) && (set = single_set (insn)) != NULL)
{
if (GET_CODE (SET_DEST (set)) == REG
&& fixed_regs[REGNO (SET_DEST (set))]
&& general_operand (SET_SRC (set), VOIDmode))
return true;
if (GET_CODE (SET_SRC (set)) == REG
&& FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
&& GET_CODE (SET_DEST (set)) == REG
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
return true;
}
return false;
}
/* Add fake edges to the function exit for any non constant and non noreturn
calls, volatile inline assembly in the bitmap of blocks specified by
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
@ -259,17 +288,27 @@ flow_call_edges_add (blocks)
spanning tree in the case that the call doesn't return.
Handle this by adding a dummy instruction in a new last basic block. */
if (check_last_block
&& need_fake_edge_p (BASIC_BLOCK (n_basic_blocks - 1)->end))
if (check_last_block)
{
edge e;
basic_block bb = BASIC_BLOCK (n_basic_blocks - 1);
rtx insn = bb->end;
for (e = BASIC_BLOCK (n_basic_blocks - 1)->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
break;
/* Back up past insns that must be kept in the same block as a call. */
while (insn != bb->head
&& keep_with_call_p (insn))
insn = PREV_INSN (insn);
insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
commit_edge_insertions ();
if (need_fake_edge_p (insn))
{
edge e;
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
break;
insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
commit_edge_insertions ();
}
}
/* Now add fake edges to the function exit for any non constant
@ -288,14 +327,22 @@ flow_call_edges_add (blocks)
if (need_fake_edge_p (insn))
{
edge e;
rtx split_at_insn = insn;
/* The above condition should be enough to verify that there is
no edge to the exit block in CFG already. Calling make_edge
in such case would make us to mark that edge as fake and
remove it later. */
/* Don't split the block between a call and an insn that should
remain in the same block as the call. */
if (GET_CODE (insn) == CALL_INSN)
while (split_at_insn != bb->end
&& keep_with_call_p (NEXT_INSN (split_at_insn)))
split_at_insn = NEXT_INSN (split_at_insn);
/* The handling above of the final block before the epilogue
should be enough to verify that there is no edge to the exit
block in CFG already. Calling make_edge in such case would
cause us to mark that edge as fake and remove it later. */
#ifdef ENABLE_CHECKING
if (insn == bb->end)
if (split_at_insn == bb->end)
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
abort ();
@ -303,7 +350,7 @@ flow_call_edges_add (blocks)
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
e = split_block (bb, insn);
e = split_block (bb, split_at_insn);
if (e)
blocks_split++;

View File

@ -1,6 +1,6 @@
/* Control flow optimization code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "cselib.h"
#include "tm_p.h"
#include "target.h"
#include "obstack.h"
@ -1096,9 +1097,20 @@ outgoing_edges_match (mode, bb1, bb2)
if (!bb2->succ
|| !bb2->succ->succ_next
|| bb1->succ->succ_next->succ_next
|| bb2->succ->succ_next->succ_next
|| !any_condjump_p (bb2->end)
|| !onlyjump_p (bb1->end))
|| !onlyjump_p (bb2->end))
return false;
/* Do not crossjump across loop boundaries. This is a temporary
workaround for the common scenario in which crossjumping results
in killing the duplicated loop condition, making bb-reorder rotate
the loop incorectly, leaving an extra unconditional jump inside
the loop.
This check should go away once bb-reorder knows how to duplicate
code in this case or rotate the loops to avoid this scenario. */
if (bb1->loop_depth != bb2->loop_depth)
return false;
b1 = BRANCH_EDGE (bb1);
@ -1174,9 +1186,10 @@ outgoing_edges_match (mode, bb1, bb2)
/* Do not use f2 probability as f2 may be forwarded. */
prob2 = REG_BR_PROB_BASE - b2->probability;
/* Fail if the difference in probabilities is
greater than 5%. */
if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 20)
/* Fail if the difference in probabilities is greater than 50%.
This rules out two well-predicted branches with opposite
outcomes. */
if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2)
{
if (rtl_dump_file)
fprintf (rtl_dump_file,
@ -1277,12 +1290,10 @@ try_crossjump_to_edge (mode, e1, e2)
away. We do this to look past the unconditional jump following a
conditional jump that is required due to the current CFG shape. */
if (src1->pred
&& !src1->pred->pred_next
&& FORWARDER_BLOCK_P (src1))
e1 = src1->pred, src1 = e1->src;
if (src2->pred
&& !src2->pred->pred_next
&& FORWARDER_BLOCK_P (src2))
e2 = src2->pred, src2 = e2->src;
@ -1531,149 +1542,158 @@ try_optimize_cfg (mode)
for (i = 0; i < n_basic_blocks; i++)
update_forwarder_flag (BASIC_BLOCK (i));
/* Attempt to merge blocks as made possible by edge removal. If a block
has only one successor, and the successor has only one predecessor,
they may be combined. */
do
if (! (* targetm.cannot_modify_jumps_p) ())
{
changed = false;
iterations++;
if (rtl_dump_file)
fprintf (rtl_dump_file, "\n\ntry_optimize_cfg iteration %i\n\n",
iterations);
for (i = 0; i < n_basic_blocks;)
/* Attempt to merge blocks as made possible by edge removal. If
a block has only one successor, and the successor has only
one predecessor, they may be combined. */
do
{
basic_block c, b = BASIC_BLOCK (i);
edge s;
bool changed_here = false;
changed = false;
iterations++;
/* Delete trivially dead basic blocks. */
while (b->pred == NULL)
if (rtl_dump_file)
fprintf (rtl_dump_file,
"\n\ntry_optimize_cfg iteration %i\n\n",
iterations);
for (i = 0; i < n_basic_blocks;)
{
c = BASIC_BLOCK (b->index - 1);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleting block %i.\n", b->index);
basic_block c, b = BASIC_BLOCK (i);
edge s;
bool changed_here = false;
flow_delete_block (b);
changed = true;
b = c;
/* Delete trivially dead basic blocks. */
while (b->pred == NULL)
{
c = BASIC_BLOCK (b->index - 1);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleting block %i.\n",
b->index);
flow_delete_block (b);
changed = true;
b = c;
}
/* Remove code labels no longer used. Don't do this
before CALL_PLACEHOLDER is removed, as some branches
may be hidden within. */
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& !(b->pred->flags & EDGE_COMPLEX)
&& GET_CODE (b->head) == CODE_LABEL
&& (!(mode & CLEANUP_PRE_SIBCALL)
|| !tail_recursion_label_p (b->head))
/* If the previous block ends with a branch to this
block, we can't delete the label. Normally this
is a condjump that is yet to be simplified, but
if CASE_DROPS_THRU, this can be a tablejump with
some element going to the same place as the
default (fallthru). */
&& (b->pred->src == ENTRY_BLOCK_PTR
|| GET_CODE (b->pred->src->end) != JUMP_INSN
|| ! label_is_jump_target_p (b->head,
b->pred->src->end)))
{
rtx label = b->head;
b->head = NEXT_INSN (b->head);
delete_insn_chain (label, label);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
}
/* If we fall through an empty block, we can remove it. */
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
/* Note that forwarder_block_p true ensures that
there is a successor for this block. */
&& (b->succ->flags & EDGE_FALLTHRU)
&& n_basic_blocks > 1)
{
if (rtl_dump_file)
fprintf (rtl_dump_file,
"Deleting fallthru block %i.\n",
b->index);
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
redirect_edge_succ_nodup (b->pred, b->succ->dest);
flow_delete_block (b);
changed = true;
b = c;
}
/* Merge blocks. Loop because chains of blocks might be
combineable. */
while ((s = b->succ) != NULL
&& s->succ_next == NULL
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
/* If the jump insn has side effects,
we can't kill the edge. */
&& (GET_CODE (b->end) != JUMP_INSN
|| onlyjump_p (b->end))
&& merge_blocks (s, b, c, mode))
changed_here = true;
/* Simplify branch over branch. */
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
{
BB_SET_FLAG (b, BB_UPDATE_LIFE);
changed_here = true;
}
/* If B has a single outgoing edge, but uses a
non-trivial jump instruction without side-effects, we
can either delete the jump entirely, or replace it
with a simple unconditional jump. Use
redirect_edge_and_branch to do the dirty work. */
if (b->succ
&& ! b->succ->succ_next
&& b->succ->dest != EXIT_BLOCK_PTR
&& onlyjump_p (b->end)
&& redirect_edge_and_branch (b->succ, b->succ->dest))
{
BB_SET_FLAG (b, BB_UPDATE_LIFE);
update_forwarder_flag (b);
changed_here = true;
}
/* Simplify branch to branch. */
if (try_forward_edges (mode, b))
changed_here = true;
/* Look for shared code between blocks. */
if ((mode & CLEANUP_CROSSJUMP)
&& try_crossjump_bb (mode, b))
changed_here = true;
/* Don't get confused by the index shift caused by
deleting blocks. */
if (!changed_here)
i = b->index + 1;
else
changed = true;
}
/* Remove code labels no longer used. Don't do this before
CALL_PLACEHOLDER is removed, as some branches may be hidden
within. */
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& !(b->pred->flags & EDGE_COMPLEX)
&& GET_CODE (b->head) == CODE_LABEL
&& (!(mode & CLEANUP_PRE_SIBCALL)
|| !tail_recursion_label_p (b->head))
/* If the previous block ends with a branch to this block,
we can't delete the label. Normally this is a condjump
that is yet to be simplified, but if CASE_DROPS_THRU,
this can be a tablejump with some element going to the
same place as the default (fallthru). */
&& (b->pred->src == ENTRY_BLOCK_PTR
|| GET_CODE (b->pred->src->end) != JUMP_INSN
|| ! label_is_jump_target_p (b->head, b->pred->src->end)))
{
rtx label = b->head;
b->head = NEXT_INSN (b->head);
delete_insn_chain (label, label);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
}
/* If we fall through an empty block, we can remove it. */
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
/* Note that forwarder_block_p true ensures that there
is a successor for this block. */
&& (b->succ->flags & EDGE_FALLTHRU)
&& n_basic_blocks > 1)
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
b->index);
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
redirect_edge_succ_nodup (b->pred, b->succ->dest);
flow_delete_block (b);
changed = true;
b = c;
}
/* Merge blocks. Loop because chains of blocks might be
combineable. */
while ((s = b->succ) != NULL
&& s->succ_next == NULL
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
/* If the jump insn has side effects,
we can't kill the edge. */
&& (GET_CODE (b->end) != JUMP_INSN
|| onlyjump_p (b->end))
&& merge_blocks (s, b, c, mode))
changed_here = true;
/* Simplify branch over branch. */
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
{
BB_SET_FLAG (b, BB_UPDATE_LIFE);
changed_here = true;
}
/* If B has a single outgoing edge, but uses a non-trivial jump
instruction without side-effects, we can either delete the
jump entirely, or replace it with a simple unconditional jump.
Use redirect_edge_and_branch to do the dirty work. */
if (b->succ
&& ! b->succ->succ_next
&& b->succ->dest != EXIT_BLOCK_PTR
&& onlyjump_p (b->end)
&& redirect_edge_and_branch (b->succ, b->succ->dest))
{
BB_SET_FLAG (b, BB_UPDATE_LIFE);
update_forwarder_flag (b);
changed_here = true;
}
/* Simplify branch to branch. */
if (try_forward_edges (mode, b))
changed_here = true;
/* Look for shared code between blocks. */
if ((mode & CLEANUP_CROSSJUMP)
&& try_crossjump_bb (mode, b))
changed_here = true;
/* Don't get confused by the index shift caused by deleting
blocks. */
if (!changed_here)
i = b->index + 1;
else
&& try_crossjump_bb (mode, EXIT_BLOCK_PTR))
changed = true;
}
if ((mode & CLEANUP_CROSSJUMP)
&& try_crossjump_bb (mode, EXIT_BLOCK_PTR))
changed = true;
#ifdef ENABLE_CHECKING
if (changed)
verify_flow_info ();
if (changed)
verify_flow_info ();
#endif
changed_overall |= changed;
changed_overall |= changed;
}
while (changed);
}
while (changed);
if (mode & CLEANUP_CROSSJUMP)
remove_fake_edges ();
@ -1709,22 +1729,33 @@ try_optimize_cfg (mode)
static bool
delete_unreachable_blocks ()
{
int i;
int i, j;
bool changed = false;
find_unreachable_blocks ();
/* Delete all unreachable basic blocks. Count down so that we
don't interfere with the block renumbering that happens in
flow_delete_block. */
/* Delete all unreachable basic blocks. Do compaction concurrently,
as otherwise we can wind up with O(N^2) behaviour here when we
have oodles of dead code. */
for (i = n_basic_blocks - 1; i >= 0; --i)
for (i = j = 0; i < n_basic_blocks; ++i)
{
basic_block b = BASIC_BLOCK (i);
if (!(b->flags & BB_REACHABLE))
flow_delete_block (b), changed = true;
{
flow_delete_block_noexpunge (b);
expunge_block_nocompact (b);
changed = true;
}
else
{
BASIC_BLOCK (j) = b;
b->index = j++;
}
}
n_basic_blocks = j;
basic_block_info->num_elements = j;
if (changed)
tidy_fallthru_edges ();

View File

@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@ -101,8 +101,7 @@ can_delete_label_p (label)
/* User declared labels must be preserved. */
&& LABEL_NAME (label) == 0
&& !in_expr_list_p (forced_labels, label)
&& !in_expr_list_p (label_value_list, label)
&& !in_expr_list_p (exception_handler_labels, label));
&& !in_expr_list_p (label_value_list, label));
}
/* Delete INSN by patching it out. Return the next insn. */
@ -323,7 +322,7 @@ create_basic_block (index, head, end)
to post-process the stream to remove empty blocks, loops, ranges, etc. */
int
flow_delete_block (b)
flow_delete_block_noexpunge (b)
basic_block b;
{
int deleted_handler = 0;
@ -338,7 +337,7 @@ flow_delete_block (b)
insn = b->head;
never_reached_warning (insn);
never_reached_warning (insn, b->end);
if (GET_CODE (insn) == CODE_LABEL)
maybe_remove_eh_handler (insn);
@ -372,6 +371,15 @@ flow_delete_block (b)
b->pred = NULL;
b->succ = NULL;
return deleted_handler;
}
int
flow_delete_block (b)
basic_block b;
{
int deleted_handler = flow_delete_block_noexpunge (b);
/* Remove the basic block from the array, and compact behind it. */
expunge_block (b);
@ -611,9 +619,9 @@ merge_blocks_nomove (a, b)
rtx x;
for (x = a_end; x != b_end; x = NEXT_INSN (x))
BLOCK_FOR_INSN (x) = a;
set_block_for_insn (x, a);
BLOCK_FOR_INSN (b_end) = a;
set_block_for_insn (b_end, a);
}
a_end = b_end;
@ -714,7 +722,7 @@ try_redirect_by_replacing_jump (e, target)
else
{
rtx target_label = block_label (target);
rtx barrier;
rtx barrier, tmp;
emit_jump_insn_after (gen_jump (target_label), insn);
JUMP_LABEL (src->end) = target_label;
@ -723,8 +731,21 @@ try_redirect_by_replacing_jump (e, target)
fprintf (rtl_dump_file, "Replacing insn %i by jump %i\n",
INSN_UID (insn), INSN_UID (src->end));
delete_insn_chain (kill_from, insn);
/* Recognize a tablejump that we are converting to a
simple jump and remove its associated CODE_LABEL
and ADDR_VEC or ADDR_DIFF_VEC. */
if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
&& (tmp = NEXT_INSN (tmp)) != NULL_RTX
&& GET_CODE (tmp) == JUMP_INSN
&& (GET_CODE (PATTERN (tmp)) == ADDR_VEC
|| GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
{
delete_insn_chain (JUMP_LABEL (insn), tmp);
}
barrier = next_nonnote_insn (src->end);
if (!barrier || GET_CODE (barrier) != BARRIER)
emit_barrier_after (src->end);
@ -905,7 +926,31 @@ force_nonfallthru_and_redirect (e, target)
abort ();
else if (!(e->flags & EDGE_FALLTHRU))
abort ();
else if (e->src->succ->succ_next)
else if (e->src == ENTRY_BLOCK_PTR)
{
/* We can't redirect the entry block. Create an empty block at the
start of the function which we use to add the new jump. */
edge *pe1;
basic_block bb = create_basic_block (0, e->dest->head, NULL);
/* Change the existing edge's source to be the new block, and add
a new edge from the entry block to the new block. */
e->src = bb;
bb->count = e->count;
bb->frequency = EDGE_FREQUENCY (e);
bb->loop_depth = 0;
for (pe1 = &ENTRY_BLOCK_PTR->succ; *pe1; pe1 = &(*pe1)->succ_next)
if (*pe1 == e)
{
*pe1 = e->succ_next;
break;
}
e->succ_next = 0;
bb->succ = e;
make_single_succ_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
}
if (e->src->succ->succ_next)
{
/* Create the new structures. */
note = last_loop_beg_note (e->src->end);
@ -1180,6 +1225,7 @@ split_edge (edge_in)
: edge_in->dest->index, before, NULL);
bb->count = edge_in->count;
bb->frequency = EDGE_FREQUENCY (edge_in);
bb->loop_depth = edge_in->dest->loop_depth;
/* ??? This info is likely going to be out of date very soon. */
if (edge_in->dest->global_live_at_start)
@ -1863,9 +1909,30 @@ purge_dead_edges (bb)
rtx insn = bb->end, note;
bool purged = false;
/* ??? This makes no sense since the later test includes more cases. */
if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
return false;
/* If this instruction cannot trap, remove REG_EH_REGION notes. */
if (GET_CODE (insn) == INSN
&& (note = find_reg_note (insn, REG_EH_REGION, NULL)))
{
rtx eqnote;
if (! may_trap_p (PATTERN (insn))
|| ((eqnote = find_reg_equal_equiv_note (insn))
&& ! may_trap_p (XEXP (eqnote, 0))))
remove_note (insn, note);
}
/* Cleanup abnormal edges caused by throwing insns that have been
eliminated. */
if (! can_throw_internal (bb->end))
for (e = bb->succ; e; e = next)
{
next = e->succ_next;
if (e->flags & EDGE_EH)
{
remove_edge (e);
purged = true;
}
}
if (GET_CODE (insn) == JUMP_INSN)
{
@ -1934,31 +2001,6 @@ purge_dead_edges (bb)
return purged;
}
/* If this instruction cannot trap, remove REG_EH_REGION notes. */
if (GET_CODE (insn) == INSN
&& (note = find_reg_note (insn, REG_EH_REGION, NULL)))
{
rtx eqnote;
if (! may_trap_p (PATTERN (insn))
|| ((eqnote = find_reg_equal_equiv_note (insn))
&& ! may_trap_p (XEXP (eqnote, 0))))
remove_note (insn, note);
}
/* Cleanup abnormal edges caused by throwing insns that have been
eliminated. */
if (! can_throw_internal (bb->end))
for (e = bb->succ; e; e = next)
{
next = e->succ_next;
if (e->flags & EDGE_EH)
{
remove_edge (e);
purged = true;
}
}
/* If we don't see a jump insn, we don't know exactly why the block would
have been broken at this point. Look for a simple, non-fallthru edge,
as these are only created by conditional branches. If we find such an

View File

@ -17,122 +17,52 @@ License along with libiberty; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This file exports two functions: choose_temp_base and make_temp_file. */
/* This file lives in at least two places: libiberty and gcc.
Don't change one without the other. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h> /* May get P_tmpdir. */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h> /* May get R_OK, etc. on some systems. */
#endif
#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "libiberty.h"
extern int mkstemps ();
#ifndef IN_GCC
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN))
#define DIR_SEPARATOR '\\'
#endif
#endif
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
/* On MSDOS, write temp files in current dir
because there's no place else we can expect to use. */
/* ??? Although the current directory is tried as a last resort,
this is left in so that on MSDOS it is preferred to /tmp on the
off chance that someone requires this, since that was the previous
behaviour. */
#ifdef __MSDOS__
#ifndef P_tmpdir
#define P_tmpdir "."
#endif
#endif
extern char *choose_tmpdir PARAMS ((void));
/* Name of temporary file.
mktemp requires 6 trailing X's. */
#define TEMP_FILE "ccXXXXXX"
#define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
/* Subroutine of choose_temp_base.
If BASE is non-NULL, return it.
Otherwise it checks if DIR is a usable directory.
If success, DIR is returned.
Otherwise NULL is returned. */
/*
static char *
try (dir, base)
char *dir, *base;
{
if (base != 0)
return base;
if (dir != 0
&& access (dir, R_OK | W_OK | X_OK) == 0)
return dir;
return 0;
}
@deftypefn Extension char* choose_temp_base (void)
/* Return a prefix for temporary file names or NULL if unable to find one.
The current directory is chosen if all else fails so the program is
exited if a temporary directory can't be found (mktemp fails).
The buffer for the result is obtained with xmalloc.
Return a prefix for temporary file names or @code{NULL} if unable to
find one. The current directory is chosen if all else fails so the
program is exited if a temporary directory can't be found (@code{mktemp}
fails). The buffer for the result is obtained with @code{xmalloc}.
This function is provided for backwards compatability only. It use
is not recommended. */
This function is provided for backwards compatability only. Its use is
not recommended.
@end deftypefn
*/
char *
choose_temp_base ()
{
char *base = 0;
const char *base = choose_tmpdir ();
char *temp_filename;
int len;
static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
base = try (getenv ("TMPDIR"), base);
base = try (getenv ("TMP"), base);
base = try (getenv ("TEMP"), base);
#ifdef P_tmpdir
base = try (P_tmpdir, base);
#endif
/* Try /usr/tmp, then /tmp. */
base = try (usrtmp, base);
base = try (tmp, base);
/* If all else fails, use the current directory! */
if (base == 0)
base = ".";
len = strlen (base);
temp_filename = xmalloc (len + 1 /*DIR_SEPARATOR*/
+ strlen (TEMP_FILE) + 1);
temp_filename = xmalloc (len + TEMP_FILE_LEN + 1);
strcpy (temp_filename, base);
if (len != 0
&& temp_filename[len-1] != '/'
&& temp_filename[len-1] != DIR_SEPARATOR)
temp_filename[len++] = DIR_SEPARATOR;
strcpy (temp_filename + len, TEMP_FILE);
mktemp (temp_filename);
@ -140,64 +70,3 @@ choose_temp_base ()
abort ();
return temp_filename;
}
/* Return a temporary file name (as a string) or NULL if unable to create
one. */
char *
make_temp_file (suffix)
char *suffix;
{
char *base = 0;
char *temp_filename;
int base_len, suffix_len;
int fd;
static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
base = try (getenv ("TMPDIR"), base);
base = try (getenv ("TMP"), base);
base = try (getenv ("TEMP"), base);
#ifdef P_tmpdir
base = try (P_tmpdir, base);
#endif
/* Try /usr/tmp, then /tmp. */
base = try (usrtmp, base);
base = try (tmp, base);
/* If all else fails, use the current directory! */
if (base == 0)
base = ".";
base_len = strlen (base);
if (suffix)
suffix_len = strlen (suffix);
else
suffix_len = 0;
temp_filename = xmalloc (base_len + 1 /*DIR_SEPARATOR*/
+ strlen (TEMP_FILE)
+ suffix_len + 1);
strcpy (temp_filename, base);
if (base_len != 0
&& temp_filename[base_len-1] != '/'
&& temp_filename[base_len-1] != DIR_SEPARATOR)
temp_filename[base_len++] = DIR_SEPARATOR;
strcpy (temp_filename + base_len, TEMP_FILE);
if (suffix)
strcat (temp_filename, suffix);
fd = mkstemps (temp_filename, suffix_len);
/* If mkstemps failed, then something bad is happening. Maybe we should
issue a message about a possible security attack in progress? */
if (fd == -1)
abort ();
/* Similarly if we can not close the file. */
if (close (fd))
abort ();
return temp_filename;
}

View File

@ -532,7 +532,7 @@ dump_file (name)
if (no_demangle)
result = 0;
else
result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
if (result)
{

View File

@ -424,6 +424,33 @@ do_SUBST (into, newval)
if (oldval == newval)
return;
/* We'd like to catch as many invalid transformations here as
possible. Unfortunately, there are way too many mode changes
that are perfectly valid, so we'd waste too much effort for
little gain doing the checks here. Focus on catching invalid
transformations involving integer constants. */
if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
&& GET_CODE (newval) == CONST_INT)
{
/* Sanity check that we're replacing oldval with a CONST_INT
that is a valid sign-extension for the original mode. */
if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval),
GET_MODE (oldval)))
abort ();
/* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
CONST_INT is not valid, because after the replacement, the
original mode would be gone. Unfortunately, we can't tell
when do_SUBST is called to replace the operand thereof, so we
perform this test on oldval instead, checking whether an
invalid replacement took place before we got here. */
if ((GET_CODE (oldval) == SUBREG
&& GET_CODE (SUBREG_REG (oldval)) == CONST_INT)
|| (GET_CODE (oldval) == ZERO_EXTEND
&& GET_CODE (XEXP (oldval, 0)) == CONST_INT))
abort ();
}
if (undobuf.frees)
buf = undobuf.frees, undobuf.frees = buf->next;
else
@ -877,8 +904,10 @@ set_nonzero_bits_and_sign_copies (x, set, data)
<< GET_MODE_BITSIZE (GET_MODE (x))));
#endif
reg_nonzero_bits[REGNO (x)]
|= nonzero_bits (src, nonzero_bits_mode);
/* Don't call nonzero_bits if it cannot change anything. */
if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
reg_nonzero_bits[REGNO (x)]
|= nonzero_bits (src, nonzero_bits_mode);
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
if (reg_sign_bit_copies[REGNO (x)] == 0
|| reg_sign_bit_copies[REGNO (x)] > num)
@ -1478,6 +1507,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
{
/* New patterns for I3 and I2, respectively. */
rtx newpat, newi2pat = 0;
int substed_i2 = 0, substed_i1 = 0;
/* Indicates need to preserve SET in I1 or I2 in I3 if it is not dead. */
int added_sets_1, added_sets_2;
/* Total number of SETs to put into I3. */
@ -1939,6 +1969,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
subst_low_cuid = INSN_CUID (i2);
newpat = subst (PATTERN (i3), i2dest, i2src, 0,
! i1_feeds_i3 && i1dest_in_i1src);
substed_i2 = 1;
/* Record whether i2's body now appears within i3's body. */
i2_is_used = n_occurrences;
@ -1963,6 +1994,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
n_occurrences = 0;
subst_low_cuid = INSN_CUID (i1);
newpat = subst (newpat, i1dest, i1src, 0, 0);
substed_i1 = 1;
}
/* Fail if an autoincrement side-effect has been duplicated. Be careful
@ -2534,6 +2566,23 @@ try_combine (i3, i2, i1, new_direct_jump_p)
INSN_CODE (i3) = insn_code_number;
PATTERN (i3) = newpat;
if (GET_CODE (i3) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (i3))
{
rtx call_usage = CALL_INSN_FUNCTION_USAGE (i3);
reset_used_flags (call_usage);
call_usage = copy_rtx (call_usage);
if (substed_i2)
replace_rtx (call_usage, i2dest, i2src);
if (substed_i1)
replace_rtx (call_usage, i1dest, i1src);
CALL_INSN_FUNCTION_USAGE (i3) = call_usage;
}
if (undobuf.other_insn)
INSN_CODE (undobuf.other_insn) = other_code_number;
@ -3013,8 +3062,11 @@ find_split_point (loc, insn)
SUBST (SET_SRC (x),
gen_binary (IOR, mode,
gen_binary (AND, mode, dest,
GEN_INT (~(mask << pos)
& GET_MODE_MASK (mode))),
GEN_INT
(
trunc_int_for_mode
(~(mask << pos)
& GET_MODE_MASK (mode), mode))),
GEN_INT (src << pos)));
SUBST (SET_DEST (x), dest);
@ -3485,7 +3537,24 @@ subst (x, from, to, in_dest, unique_copy)
if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
return new;
SUBST (XEXP (x, i), new);
if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
{
x = simplify_subreg (GET_MODE (x), new,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
if (! x)
abort ();
}
else if (GET_CODE (new) == CONST_INT
&& GET_CODE (x) == ZERO_EXTEND)
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
new, GET_MODE (XEXP (x, 0)));
if (! x)
abort ();
}
else
SUBST (XEXP (x, i), new);
}
}
}
@ -3807,6 +3876,13 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return temp;
}
/* Don't change the mode of the MEM if that would change the meaning
of the address. */
if (GET_CODE (SUBREG_REG (x)) == MEM
&& (MEM_VOLATILE_P (SUBREG_REG (x))
|| mode_dependent_address_p (XEXP (SUBREG_REG (x), 0))))
return gen_rtx_CLOBBER (mode, const0_rtx);
/* Note that we cannot do any narrowing for non-constants since
we might have been counting on using the fact that some bits were
zero. We now do this in the SET. */
@ -5963,6 +6039,9 @@ make_extraction (mode, inner, pos, pos_rtx, len,
if (mode == tmode)
return new;
if (GET_CODE (new) == CONST_INT)
return GEN_INT (trunc_int_for_mode (INTVAL (new), mode));
/* If we know that no extraneous bits are set, and that the high
bit is not set, convert the extraction to the cheaper of
sign and zero extension, that are equivalent in these cases. */
@ -6753,33 +6832,12 @@ force_to_mode (x, mode, mask, reg, just_select)
smask |= (HOST_WIDE_INT) -1 << width;
if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (- smask) >= 0)
{
#ifdef STACK_BIAS
if (STACK_BIAS
&& (XEXP (x, 0) == stack_pointer_rtx
|| XEXP (x, 0) == frame_pointer_rtx))
{
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
sp_mask &= ~(sp_alignment - 1);
if ((sp_mask & ~smask) == 0
&& ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
((INTVAL (XEXP (x, 1)) -
STACK_BIAS) & smask)
+ STACK_BIAS),
mode, smask, reg, next_select);
}
#endif
if ((nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
&& (INTVAL (XEXP (x, 1)) & ~smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
(INTVAL (XEXP (x, 1))
& smask)),
mode, smask, reg, next_select);
}
&& exact_log2 (- smask) >= 0
&& (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
&& (INTVAL (XEXP (x, 1)) & ~smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
(INTVAL (XEXP (x, 1)) & smask)),
mode, smask, reg, next_select);
}
/* ... fall through ... */
@ -7322,7 +7380,7 @@ if_then_else_cond (x, ptrue, pfalse)
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
{
*ptrue = GEN_INT (nz), *pfalse = const0_rtx;
*ptrue = GEN_INT (trunc_int_for_mode (nz, mode)), *pfalse = const0_rtx;
return x;
}
@ -7431,6 +7489,50 @@ known_cond (x, cond, reg, val)
}
}
}
else if (code == SUBREG)
{
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
if (SUBREG_REG (x) != r)
{
/* We must simplify subreg here, before we lose track of the
original inner_mode. */
new = simplify_subreg (GET_MODE (x), r,
inner_mode, SUBREG_BYTE (x));
if (new)
return new;
else
SUBST (SUBREG_REG (x), r);
}
return x;
}
/* We don't have to handle SIGN_EXTEND here, because even in the
case of replacing something with a modeless CONST_INT, a
CONST_INT is already (supposed to be) a valid sign extension for
its narrower mode, which implies it's already properly
sign-extended for the wider mode. Now, for ZERO_EXTEND, the
story is different. */
else if (code == ZERO_EXTEND)
{
enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
if (XEXP (x, 0) != r)
{
/* We must simplify the zero_extend here, before we lose
track of the original inner_mode. */
new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
r, inner_mode);
if (new)
return new;
else
SUBST (XEXP (x, 0), r);
}
return x;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@ -7743,14 +7845,23 @@ simplify_and_const_int (x, mode, varop, constop)
int i;
/* Simplify VAROP knowing that we will be only looking at some of the
bits in it. */
bits in it.
Note by passing in CONSTOP, we guarantee that the bits not set in
CONSTOP are not significant and will never be examined. We must
ensure that is the case by explicitly masking out those bits
before returning. */
varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
/* If VAROP is a CLOBBER, we will fail so return it; if it is a
CONST_INT, we are done. */
if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT)
/* If VAROP is a CLOBBER, we will fail so return it. */
if (GET_CODE (varop) == CLOBBER)
return varop;
/* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
to VAROP and return the new constant. */
if (GET_CODE (varop) == CONST_INT)
return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode));
/* See what bits may be nonzero in VAROP. Unlike the general case of
a call to nonzero_bits, here we don't care about bits outside
MODE. */
@ -7916,40 +8027,28 @@ nonzero_bits (x, mode)
nonzero &= GET_MODE_MASK (ptr_mode);
#endif
#ifdef STACK_BOUNDARY
/* If this is the stack pointer, we may know something about its
alignment. If PUSH_ROUNDING is defined, it is possible for the
stack to be momentarily aligned only to that amount, so we pick
the least alignment. */
/* We can't check for arg_pointer_rtx here, because it is not
guaranteed to have as much alignment as the stack pointer.
In particular, in the Irix6 n64 ABI, the stack has 128 bit
alignment but the argument pointer has only 64 bit alignment. */
if ((x == frame_pointer_rtx
|| x == stack_pointer_rtx
|| x == hard_frame_pointer_rtx
|| (REGNO (x) >= FIRST_VIRTUAL_REGISTER
&& REGNO (x) <= LAST_VIRTUAL_REGISTER))
#ifdef STACK_BIAS
&& !STACK_BIAS
#endif
)
/* Include declared information about alignment of pointers. */
/* ??? We don't properly preserve REG_POINTER changes across
pointer-to-integer casts, so we can't trust it except for
things that we know must be pointers. See execute/960116-1.c. */
if ((x == stack_pointer_rtx
|| x == frame_pointer_rtx
|| x == arg_pointer_rtx)
&& REGNO_POINTER_ALIGN (REGNO (x)))
{
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
unsigned HOST_WIDE_INT alignment
= REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
#ifdef PUSH_ROUNDING
if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS)
sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
/* If PUSH_ROUNDING is defined, it is possible for the
stack to be momentarily aligned only to that amount,
so we pick the least alignment. */
if (x == stack_pointer_rtx && PUSH_ARGS)
alignment = MIN (PUSH_ROUNDING (1), alignment);
#endif
/* We must return here, otherwise we may get a worse result from
one of the choices below. There is nothing useful below as
far as the stack pointer is concerned. */
return nonzero &= ~(sp_alignment - 1);
nonzero &= ~(alignment - 1);
}
#endif
/* If X is a register whose nonzero bits value is current, use it.
Otherwise, if X is a register whose value we can find, use that
@ -7957,14 +8056,16 @@ nonzero_bits (x, mode)
for this register. */
if (reg_last_set_value[REGNO (x)] != 0
&& reg_last_set_mode[REGNO (x)] == mode
&& (reg_last_set_mode[REGNO (x)] == mode
|| (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
&& GET_MODE_CLASS (mode) == MODE_INT))
&& (reg_last_set_label[REGNO (x)] == label_tick
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (x)) == 1
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
REGNO (x))))
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
return reg_last_set_nonzero_bits[REGNO (x)];
return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
tem = get_last_value (x);
@ -7990,7 +8091,7 @@ nonzero_bits (x, mode)
| ((HOST_WIDE_INT) (-1)
<< GET_MODE_BITSIZE (GET_MODE (x))));
#endif
return nonzero_bits (tem, mode);
return nonzero_bits (tem, mode) & nonzero;
}
else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
{
@ -8099,8 +8200,14 @@ nonzero_bits (x, mode)
case XOR: case IOR:
case UMIN: case UMAX: case SMIN: case SMAX:
nonzero &= (nonzero_bits (XEXP (x, 0), mode)
| nonzero_bits (XEXP (x, 1), mode));
{
unsigned HOST_WIDE_INT nonzero0 = nonzero_bits (XEXP (x, 0), mode);
/* Don't call nonzero_bits for the second time if it cannot change
anything. */
if ((nonzero & nonzero0) != nonzero)
nonzero &= (nonzero0 | nonzero_bits (XEXP (x, 1), mode));
}
break;
case PLUS: case MINUS:
@ -8128,22 +8235,6 @@ nonzero_bits (x, mode)
switch (code)
{
case PLUS:
#ifdef STACK_BIAS
if (STACK_BIAS
&& (XEXP (x, 0) == stack_pointer_rtx
|| XEXP (x, 0) == frame_pointer_rtx)
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
{
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
nz0 = (GET_MODE_MASK (mode) & ~(sp_alignment - 1));
nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS;
width0 = floor_log2 (nz0) + 1;
width1 = floor_log2 (nz1) + 1;
low0 = floor_log2 (nz0 & -nz0);
low1 = floor_log2 (nz1 & -nz1);
}
#endif
result_width = MAX (width0, width1) + 1;
result_low = MIN (low0, low1);
break;
@ -9590,7 +9681,7 @@ recog_for_combine (pnewpat, insn, pnotes)
int num_clobbers_to_add = 0;
int i;
rtx notes = 0;
rtx old_notes;
rtx dummy_insn;
/* If PAT is a PARALLEL, check to see if it contains the CLOBBER
we use to indicate that something didn't match. If we find such a
@ -9601,11 +9692,13 @@ recog_for_combine (pnewpat, insn, pnotes)
&& XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
return -1;
/* Remove the old notes prior to trying to recognize the new pattern. */
old_notes = REG_NOTES (insn);
REG_NOTES (insn) = 0;
/* *pnewpat does not have to be actual PATTERN (insn), so make a dummy
instruction for pattern recognition. */
dummy_insn = shallow_copy_rtx (insn);
PATTERN (dummy_insn) = pat;
REG_NOTES (dummy_insn) = 0;
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
/* If it isn't, there is the possibility that we previously had an insn
that clobbered some register as a side effect, but the combined
@ -9630,15 +9723,14 @@ recog_for_combine (pnewpat, insn, pnotes)
if (pos == 1)
pat = XVECEXP (pat, 0, 0);
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
PATTERN (dummy_insn) = pat;
insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
}
/* Recognize all noop sets, these will be killed by followup pass. */
if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;
REG_NOTES (insn) = old_notes;
/* If we had any clobbers to add, make a new pattern than contains
them. Then check to make sure that all of them are dead. */
if (num_clobbers_to_add)
@ -10775,9 +10867,9 @@ simplify_comparison (code, pop0, pop1)
&& XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
MODE_INT, 1)) != BLKmode
&& ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode)
|| ((unsigned HOST_WIDE_INT) -const_op
<= GET_MODE_MASK (tmode))))
&& (((unsigned HOST_WIDE_INT) const_op
+ (GET_MODE_MASK (tmode) >> 1) + 1)
<= GET_MODE_MASK (tmode)))
{
op0 = gen_lowpart_for_combine (tmode, XEXP (XEXP (op0, 0), 0));
continue;
@ -10794,9 +10886,9 @@ simplify_comparison (code, pop0, pop1)
&& XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
MODE_INT, 1)) != BLKmode
&& ((unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (tmode)
|| ((unsigned HOST_WIDE_INT) -const_op
<= GET_MODE_MASK (tmode))))
&& (((unsigned HOST_WIDE_INT) const_op
+ (GET_MODE_MASK (tmode) >> 1) + 1)
<= GET_MODE_MASK (tmode)))
{
rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
rtx add_const = XEXP (XEXP (op0, 0), 1);
@ -10821,10 +10913,18 @@ simplify_comparison (code, pop0, pop1)
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (XEXP (op0, 0), mode)
& (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
&& (const_op == 0
|| (floor_log2 (const_op) + INTVAL (XEXP (op0, 1))
< mode_width)))
&& (((unsigned HOST_WIDE_INT) const_op
+ (GET_CODE (op0) != LSHIFTRT
? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
+ 1)
: 0))
<= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
{
/* If the shift was logical, then we must make the condition
unsigned. */
if (GET_CODE (op0) == LSHIFTRT)
code = unsigned_condition (code);
const_op <<= INTVAL (XEXP (op0, 1));
op1 = GEN_INT (const_op);
op0 = XEXP (op0, 0);
@ -10853,38 +10953,56 @@ simplify_comparison (code, pop0, pop1)
/* Now make any compound operations involved in this comparison. Then,
check for an outmost SUBREG on OP0 that is not doing anything or is
paradoxical. The latter case can only occur when it is known that the
"extra" bits will be zero. Therefore, it is safe to remove the SUBREG.
We can never remove a SUBREG for a non-equality comparison because the
sign bit is in a different place in the underlying object. */
paradoxical. The latter transformation must only be performed when
it is known that the "extra" bits will be the same in op0 and op1 or
that they don't matter. There are three cases to consider:
1. SUBREG_REG (op0) is a register. In this case the bits are don't
care bits and we can assume they have any convenient value. So
making the transformation is safe.
2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined.
In this case the upper bits of op0 are undefined. We should not make
the simplification in that case as we do not know the contents of
those bits.
3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not
NIL. In that case we know those bits are zeros or ones. We must
also be sure that they are the same as the upper bits of op1.
We can never remove a SUBREG for a non-equality comparison because
the sign bit is in a different place in the underlying object. */
op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
op1 = make_compound_operation (op1, SET);
if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
/* Case 3 above, to sometimes allow (subreg (mem x)), isn't
implemented. */
&& GET_CODE (SUBREG_REG (op0)) == REG
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
&& (code == NE || code == EQ)
&& ((GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))))
&& (code == NE || code == EQ))
{
op0 = SUBREG_REG (op0);
op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
}
if (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
{
op0 = SUBREG_REG (op0);
op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
}
else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
<= HOST_BITS_PER_WIDE_INT)
&& (nonzero_bits (SUBREG_REG (op0),
GET_MODE (SUBREG_REG (op0)))
& ~GET_MODE_MASK (GET_MODE (op0))) == 0)
{
tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1);
else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
&& (code == NE || code == EQ)
&& (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
<= HOST_BITS_PER_WIDE_INT)
&& (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0)))
& ~GET_MODE_MASK (GET_MODE (op0))) == 0
&& (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)),
op1),
(nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
& ~GET_MODE_MASK (GET_MODE (op0))) == 0))
op0 = SUBREG_REG (op0), op1 = tem;
if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
& ~GET_MODE_MASK (GET_MODE (op0))) == 0)
op0 = SUBREG_REG (op0), op1 = tem;
}
}
/* We now do the opposite procedure: Some machines don't have compare
insns in all modes. If OP0's mode is an integer mode smaller than a
@ -10902,14 +11020,22 @@ simplify_comparison (code, pop0, pop1)
tmode = GET_MODE_WIDER_MODE (tmode))
if (have_insn_for (COMPARE, tmode))
{
int zero_extended;
/* If the only nonzero bits in OP0 and OP1 are those in the
narrower mode and this is an equality or unsigned comparison,
we can use the wider mode. Similarly for sign-extended
values, in which case it is true for all comparisons. */
if (((code == EQ || code == NE
|| code == GEU || code == GTU || code == LEU || code == LTU)
&& (nonzero_bits (op0, tmode) & ~GET_MODE_MASK (mode)) == 0
&& (nonzero_bits (op1, tmode) & ~GET_MODE_MASK (mode)) == 0)
zero_extended = ((code == EQ || code == NE
|| code == GEU || code == GTU
|| code == LEU || code == LTU)
&& (nonzero_bits (op0, tmode)
& ~GET_MODE_MASK (mode)) == 0
&& ((GET_CODE (op1) == CONST_INT
|| (nonzero_bits (op1, tmode)
& ~GET_MODE_MASK (mode)) == 0)));
if (zero_extended
|| ((num_sign_bit_copies (op0, tmode)
> GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode))
&& (num_sign_bit_copies (op1, tmode)
@ -10926,6 +11052,8 @@ simplify_comparison (code, pop0, pop1)
XEXP (op0, 1)));
op0 = gen_lowpart_for_combine (tmode, op0);
if (zero_extended && GET_CODE (op1) == CONST_INT)
op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
op1 = gen_lowpart_for_combine (tmode, op1);
break;
}
@ -11123,9 +11251,13 @@ record_value_for_reg (reg, insn, value)
if (value)
{
enum machine_mode mode = GET_MODE (reg);
subst_low_cuid = INSN_CUID (insn);
reg_last_set_mode[regno] = GET_MODE (reg);
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, GET_MODE (reg));
reg_last_set_mode[regno] = mode;
if (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
mode = nonzero_bits_mode;
reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
reg_last_set_sign_bit_copies[regno]
= num_sign_bit_copies (value, GET_MODE (reg));
}
@ -11612,6 +11744,7 @@ mark_used_regs_combine (x)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:

236
contrib/gcc/concat.c Normal file
View File

@ -0,0 +1,236 @@
/* Concatenate variable number of strings.
Copyright (C) 1991, 1994, 2001 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @dots{}, @code{NULL})
Concatenate zero or more of strings and return the result in freshly
@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
available. The argument list is terminated by the first @code{NULL}
pointer encountered. Pointers to empty strings are ignored.
@end deftypefn
NOTES
This function uses xmalloc() which is expected to be a front end
function to malloc() that deals with low memory situations. In
typical use, if malloc() returns NULL then xmalloc() diverts to an
error handler routine which never returns, and thus xmalloc will
never return a NULL pointer. If the client application wishes to
deal with low memory situations itself, it should supply an xmalloc
that just directly invokes malloc and blindly returns whatever
malloc returns.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ansidecl.h"
#include "libiberty.h"
#include <sys/types.h> /* size_t */
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
# if HAVE_STRING_H
# include <string.h>
# else
# if HAVE_STRINGS_H
# include <strings.h>
# endif
# endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
static inline unsigned long vconcat_length PARAMS ((const char *, va_list));
static inline unsigned long
vconcat_length (first, args)
const char *first;
va_list args;
{
unsigned long length = 0;
const char *arg;
for (arg = first; arg ; arg = va_arg (args, const char *))
length += strlen (arg);
return length;
}
static inline char *vconcat_copy PARAMS ((char *, const char *, va_list));
static inline char *
vconcat_copy (dst, first, args)
char *dst;
const char *first;
va_list args;
{
char *end = dst;
const char *arg;
for (arg = first; arg ; arg = va_arg (args, const char *))
{
unsigned long length = strlen (arg);
memcpy (end, arg, length);
end += length;
}
*end = '\000';
return dst;
}
/* @undocumented concat_length */
unsigned long
concat_length VPARAMS ((const char *first, ...))
{
unsigned long length;
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
length = vconcat_length (first, args);
VA_CLOSE (args);
return length;
}
/* @undocumented concat_copy */
char *
concat_copy VPARAMS ((char *dst, const char *first, ...))
{
char *save_dst;
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, dst);
VA_FIXEDARG (args, const char *, first);
vconcat_copy (dst, first, args);
save_dst = dst; /* With K&R C, dst goes out of scope here. */
VA_CLOSE (args);
return save_dst;
}
char *libiberty_concat_ptr;
/* @undocumented concat_copy2 */
char *
concat_copy2 VPARAMS ((const char *first, ...))
{
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
vconcat_copy (libiberty_concat_ptr, first, args);
VA_CLOSE (args);
return libiberty_concat_ptr;
}
char *
concat VPARAMS ((const char *first, ...))
{
char *newstr;
/* First compute the size of the result and get sufficient memory. */
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
VA_CLOSE (args);
/* Now copy the individual pieces to the result string. */
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
vconcat_copy (newstr, first, args);
VA_CLOSE (args);
return newstr;
}
/*
@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @dots{}, @code{NULL})
Same as @code{concat}, except that if @var{optr} is not @code{NULL} it
is freed after the string is created. This is intended to be useful
when you're extending an existing string or building up a string in a
loop:
@example
str = reconcat (str, "pre-", str, NULL);
@end example
@end deftypefn
*/
char *
reconcat VPARAMS ((char *optr, const char *first, ...))
{
char *newstr;
/* First compute the size of the result and get sufficient memory. */
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, optr);
VA_FIXEDARG (args, const char *, first);
newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
VA_CLOSE (args);
/* Now copy the individual pieces to the result string. */
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, optr);
VA_FIXEDARG (args, const char *, first);
vconcat_copy (newstr, first, args);
if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
free (optr);
VA_CLOSE (args);
return newstr;
}
#ifdef MAIN
#define NULLP (char *)0
/* Simple little test driver. */
#include <stdio.h>
int
main ()
{
printf ("\"\" = \"%s\"\n", concat (NULLP));
printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));
printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP));
printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP));
printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP));
printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP));
printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP));
return 0;
}
#endif

View File

@ -207,6 +207,80 @@ gas="$gas_flag"
gnu_ld="$gnu_ld_flag"
enable_threads=$enable_threads_flag
# Obsolete configurations.
# To avoid some tedious lists, we have a blacklist with a whitelist
# embedded within it.
case $machine in
1750a-* \
| a29k-* \
| alpha*-*-osf[123]* \
| arm-*-riscix* \
| c*-convex-* \
| clipper-* \
| elxsi-* \
| i860-* \
| i?86-*-aix* \
| i?86-*-bsd* \
| i?86-*-chorusos* \
| i?86-*-dgux* \
| i?86-*-freebsd1.* \
| i?86-*-isc* \
| i?86-*-linux*oldld* \
| i?86-*-osf1* \
| i?86-*-osfrose* \
| i?86-*-rtemscoff* \
| i?86-*-sunos* \
| i?86-go32-rtems* \
| i?86-next-* \
| i?86-sequent-bsd* \
| i?86-sequent-ptx[12]* \
| i?86-sequent-sysv3* \
| m68[k0]*-*-lynxos* \
| m68[k0]*-*-rtemscoff* \
| m68[k0]*-*-sysv3* \
| m68[k0]*-altos-* \
| m68[k0]*-apollo-* \
| m68[k0]*-apple-* \
| m68[k0]*-bull-* \
| m68[k0]*-convergent-* \
| m68[k0]*-isi-* \
| m68[k0]*-next-* \
| m68[k0]*-sony-* \
| m88k-* \
| mips-*-bsd* \
| mips-*-riscos* \
| mips-*-sysv* \
| mips-*-ultrix* \
| mips-dec-* \
| mips-sgi-irix[1234]* \
| mips-sony-* \
| mips-tandem-* \
| ns32k-* \
| pj-* \
| pjl-* \
| romp-* \
| sparc-*-rtemsaout* \
| we32k-* \
)
case $machine in
mips-sni-sysv4 \
| m88k-*-aout* | m88k-*-openbsd* | m88k-*-sysv4* \
| ns32k-*-netbsd* | ns32k-*-openbsd* \
| romp-*-openbsd* \
)
# Whitelisted.
;;
*)
if test "x$enable_obsolete" != xyes; then
echo "*** Configuration $machine is obsolete." >&2
echo "*** Specify --enable-obsolete to build it anyway." >&2
echo "*** Support will be REMOVED in the next major release of GCC," >&2
echo "*** unless a maintainer comes forward." >&2
exit 1
fi;;
esac
esac
# Set default cpu_type, tm_file, tm_p_file and xm_file so it can be
# updated in each machine entry. Also set default extra_headers for some
# machines.
@ -243,7 +317,7 @@ ia64-*-*)
hppa*-*-* | parisc*-*-*)
cpu_type=pa
;;
m680[02]0-*-*)
m680[012]0-*-*)
cpu_type=m68k
extra_headers=math-68881.h
;;
@ -263,6 +337,9 @@ powerpc*-*-*)
sparc*-*-*)
cpu_type=sparc
;;
sh64-*-*)
cpu_type=sh
;;
esac
tm_file=${cpu_type}/${cpu_type}.h
@ -320,7 +397,7 @@ case $machine in
fi
;;
*-*-netbsd*)
tmake_file="t-libc-ok t-netbsd"
tmake_file="t-slibgcc-elf-ver t-libc-ok t-netbsd"
xm_defines=POSIX
gas=yes
gnu_ld=yes
@ -360,7 +437,7 @@ case $machine in
*-*-freebsd6 | *-*-freebsd[6].*) fbsd_tm_file="freebsd6.h";;
*) echo 'Please update *-*-freebsd* in gcc/config.gcc'; exit 1;;
esac
tmake_file=t-freebsd
tmake_file="t-slibgcc-elf-ver t-freebsd"
xmake_file=none
xm_defines=POSIX
case x${enable_threads} in
@ -368,6 +445,12 @@ case $machine in
x | xyes | xpthreads | xposix)
thread_file='posix'
tmake_file="${tmake_file} t-freebsd-thread"
# Before 5.0, FreeBSD can't bind shared libraries to -lc
# when "optionally" threaded via weak pthread_* checks.
case $machine in
*-*-freebsd[34] | *-*-freebsd[34].*)
tmake_file="${tmake_file} t-slibgcc-nolc-override";;
esac
;;
*) echo 'Unknown thread configuration for FreeBSD'; exit 1;;
esac
@ -407,7 +490,8 @@ a29k-*-udi | a29k-*-coff)
tmake_file=a29k/t-a29kbare
;;
a29k*-*-rtems*)
tm_file=a29k/rtems.h
xm_defines=POSIX
tm_file="a29k/a29k.h a29k/rtems.h rtems.h"
tmake_file="a29k/t-a29kbare t-rtems"
if test x$enable_threads = xyes; then
thread_file='rtems'
@ -587,13 +671,6 @@ arc-*-elf*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
extra_parts="crtinit.o crtfini.o"
;;
arm*-*-rtems*)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
tmake_file="arm/t-arm-elf t-rtems"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
arm-*-coff* | armel-*-coff*)
tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h"
tmake_file=arm/t-arm-coff
@ -629,6 +706,9 @@ arm*-*-freebsd*|strongarm*-*-freebsd*)
tm_file="dbxelf.h elfos.h ${fbsd_tm_file} arm/elf.h arm/aout.h arm/freebsd.h arm/arm.h"
tmake_file="${tmake_file} arm/t-strongarm-elf"
;;
arm*-*-netbsdelf*)
echo "GCC does not yet support the ${machine} target"; exit 1
;;
arm*-*-netbsd*)
tm_file="arm/aout.h arm/arm.h netbsd.h netbsd-aout.h arm/netbsd.h"
tmake_file="t-netbsd arm/t-netbsd"
@ -657,6 +737,14 @@ arm*-*-ecos-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
tmake_file=arm/t-arm-elf
;;
arm*-*-rtems*)
xm_defines=POSIX
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
tmake_file="arm/t-arm-elf t-rtems"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
arm*-*-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
tmake_file=arm/t-arm-elf
@ -697,8 +785,9 @@ c38-convex-*)
use_collect2=yes
;;
c4x-*-rtems*)
xm_defines=POSIX
tmake_file="c4x/t-c4x t-rtems"
tm_file=c4x/rtems.h
tm_file="c4x/c4x.h c4x/rtems.h rtems.h"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
@ -753,8 +842,9 @@ fr30-*-elf)
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
;;
h8300-*-rtems*)
xm_defines=POSIX
tmake_file="h8300/t-h8300 t-rtems"
tm_file=h8300/rtems.h
tm_file="h8300/h8300.h h8300/rtems.h rtems.h"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
@ -794,32 +884,39 @@ hppa1.1-*-pro*)
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h"
tmake_file="pa/t-bsd pa/t-pro"
xmake_file="pa/x-ada"
;;
hppa1.1-*-osf*)
target_cpu_default="MASK_PA_11"
tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
tmake_file="pa/t-bsd pa/t-pa"
xmake_file="pa/x-ada"
use_collect2=yes
;;
hppa1.1-*-rtems*)
xm_defines=POSIX
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h pa/rtems.h"
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h pa/rtems.h rtems.h"
tmake_file="pa/t-bsd pa/t-pro"
xmake_file="pa/x-ada"
;;
hppa1.0-*-osf*)
tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
tmake_file="pa/t-bsd pa/t-pa"
xmake_file="pa/x-ada"
use_collect2=yes
;;
hppa1.1-*-bsd*)
tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
target_cpu_default="MASK_PA_11"
tmake_file="pa/t-bsd pa/t-pa"
xmake_file="pa/x-ada"
use_collect2=yes
;;
hppa1.0-*-bsd*)
tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
tmake_file="pa/t-bsd pa/t-pa"
xmake_file="pa/x-ada"
use_collect2=yes
;;
hppa1.0-*-hpux7*)
@ -873,6 +970,7 @@ hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
float_format=i128
xm_defines=POSIX
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
xmake_file="pa/x-ada"
if test x$enable_threads = x; then
enable_threads=$have_pthread_h
fi
@ -889,6 +987,7 @@ hppa1.0-*-hpux10*)
float_format=i128
xm_defines=POSIX
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
xmake_file="pa/x-ada"
if test x$enable_threads = x; then
enable_threads=$have_pthread_h
fi
@ -905,6 +1004,7 @@ hppa*64*-*-hpux11*)
tm_file="pa/pa64-start.h ${tm_file} pa/pa64-regs.h pa/long_double.h pa/elf.h pa/pa-hpux.h pa/pa-hpux11.h pa/pa-64.h pa/pa64-hpux.h"
float_format=i128
tmake_file="pa/t-pa64 pa/t-pa-hpux"
xmake_file="pa/x-ada"
target_cpu_default="(MASK_PA_11|MASK_PA_20|MASK_GAS)"
# if [ x$enable_threads = x ]; then
@ -923,6 +1023,7 @@ hppa1.1-*-hpux11* | hppa2*-*-hpux11*)
float_format=i128
xm_defines=POSIX
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
xmake_file="pa/x-ada"
# if test x$enable_threads = x; then
# enable_threads=$have_pthread_h
# fi
@ -938,6 +1039,7 @@ hppa1.0-*-hpux11*)
float_format=i128
xm_defines=POSIX
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
xmake_file="pa/x-ada"
# if test x$enable_threads = x; then
# enable_threads=$have_pthread_h
# fi
@ -982,6 +1084,7 @@ hppa*-*-lites*)
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h"
target_cpu_default="MASK_PA_11"
tmake_file="pa/t-bsd pa/t-pa"
xmake_file="pa/x-ada"
use_collect2=yes
;;
hppa*-*-mpeix*)
@ -1221,7 +1324,7 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
x86_64-*-linux*)
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h \
i386/x86-64.h i386/linux64.h"
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff i386/t-linux64"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
float_format=i386
@ -1281,21 +1384,24 @@ i[34567]86-*-osfrose*) # 386 using OSF/rose
extra_objs=halfpic.o
;;
i[34567]86-go32-rtems*)
tm_file=i386/djgpp-rtems.h
xm_defines=POSIX
tm_file="i386/djgpp.h i386/djgpp-rtems.h rtems.h"
tmake_file=t-rtems
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
i[34567]86-*-rtemscoff*)
tm_file=i386/rtems.h
xm_defines=POSIX
tm_file="i386/i386-coff.h i386/rtems.h rtems.h"
tmake_file=t-rtems
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
i[34567]86-*-rtems*|i[34567]86-*-rtemself*)
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/rtemself.h rtems.h"
xm_defines=POSIX
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/rtemself.h rtems.h"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
tmake_file="i386/t-rtems-i386 i386/t-crtstuff t-rtems"
if test x$enable_threads = xyes; then
@ -1319,7 +1425,6 @@ i[34567]86-*-solaris2*)
xm_defines="POSIX SMALL_ARG_MAX"
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sol2.h"
if test x$gas = xyes; then
# Only needed if gas does not support -s
tm_file="i386/sol2gas.h ${tm_file}"
fi
tmake_file="i386/t-sol2 t-svr4"
@ -1557,8 +1662,9 @@ i960-*-coff*)
cxx_target_objs="i960-c.o"
;;
i960-*-rtems)
xm_defines=POSIX
tmake_file="i960/t-960bare t-rtems"
tm_file="${tm_file} dbxcoff.h i960/rtems.h"
tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/rtems.h rtems.h"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
@ -1591,7 +1697,7 @@ ia64*-*-elf*)
float_format=i386
;;
ia64*-*-freebsd*)
tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h ia64/sysv4.h ia64/freebsd.h"
tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} ia64/sysv4.h ia64/freebsd.h"
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
tmake_file="${tmake_file} ia64/t-ia64"
float_format=i386
@ -1932,6 +2038,18 @@ m68k-*-lynxos*)
tmake_file=m68k/t-lynx
float_format=m68k
;;
m68010-*-netbsdelf* | m68k*-*-netbsdelf*)
tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
case $machine in
m68010*)
target_cpu_default="0"
;;
*)
target_cpu_default="MASK_68020|MASK_68881|MASK_BITFIELD"
;;
esac
float_format=m68k
;;
m68k*-*-netbsd*)
tm_file=m68k/netbsd.h
tmake_file=t-netbsd
@ -1991,16 +2109,18 @@ m68k-*-psos*)
float_format=m68k
;;
m68k-*-rtemscoff*)
xm_defines=POSIX
tmake_file="m68k/t-m68kbare t-rtems"
tm_file=m68k/rtems.h
tm_file="m68k/m68k-coff.h m68k/rtems.h rtems.h"
float_format=m68k
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
m68k-*-rtemself*|m68k-*-rtems*)
xm_defines=POSIX
tmake_file="m68k/t-m68kbare t-rtems m68k/t-crtstuff"
tm_file=m68k/rtemself.h
tm_file="m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h"
float_format=m68k
extra_parts="crtbegin.o crtend.o"
if test x$enable_threads = xyes; then
@ -2518,14 +2638,16 @@ mips64orion-*-elf*)
tmake_file=mips/t-elf
;;
mips64orion-*-rtems*)
tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h"
xm_defines=POSIX
tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h rtems.h"
tmake_file="mips/t-elf t-rtems"
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
mips*-*-rtems*)
tm_file="mips/elf.h mips/rtems.h"
xm_defines=POSIX
tm_file="mips/elf.h mips/rtems.h rtems.h"
tmake_file="mips/t-elf t-rtems"
if test x$enable_threads = xyes; then
thread_file='rtems'
@ -2602,6 +2724,9 @@ ns32k-pc532-minix*)
xm_defines='POSIX HZ=60'
use_collect2=yes
;;
ns32k-*-netbsdelf*)
echo "GCC does not yet support the ${machine} target"; exit 1
;;
ns32k-*-netbsd*)
tm_file=ns32k/netbsd.h
# On NetBSD, the headers are already okay, except for math.h.
@ -2643,7 +2768,12 @@ powerpc-*-openbsd*)
powerpc64-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux64.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
tmake_file="rs6000/t-rs6000 t-slibgcc-elf-ver t-linux rs6000/t-linux64"
;;
powerpc64-*-gnu*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux64.h rs6000/gnu.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
;;
powerpc-*-beos*)
tm_file="${tm_file} rs6000/aix.h rs6000/beos.h rs6000/xcoff.h"
@ -2719,7 +2849,7 @@ powerpc-*-eabi*)
;;
powerpc-*-rtems*)
xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rtems.h rs6000/rtems.h"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h rtems.h"
tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='rtems'
@ -2749,6 +2879,22 @@ powerpc-*-linux*)
thread_file='posix'
fi
;;
powerpc-*-gnu-gnualtivec*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-gnu*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/gnu.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-wrs-vxworks*)
xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/vxppc.h"
@ -2852,11 +2998,11 @@ s390-*-linux*)
fi
;;
s390x-*-linux*)
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h s390/linux64.h"
tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
tm_p_file=s390/s390-protos.h
md_file=s390/s390.md
out_file=s390/s390.c
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux s390/t-linux64"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
if test x$enable_threads = xyes; then
thread_file='posix'
@ -2867,17 +3013,29 @@ sh-*-elf*)
tm_file="${tm_file} sh/elf.h"
float_format=sh
;;
sh64-*-elf*)
tmake_file="sh/t-sh sh/t-elf sh/t-sh64"
tm_file="${tm_file} sh/sh.h sh/elf.h sh/sh64.h"
float_format=sh
extra_headers="../../config/sh/shmedia.h ../../config/sh/ushmedia.h ../../config/sh/sshmedia.h"
# Not strictly necessary to check this, but a good idea anyway.
if test $machine = $target; then
target_requires_64bit_host_wide_int=yes
fi
;;
sh-*-rtemself*)
xm_defines=POSIX
tmake_file="sh/t-sh sh/t-elf t-rtems"
tm_file="${tm_file} sh/elf.h sh/rtemself.h"
tm_file="${tm_file} sh/elf.h sh/rtemself.h rtems.h"
float_format=sh
if test x$enable_threads = xyes; then
thread_file='rtems'
fi
;;
sh-*-rtems*)
xm_defines=POSIX
tmake_file="sh/t-sh t-rtems"
tm_file="${tm_file} sh/rtems.h"
tm_file="${tm_file} sh/rtems.h rtems.h"
float_format=sh
if test x$enable_threads = xyes; then
thread_file='rtems'
@ -2901,7 +3059,7 @@ sparc-tti-*)
;;
sparc64-wrs-vxworks*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h sparc/biarch64.h gofast.h sparc/vxsparc64.h"
tmake_file=sparc/t-vxsparc64
tmake_file="sparc/t-vxsparc64 sparc/t-crtfm"
use_collect2=yes
;;
sparc-wrs-vxworks* | sparclite-wrs-vxworks*)
@ -2914,6 +3072,9 @@ sparc-*-aout*)
tmake_file=sparc/t-sparcbare
tm_file="sparc/sparc.h aoutos.h sparc/aout.h libgloss.h"
;;
sparc-*-netbsdelf*)
tm_file="${tm_file} elfos.h svr4.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
;;
sparc-*-netbsd*)
tm_file="${tm_file} sparc/aout.h netbsd.h netbsd-aout.h sparc/netbsd.h"
tmake_file=t-netbsd
@ -2931,7 +3092,7 @@ sparc-*-bsd*)
;;
sparc-*-chorusos*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h chorus.h"
tmake_file=sparc/t-chorus-elf
tmake_file="sparc/t-chorus-elf sparc/t-crtfm"
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
float_format=i64
case x${enable_threads} in
@ -2942,7 +3103,7 @@ sparc-*-chorusos*)
;;
sparc-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h"
tmake_file=sparc/t-elf
tmake_file="sparc/t-elf sparc/t-crtfm"
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
#float_format=i128
float_format=i64
@ -2953,14 +3114,14 @@ sparc-*-linux*aout*) # Sparc's running GNU/Linux, a.out
;;
sparc-*-linux*libc1*) # Sparc's running GNU/Linux, libc5
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1"
tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1 sparc/t-crtfm"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
gnu_ld=yes
float_format=sparc
;;
sparc-*-linux*) # Sparc's running GNU/Linux, libc6
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
tmake_file="t-slibgcc-elf-ver t-linux"
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
if test x$enable_threads = xyes; then
@ -2978,6 +3139,7 @@ sparc-*-lynxos*)
tmake_file=sparc/t-sunos41
;;
sparc-*-rtemsaout*)
xm_defines=POSIX
tmake_file="sparc/t-sparcbare t-rtems"
tm_file="${tm_file} aoutos.h sparc/aout.h sparc/rtems.h rtems.h"
if test x$enable_threads = xyes; then
@ -2985,8 +3147,9 @@ sparc-*-rtemsaout*)
fi
;;
sparc-*-rtems*|sparc-*-rtemself*)
xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h sparc/rtemself.h rtems.h"
tmake_file="sparc/t-elf t-rtems"
tmake_file="sparc/t-elf sparc/t-crtfm t-rtems"
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
#float_format=i128
float_format=i64
@ -2994,22 +3157,23 @@ sparc-*-rtems*|sparc-*-rtemself*)
thread_file='rtems'
fi
;;
sparcv9-*-solaris2* | sparc64-*-solaris2*)
if test x$gnu_ld = xyes
then
tm_file="sparc/sol2-sld-64.h sparc/sol2-64.h"
else
tm_file=sparc/sol2-sld-64.h
sparc64-*-solaris2* | sparcv9-*-solaris2*)
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sol2-64.h sparc/sol2-bi.h"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld.h sparc/sol2-gld-bi.h"
fi
if test x$gas = xyes; then
tm_file="${tm_file} sparc/sol2-gas-bi.h"
fi
xm_defines=POSIX
tmake_file="sparc/t-sol2 sparc/t-sol2-64"
tmake_file="sparc/t-sol2 sparc/t-sol2-64 sparc/t-crtfm"
if test x$gnu_ld = xyes; then
tmake_file="$tmake_file t-slibgcc-elf-ver"
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o"
float_format=none
float_format=i128
if test x${enable_threads} = x ; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x ; then
@ -3027,58 +3191,50 @@ sparcv9-*-solaris2* | sparc64-*-solaris2*)
sparc-hal-solaris2*)
xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/hal.h"
tmake_file="sparc/t-halos sparc/t-sol2"
tmake_file="sparc/t-halos sparc/t-sol2 sparc/t-crtfm"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld.h"
tmake_file="$tmake_file t-slibgcc-elf-ver"
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o"
case $machine in
*-*-solaris2.[0-4])
float_format=i128
;;
*)
float_format=none
;;
esac
float_format=i128
thread_file='solaris'
;;
sparc-*-solaris2*)
if test x$gnu_ld = xyes
then
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h"
else
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sol2-sld.h"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld.h"
fi
xm_defines=POSIX
tmake_file=sparc/t-sol2
tmake_file="sparc/t-sol2 sparc/t-crtfm"
if test x$gnu_ld = xyes; then
tmake_file="$tmake_file t-slibgcc-elf-ver"
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
case $machine in
*-*-solaris2.[0-6] | *-*-solaris2.[0-6].*) ;;
*-*-solaris2*)
if test x$gnu_ld = xyes
then
tm_file="sparc/sol2-sld-64.h sparc/sol2-64.h"
else
tm_file="sparc/sol2-sld-64.h"
*-*-solaris2.[789])
tm_file="sparc/biarch64.h ${tm_file} sparc/sol2-bi.h"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld-bi.h"
fi
if test x$gas = xyes; then
tm_file="${tm_file} sparc/sol2-gas-bi.h"
fi
tmake_file="$tmake_file sparc/t-sol2-64"
;;
esac
case $machine in
*-*-solaris2.[0-4])
float_format=i128
;;
*)
float_format=none
*-*-solaris2.[0-7] | *-*-solaris2.[0-7].*)
if test x$gnu_ld = xno; then
tm_file="${tm_file} sparc/sol27-sld.h"
fi
;;
esac
xm_defines=POSIX
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
float_format=i128
if test x${enable_threads} = x; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x; then
@ -3134,7 +3290,7 @@ sparclite-*-aout*)
;;
sparclite-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h gofast.h sparc/liteelf.h"
tmake_file=sparc/t-sparclite
tmake_file="sparc/t-sparclite sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
;;
sparc86x-*-aout*)
@ -3143,7 +3299,7 @@ sparc86x-*-aout*)
;;
sparc86x-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/elf.h gofast.h sparc/sp86x-elf.h"
tmake_file=sparc/t-sp86x
tmake_file="sparc/t-sp86x sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
;;
sparc64-*-aout*)
@ -3151,18 +3307,21 @@ sparc64-*-aout*)
;;
sparc64-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sp64-elf.h"
tmake_file="${tmake_file} sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
;;
sparc64-*-freebsd*|ultrasparc-*-freebsd*)
tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
tmake_file="${tmake_file} sparc/t-crtfm"
xmake_file=none
case "x$with_cpu" in
xultrasparc) ;;
x) with_cpu=ultrasparc ;;
*) echo "$with_cpu not supported for freebsd target"; exit 1 ;;
esac
;;
sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64"
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64 sparc/t-crtfm"
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
@ -3171,6 +3330,12 @@ sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
fi
float_format=sparc
;;
sparc64-*-netbsd*)
tmake_file="${tmake_file} sparc/t-netbsd64"
tm_file="sparc/biarch64.h ${tm_file}"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
float_format=sparc
;;
strongarm-*-elf*)
tm_file="arm/strongarm-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
tmake_file=arm/t-strongarm-elf
@ -3197,7 +3362,8 @@ thumb*-*-*)
*** when the -mthumb switch is given to the compiler." 1>&2; exit 1; }
;;
v850-*-rtems*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} v850/rtems.h"
xm_defines=POSIX
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} v850/v850.h v850/rtems.h rtems.h"
tmake_file="v850/t-v850 t-rtems"
if test x$stabs = xyes
then
@ -3228,6 +3394,9 @@ vax-*-sysv*) # VAXen running system V
xm_defines=POSIX
float_format=vax
;;
vax-*-netbsdelf*)
echo "GCC does not yet support the ${machine} target"; exit 1
;;
vax-*-netbsd*)
tm_file="${tm_file} netbsd.h netbsd-aout.h vax/netbsd.h"
tmake_file=t-netbsd

View File

@ -1,4 +1,4 @@
/* config.in. Generated automatically from configure.in by autoheader 2.13. */
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
#undef C_ALLOCA
@ -529,8 +529,8 @@
/* Define if your assembler and linker support unaligned PC relative relocs. */
#undef HAVE_AS_SPARC_UA_PCREL
/* Define if the assembler supports 64bit sparc. */
#undef AS_SPARC64_FLAG
/* Define if your assembler and linker support unaligned PC relative relocs against hidden symbols. */
#undef HAVE_AS_SPARC_UA_PCREL_HIDDEN
/* Define if your assembler supports offsetable %lo(). */
#undef HAVE_AS_OFFSETABLE_LO10

View File

@ -59,7 +59,7 @@ extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int some_small_symbolic_mem_operand PARAMS ((rtx, enum machine_mode));
extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int call_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
@ -90,7 +90,7 @@ extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
int, int, int));
extern rtx split_small_symbolic_mem_operand PARAMS ((rtx));
extern rtx split_small_symbolic_operand PARAMS ((rtx));
extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PARAMS ((rtx, int));
@ -163,6 +163,8 @@ extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
#endif
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
extern void alpha_output_mi_thunk_osf PARAMS ((FILE *, tree,
HOST_WIDE_INT, tree));
extern void alpha_encode_section_info PARAMS ((tree));
#endif /* TREE CODE */

View File

@ -46,9 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
/* External data. */
extern int rtx_equal_function_value_matters;
#include "debug.h"
/* Specify which cpu to schedule for. */
@ -116,9 +114,9 @@ int alpha_this_gpdisp_sequence_number;
/* Declarations of static functions. */
static bool decl_in_text_section
PARAMS ((tree));
static int some_small_symbolic_mem_operand_1
static int some_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static int split_small_symbolic_mem_operand_1
static int split_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static bool local_symbol_p
PARAMS ((rtx));
@ -1874,61 +1872,55 @@ alpha_legitimize_address (x, scratch, mode)
so that sched2 has the proper dependency information. */
int
some_small_symbolic_mem_operand (x, mode)
some_small_symbolic_operand (x, mode)
rtx x;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return for_each_rtx (&x, some_small_symbolic_mem_operand_1, NULL);
return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
}
static int
some_small_symbolic_mem_operand_1 (px, data)
some_small_symbolic_operand_1 (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
rtx x = *px;
if (GET_CODE (x) != MEM)
return 0;
x = XEXP (x, 0);
/* Don't re-split. */
if (GET_CODE (x) == LO_SUM)
return -1;
/* If this is an ldq_u type address, discard the outer AND. */
if (GET_CODE (x) == AND)
x = XEXP (x, 0);
return small_symbolic_operand (x, Pmode) ? 1 : -1;
return small_symbolic_operand (x, Pmode) != 0;
}
rtx
split_small_symbolic_mem_operand (x)
split_small_symbolic_operand (x)
rtx x;
{
x = copy_insn (x);
for_each_rtx (&x, split_small_symbolic_mem_operand_1, NULL);
for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
return x;
}
static int
split_small_symbolic_mem_operand_1 (px, data)
split_small_symbolic_operand_1 (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
rtx x = *px;
if (GET_CODE (x) != MEM)
return 0;
px = &XEXP (x, 0), x = *px;
if (GET_CODE (x) == AND)
px = &XEXP (x, 0), x = *px;
/* Don't re-split. */
if (GET_CODE (x) == LO_SUM)
return -1;
if (small_symbolic_operand (x, Pmode))
{
x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
*px = x;
return -1;
}
return -1;
return 0;
}
/* Try a machine-dependent way of reloading an illegitimate address
@ -2236,15 +2228,39 @@ alpha_emit_set_const (target, mode, c, n)
HOST_WIDE_INT c;
int n;
{
rtx pat;
rtx result = 0;
rtx orig_target = target;
int i;
/* If we can't make any pseudos, TARGET is an SImode hard register, we
can't load this constant in one insn, do this in DImode. */
if (no_new_pseudos && mode == SImode
&& GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
&& (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
{
target = gen_lowpart (DImode, target);
mode = DImode;
}
/* Try 1 insn, then 2, then up to N. */
for (i = 1; i <= n; i++)
if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
return pat;
{
result = alpha_emit_set_const_1 (target, mode, c, i);
if (result)
{
rtx insn = get_last_insn ();
rtx set = single_set (insn);
if (! CONSTANT_P (SET_SRC (set)))
set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
break;
}
}
return 0;
/* Allow for the case where we changed the mode of TARGET. */
if (result == target)
result = orig_target;
return result;
}
/* Internal routine for the above to check for N or below insns. */
@ -2260,18 +2276,8 @@ alpha_emit_set_const_1 (target, mode, c, n)
int i, bits;
/* Use a pseudo if highly optimizing and still generating RTL. */
rtx subtarget
= (flag_expensive_optimizations && rtx_equal_function_value_matters
? 0 : target);
rtx temp;
#if HOST_BITS_PER_WIDE_INT == 64
/* We are only called for SImode and DImode. If this is SImode, ensure that
we are sign extended to a full word. This does not make any sense when
cross-compiling on a narrow machine. */
if (mode == SImode)
c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
#endif
= (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
rtx temp, insn;
/* If this is a sign-extended 32-bit constant, we can do this in at most
three insns, so do it if we have enough insns left. We always have
@ -2312,12 +2318,28 @@ alpha_emit_set_const_1 (target, mode, c, n)
{
temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
if (extra != 0)
temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
subtarget, 0, OPTAB_WIDEN);
/* As of 2002-02-23, addsi3 is only available when not optimizing.
This means that if we go through expand_binop, we'll try to
generate extensions, etc, which will require new pseudos, which
will fail during some split phases. The SImode add patterns
still exist, but are not named. So build the insns by hand. */
return expand_binop (mode, add_optab, temp, GEN_INT (low),
target, 0, OPTAB_WIDEN);
if (extra != 0)
{
if (! subtarget)
subtarget = gen_reg_rtx (mode);
insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
insn = gen_rtx_SET (VOIDmode, subtarget, insn);
emit_insn (insn);
temp = subtarget;
}
if (target == NULL)
target = gen_reg_rtx (mode);
insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
insn = gen_rtx_SET (VOIDmode, target, insn);
emit_insn (insn);
return target;
}
}
@ -2326,8 +2348,7 @@ alpha_emit_set_const_1 (target, mode, c, n)
we can't make pseudos, we can't do anything since the expand_binop
and expand_unop calls will widen and try to make pseudos. */
if (n == 1
|| (mode == SImode && ! rtx_equal_function_value_matters))
if (n == 1 || (mode == SImode && no_new_pseudos))
return 0;
/* Next, see if we can load a related constant and then shift and possibly
@ -2508,7 +2529,26 @@ alpha_expand_mov (mode, operands)
/* Allow legitimize_address to perform some simplifications. */
if (mode == Pmode && symbolic_operand (operands[1], mode))
{
rtx tmp = alpha_legitimize_address (operands[1], operands[0], mode);
rtx tmp;
/* With RTL inlining, at -O3, rtl is generated, stored, then actually
compiled at the end of compilation. In the meantime, someone can
re-encode-section-info on some symbol changing it e.g. from global
to local-not-small. If this happens, we'd have emitted a plain
load rather than a high+losum load and not recognize the insn.
So if rtl inlining is in effect, we delay the global/not-global
decision until rest_of_compilation by wrapping it in an
UNSPEC_SYMBOL. */
if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
&& rtx_equal_function_value_matters
&& global_symbolic_operand (operands[1], mode))
{
emit_insn (gen_movdi_er_maybe_g (operands[0], operands[1]));
return true;
}
tmp = alpha_legitimize_address (operands[1], operands[0], mode);
if (tmp)
{
operands[1] = tmp;
@ -2784,21 +2824,29 @@ alpha_emit_conditional_branch (code)
1 true
Convert the compare against the raw return value. */
if (code == UNORDERED || code == ORDERED)
cmp_code = EQ;
else
cmp_code = code;
switch (code)
{
case UNORDERED:
cmp_code = EQ;
code = LT;
break;
case ORDERED:
cmp_code = EQ;
code = GE;
break;
case NE:
cmp_code = NE;
code = NE;
break;
default:
cmp_code = code;
code = GT;
break;
}
op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
op1 = const0_rtx;
alpha_compare.fp_p = 0;
if (code == UNORDERED)
code = LT;
else if (code == ORDERED)
code = GE;
else
code = GT;
}
/* The general case: fold the comparison code to the types of compares
@ -4985,7 +5033,10 @@ alpha_return_addr (count, frame)
rtx
alpha_gp_save_rtx ()
{
return get_hard_reg_initial_val (DImode, 29);
rtx r = get_hard_reg_initial_val (DImode, 29);
if (GET_CODE (r) != MEM)
r = gen_mem_addressof (r, NULL_TREE);
return r;
}
static int
@ -4993,10 +5044,6 @@ alpha_ra_ever_killed ()
{
rtx top;
#ifdef ASM_OUTPUT_MI_THUNK
if (current_function_is_thunk)
return 0;
#endif
if (!has_hard_reg_initial_val (Pmode, REG_RA))
return regs_ever_live[REG_RA];
@ -5512,12 +5559,13 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
OPTAB_WIDEN);
temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
build_int_2 (2, 0), NULL_RTX, 1);
temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
temp = expand_and (SImode, gen_lowpart (SImode, temp),
GEN_INT (0x3fff), 0);
/* Merge in the hint. */
addr = memory_address (SImode, plus_constant (tramp, jmpofs));
temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
OPTAB_WIDEN);
emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
@ -5759,9 +5807,8 @@ rtx
alpha_va_arg (valist, type)
tree valist, type;
{
HOST_WIDE_INT tsize;
rtx addr;
tree t;
tree t, type_size, rounded_size;
tree offset_field, base_field, addr_tree, addend;
tree wide_type, wide_ofs;
int indirect = 0;
@ -5769,7 +5816,18 @@ alpha_va_arg (valist, type)
if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
return std_expand_builtin_va_arg (valist, type);
tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))
rounded_size = size_zero_node;
else
rounded_size = fold (build (MULT_EXPR, sizetype,
fold (build (TRUNC_DIV_EXPR, sizetype,
fold (build (PLUS_EXPR, sizetype,
type_size,
size_int (7))),
size_int (8))),
size_int (8)));
base_field = TYPE_FIELDS (TREE_TYPE (valist));
offset_field = TREE_CHAIN (base_field);
@ -5779,6 +5837,17 @@ alpha_va_arg (valist, type)
offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
valist, offset_field);
/* If the type could not be passed in registers, skip the block
reserved for the registers. */
if (MUST_PASS_IN_STACK (TYPE_MODE (type), type))
{
t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
build (MAX_EXPR, TREE_TYPE (offset_field),
offset_field, build_int_2 (6*8, 0)));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
wide_type = make_signed_type (64);
wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
@ -5787,7 +5856,7 @@ alpha_va_arg (valist, type)
if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode)
{
indirect = 1;
tsize = UNITS_PER_WORD;
rounded_size = size_int (UNITS_PER_WORD);
}
else if (FLOAT_TYPE_P (type))
{
@ -5811,7 +5880,7 @@ alpha_va_arg (valist, type)
t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
build (PLUS_EXPR, TREE_TYPE (offset_field),
offset_field, build_int_2 (tsize, 0)));
offset_field, rounded_size));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@ -5835,7 +5904,8 @@ alpha_va_arg (valist, type)
descriptior to generate. */
/* Nonzero if we need a stack procedure. */
static int alpha_is_stack_procedure;
enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
static enum alpha_procedure_types alpha_procedure_type;
/* Register number (either FP or SP) that is used to unwind the frame. */
static int vms_unwind_regno;
@ -5859,44 +5929,49 @@ alpha_sa_mask (imaskP, fmaskP)
unsigned long fmask = 0;
unsigned int i;
#ifdef ASM_OUTPUT_MI_THUNK
if (!current_function_is_thunk)
#endif
/* Irritatingly, there are two kinds of thunks -- those created with
ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go through
the regular part of the compiler. In the ASM_OUTPUT_MI_THUNK case
we don't have valid register life info, but assemble_start_function
wants to output .frame and .mask directives. */
if (current_function_is_thunk && !no_new_pseudos)
{
if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
imask |= (1L << HARD_FRAME_POINTER_REGNUM);
/* One for every register we have to save. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! fixed_regs[i] && ! call_used_regs[i]
&& regs_ever_live[i] && i != REG_RA
&& (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
{
if (i < 32)
imask |= (1L << i);
else
fmask |= (1L << (i - 32));
}
/* We need to restore these for the handler. */
if (current_function_calls_eh_return)
{
for (i = 0; ; ++i)
{
unsigned regno = EH_RETURN_DATA_REGNO (i);
if (regno == INVALID_REGNUM)
break;
imask |= 1L << regno;
}
}
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
if (imask || fmask || alpha_ra_ever_killed ())
imask |= (1L << REG_RA);
*imaskP = 0;
*fmaskP = 0;
return;
}
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
imask |= (1L << HARD_FRAME_POINTER_REGNUM);
/* One for every register we have to save. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! fixed_regs[i] && ! call_used_regs[i]
&& regs_ever_live[i] && i != REG_RA
&& (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
{
if (i < 32)
imask |= (1L << i);
else
fmask |= (1L << (i - 32));
}
/* We need to restore these for the handler. */
if (current_function_calls_eh_return)
for (i = 0; ; ++i)
{
unsigned regno = EH_RETURN_DATA_REGNO (i);
if (regno == INVALID_REGNUM)
break;
imask |= 1L << regno;
}
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
if (imask || fmask || alpha_ra_ever_killed ())
imask |= (1L << REG_RA);
*imaskP = imask;
*fmaskP = fmask;
}
@ -5931,17 +6006,16 @@ alpha_sa_size ()
use alloca and have not determined that we need a frame for other
reasons. */
alpha_is_stack_procedure = (sa_size
|| get_frame_size() != 0
|| current_function_outgoing_args_size
|| current_function_varargs
|| current_function_stdarg
|| current_function_calls_alloca
|| frame_pointer_needed);
alpha_procedure_type
= (sa_size || get_frame_size() != 0
|| current_function_outgoing_args_size || current_function_varargs
|| current_function_stdarg || current_function_calls_alloca
|| frame_pointer_needed)
? PT_STACK : PT_REGISTER;
/* Always reserve space for saving callee-saved registers if we
need a frame as required by the calling convention. */
if (alpha_is_stack_procedure)
if (alpha_procedure_type == PT_STACK)
sa_size = 14;
}
else if (TARGET_ABI_OPEN_VMS)
@ -5949,22 +6023,29 @@ alpha_sa_size ()
/* Start by assuming we can use a register procedure if we don't
make any calls (REG_RA not used) or need to save any
registers and a stack procedure if we do. */
alpha_is_stack_procedure = ((mask[0] >> REG_RA) & 1);
if ((mask[0] >> REG_RA) & 1)
alpha_procedure_type = PT_STACK;
else if (get_frame_size() != 0)
alpha_procedure_type = PT_REGISTER;
else
alpha_procedure_type = PT_NULL;
/* Don't reserve space for saving RA yet. Do that later after we've
/* Don't reserve space for saving FP & RA yet. Do that later after we've
made the final decision on stack procedure vs register procedure. */
if (alpha_is_stack_procedure)
sa_size--;
if (alpha_procedure_type == PT_STACK)
sa_size -= 2;
/* Decide whether to refer to objects off our PV via FP or PV.
If we need FP for something else or if we receive a nonlocal
goto (which expects PV to contain the value), we must use PV.
Otherwise, start by assuming we can use FP. */
vms_base_regno = (frame_pointer_needed
|| current_function_has_nonlocal_label
|| alpha_is_stack_procedure
|| current_function_outgoing_args_size
? REG_PV : HARD_FRAME_POINTER_REGNUM);
vms_base_regno
= (frame_pointer_needed
|| current_function_has_nonlocal_label
|| alpha_procedure_type == PT_STACK
|| current_function_outgoing_args_size)
? REG_PV : HARD_FRAME_POINTER_REGNUM;
/* If we want to copy PV into FP, we need to find some register
in which to save FP. */
@ -5975,15 +6056,17 @@ alpha_sa_size ()
if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
vms_save_fp_regno = i;
if (vms_save_fp_regno == -1)
vms_base_regno = REG_PV, alpha_is_stack_procedure = 1;
if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
else if (alpha_procedure_type == PT_NULL)
vms_base_regno = REG_PV;
/* Stack unwinding should be done via FP unless we use it for PV. */
vms_unwind_regno = (vms_base_regno == REG_PV
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
/* If this is a stack procedure, allow space for saving FP and RA. */
if (alpha_is_stack_procedure)
if (alpha_procedure_type == PT_STACK)
sa_size += 2;
}
else
@ -6000,7 +6083,7 @@ int
alpha_pv_save_size ()
{
alpha_sa_size ();
return alpha_is_stack_procedure ? 8 : 0;
return alpha_procedure_type == PT_STACK ? 8 : 0;
}
int
@ -6043,10 +6126,8 @@ alpha_does_function_need_gp ()
if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
return 1;
#ifdef ASM_OUTPUT_MI_THUNK
if (current_function_is_thunk)
return 1;
#endif
/* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
Even if we are a static function, we still need to do this in case
@ -6151,13 +6232,13 @@ alpha_expand_prologue ()
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 8 : 0)
+ (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
/* We have to allocate space for the DSIB if we generate a frame. */
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 48 : 0))
+ (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@ -6312,7 +6393,7 @@ alpha_expand_prologue ()
}
/* Save regs in stack order. Beginning with VMS PV. */
if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
{
mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
set_mem_alias_set (mem, alpha_sr_alias_set);
@ -6348,7 +6429,7 @@ alpha_expand_prologue ()
reg_offset += 8;
}
}
else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
{
/* The standard frame on the T3E includes space for saving registers.
We just have to use it. We don't have to save the return address and
@ -6377,17 +6458,18 @@ alpha_expand_prologue ()
if (TARGET_ABI_OPEN_VMS)
{
if (!alpha_is_stack_procedure)
/* Register frame procedures save the fp. */
/* ??? Ought to have a dwarf2 save for this. */
if (alpha_procedure_type == PT_REGISTER)
/* Register frame procedures save the fp.
?? Ought to have a dwarf2 save for this. */
emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
hard_frame_pointer_rtx);
if (vms_base_regno != REG_PV)
if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
gen_rtx_REG (DImode, REG_PV)));
if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
if (alpha_procedure_type != PT_NULL
&& vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
/* If we have to allocate space for outgoing args, do it now. */
@ -6460,12 +6542,12 @@ alpha_start_function (file, fnname, decl)
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 8 : 0)
+ (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 48 : 0))
+ (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@ -6512,7 +6594,9 @@ alpha_start_function (file, fnname, decl)
/* If the function needs GP, we'll write the "..ng" label there.
Otherwise, do it here. */
if (TARGET_ABI_OSF && ! alpha_function_needs_gp)
if (TARGET_ABI_OSF
&& ! alpha_function_needs_gp
&& ! current_function_is_thunk)
{
putc ('$', file);
assemble_name (file, fnname);
@ -6583,7 +6667,7 @@ alpha_start_function (file, fnname, decl)
fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
if (fmask)
fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
if (!alpha_is_stack_procedure)
if (alpha_procedure_type == PT_REGISTER)
fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
}
else if (!flag_inhibit_size_directive)
@ -6627,7 +6711,9 @@ alpha_start_function (file, fnname, decl)
ASM_OUTPUT_LABEL (file, fnname);
fprintf (file, "\t.pdesc ");
assemble_name (file, fnname);
fprintf (file, "..en,%s\n", alpha_is_stack_procedure ? "stack" : "reg");
fprintf (file, "..en,%s\n",
alpha_procedure_type == PT_STACK ? "stack"
: alpha_procedure_type == PT_REGISTER ? "reg" : "null");
alpha_need_linkage (fnname, 1);
text_section ();
#endif
@ -6646,7 +6732,8 @@ alpha_output_function_end_prologue (file)
else if (TARGET_ABI_WINDOWS_NT)
fputs ("\t.prologue 0\n", file);
else if (!flag_inhibit_size_directive)
fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
fprintf (file, "\t.prologue %d\n",
alpha_function_needs_gp || current_function_is_thunk);
}
/* Write function epilogue. */
@ -6680,12 +6767,12 @@ alpha_expand_epilogue ()
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 8 : 0)
+ (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_is_stack_procedure ? 48 : 0))
+ (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@ -6695,14 +6782,20 @@ alpha_expand_epilogue ()
+ current_function_pretend_args_size));
if (TARGET_ABI_OPEN_VMS)
reg_offset = 8;
{
if (alpha_procedure_type == PT_STACK)
reg_offset = 8;
else
reg_offset = 0;
}
else
reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
alpha_sa_mask (&imask, &fmask);
fp_is_frame_pointer = ((TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
|| (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
fp_is_frame_pointer
= ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
|| (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
fp_offset = 0;
sa_reg = stack_pointer_rtx;
@ -6769,7 +6862,7 @@ alpha_expand_epilogue ()
reg_offset += 8;
}
}
else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
{
/* Restore callee-saved general-purpose registers. */
@ -6889,13 +6982,13 @@ alpha_expand_epilogue ()
}
else
{
if (TARGET_ABI_OPEN_VMS && !alpha_is_stack_procedure)
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
{
emit_insn (gen_blockage ());
FRP (emit_move_insn (hard_frame_pointer_rtx,
gen_rtx_REG (DImode, vms_save_fp_regno)));
}
else if (TARGET_ABI_UNICOSMK && !alpha_is_stack_procedure)
else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
{
/* Decrement the frame pointer if the function does not have a
frame. */
@ -6946,6 +7039,76 @@ alpha_end_function (file, fnname, decl)
unicosmk_output_deferred_case_vectors (file);
}
}
/* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
In order to avoid the hordes of differences between generated code
with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
lots of code loading up large constants, generate rtl and emit it
instead of going straight to text.
Not sure why this idea hasn't been explored before... */
void
alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, function)
FILE *file;
tree thunk_fndecl ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
tree function;
{
HOST_WIDE_INT hi, lo;
rtx this, insn, funexp;
/* We always require a valid GP. */
emit_insn (gen_prologue_ldgp ());
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. If the function returns a structure,
the structure return pointer is in $16. */
if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
this = gen_rtx_REG (Pmode, 17);
else
this = gen_rtx_REG (Pmode, 16);
/* Add DELTA. When possible we use ldah+lda. Otherwise load the
entire constant for the add. */
lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
if (hi + lo == delta)
{
if (hi)
emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
if (lo)
emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
}
else
{
rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
delta, -(delta < 0));
emit_insn (gen_adddi3 (this, this, tmp));
}
/* Generate a tail call to the target function. */
if (! TREE_USED (function))
{
assemble_external (function);
TREE_USED (function) = 1;
}
funexp = XEXP (DECL_RTL (function), 0);
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
SIBLING_CALL_P (insn) = 1;
/* Run just enough of rest_of_compilation to get the insns emitted.
There's not really enough bulk here to make other passes such as
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
}
/* Debugging support. */
@ -8628,7 +8791,7 @@ static void
unicosmk_gen_dsib (imaskP)
unsigned long * imaskP;
{
if (alpha_is_stack_procedure)
if (alpha_procedure_type == PT_STACK)
{
const char *ssib_name;
rtx mem;

View File

@ -43,12 +43,6 @@ Boston, MA 02111-1307, USA. */
#define CPP_SUBTARGET_SPEC ""
#endif
/* Set the spec to use for signed char. The default tests the above macro
but DEC's compiler can't handle the conditional in a "constant"
operand. */
#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "rpath") || DEFAULT_WORD_SWITCH_TAKES_ARG(STR))
@ -2079,7 +2073,8 @@ do { \
{"reg_no_subreg_operand", {REG}}, \
{"addition_operation", {PLUS}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"some_small_symbolic_mem_operand", {SET, PARALLEL}},
{"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
UNSPEC_VOLATILE}},
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \
@ -2242,3 +2237,8 @@ do { \
/* Generate calls to memcpy, etc., not bcopy, etc. */
#define TARGET_MEM_FUNCTIONS 1
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
alpha_output_mi_thunk_osf (FILE, THUNK_FNDECL, DELTA, FUNCTION)

View File

@ -39,6 +39,7 @@
(UNSPEC_LITERAL 11)
(UNSPEC_LITUSE 12)
(UNSPEC_SIBCALL 13)
(UNSPEC_SYMBOL 14)
])
;; UNSPEC_VOLATILE:
@ -518,31 +519,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(sign_extend:DI (match_dup 1)))]
"")
;; Do addsi3 the way expand_binop would do if we didn't have one. This
;; generates better code. We have the anonymous addsi3 pattern below in
;; case combine wants to make it.
;; Don't say we have addsi3 if optimizing. This generates better code. We
;; have the anonymous addsi3 pattern below in case combine wants to make it.
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "add_operand" "")))]
""
{
if (optimize)
{
rtx op1 = gen_lowpart (DImode, operands[1]);
rtx op2 = gen_lowpart (DImode, operands[2]);
if (! cse_not_expected)
{
rtx tmp = gen_reg_rtx (DImode);
emit_insn (gen_adddi3 (tmp, op1, op2));
emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
}
else
emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
DONE;
}
})
"! optimize"
"")
(define_insn "*addsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@ -581,6 +565,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
addl %r1,%2,%0
subl %r1,%n2,%0")
(define_insn "*addsi_se2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
(subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
(match_operand:DI 2 "sext_add_operand" "rI,O"))
0)))]
""
"@
addl %r1,%2,%0
subl %r1,%n2,%0")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(sign_extend:DI
@ -844,24 +839,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_8bit_operand" "")))]
""
{
if (optimize)
{
rtx op1 = gen_lowpart (DImode, operands[1]);
rtx op2 = gen_lowpart (DImode, operands[2]);
if (! cse_not_expected)
{
rtx tmp = gen_reg_rtx (DImode);
emit_insn (gen_subdi3 (tmp, op1, op2));
emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
}
else
emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
DONE;
}
})
"! optimize"
"")
(define_insn "*subsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
@ -877,6 +856,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
""
"subl %r1,%2,%0")
(define_insn "*subsi_se2"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rI"))
0)))]
""
"subl %r1,%2,%0")
(define_insn "subvsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
@ -1610,23 +1598,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
}
[(set_attr "type" "iadd,shift")])
;; ??? The following pattern is made by combine, but earlier phases
;; (specifically flow) can't handle it. This occurs in jump.c. Deal
;; with this in a better way at some point.
;;(define_insn ""
;; [(set (match_operand:DI 0 "register_operand" "=r")
;; (sign_extend:DI
;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
;; (match_operand:DI 2 "const_int_operand" "P"))
;; 0)))]
;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
;;{
;; if (operands[2] == const1_rtx)
;; return "addl %r1,%r1,%0";
;; else
;; return "s%P2addl %r1,0,%0";
;;}
;; [(set_attr "type" "iadd")])
(define_insn "*ashldi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
(subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "const_int_operand" "P"))
0)))]
"INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
{
if (operands[2] == const1_rtx)
return "addl %r1,%r1,%0";
else
return "s%P2addl %r1,0,%0";
}
[(set_attr "type" "iadd")])
(define_insn "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
@ -5111,6 +5096,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
""
"call_pal 0x86"
[(set_attr "type" "ibr")])
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
;; NT does not document anything at 0x81 -- presumably it would generate
;; the equivalent of SIGILL, but this isn't that important.
;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
"!TARGET_ABI_WINDOWS_NT"
"call_pal 0x81"
[(set_attr "type" "ibr")])
;; Finally, we have the basic data motion insns. The byte and word insns
;; are done via define_expand. Start with the floating-point insns, since
@ -5292,10 +5287,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
itofs %1,%0"
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "*movsi_nt_vms"
(define_insn "*movsi_nt_vms_nofix"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
&& !TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@ -5310,6 +5306,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
st%, %R1,%0"
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
(define_insn "*movsi_nt_vms_fix"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
&& TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
bis $31,%1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldl %0,%1
stl %r1,%0
cpys %R1,%R1,%0
ld%, %0,%1
st%, %R1,%0
ftois %1,%0
itofs %1,%0"
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "*movhi_nobwx"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_operand:HI 1 "input_operand" "rJ,n"))]
@ -5501,10 +5518,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"operands[2] = pic_offset_table_rtx;")
(define_split
[(match_operand 0 "some_small_symbolic_mem_operand" "")]
[(match_operand 0 "some_small_symbolic_operand" "")]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(match_dup 0)]
"operands[0] = split_small_symbolic_mem_operand (operands[0]);")
"operands[0] = split_small_symbolic_operand (operands[0]);")
(define_insn "movdi_er_high_g"
[(set (match_operand:DI 0 "register_operand" "=r")
@ -5531,6 +5548,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_int 0)] UNSPEC_LITERAL))]
"operands[2] = pic_offset_table_rtx;")
;; With RTL inlining, at -O3, rtl is generated, stored, then actually
;; compiled at the end of compilation. In the meantime, someone can
;; re-encode-section-info on some symbol changing it e.g. from global
;; to local-not-small. If this happens, we'd have emitted a plain
;; load rather than a high+losum load and not recognize the insn.
;;
;; So if rtl inlining is in effect, we delay the global/not-global
;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL.
(define_insn_and_split "movdi_er_maybe_g"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
UNSPEC_SYMBOL))]
"TARGET_EXPLICIT_RELOCS && flag_inline_functions"
"#"
""
[(set (match_dup 0) (match_dup 1))]
{
if (local_symbolic_operand (operands[1], Pmode)
&& !small_symbolic_operand (operands[1], Pmode))
{
rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
rtx tmp;
tmp = gen_rtx_HIGH (Pmode, operands[1]);
if (reload_completed)
tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]);
emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
DONE;
}
})
(define_insn "*movdi_er_nofix"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
@ -6700,13 +6752,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(set_attr "type" "multi")])
(define_insn "*exception_receiver_2"
[(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
UNSPECV_EHR)]
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
"TARGET_LD_BUGGY_LDGP"
"@
bis $31,%0,$29
ldq $29,%0"
[(set_attr "type" "ilog,ild")])
"ldq $29,%0"
[(set_attr "type" "ild")])
(define_expand "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)

View File

@ -168,6 +168,16 @@ do { \
ASM_OUTPUT_SKIP((FILE), (SIZE)); \
} while (0)
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
ASM_GLOBALIZE_LABEL (FILE, NAME); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
/* Biggest alignment supported by the object file format of this
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
@ -473,11 +483,32 @@ do { \
/* This is how we tell the assembler that two symbols have the same value. */
#undef ASM_OUTPUT_DEF
#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
do { assemble_name(FILE, NAME1); \
fputs(" = ", FILE); \
assemble_name(FILE, NAME2); \
fputc('\n', FILE); } while (0)
#define ASM_OUTPUT_DEF(FILE, ALIAS, NAME) \
do { \
assemble_name(FILE, ALIAS); \
fputs(" = ", FILE); \
assemble_name(FILE, NAME); \
fputc('\n', FILE); \
} while (0)
#undef ASM_OUTPUT_DEF_FROM_DECLS
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
do { \
const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
const char *name = IDENTIFIER_POINTER (TARGET); \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
{ \
fputc ('$', FILE); \
assemble_name (FILE, alias); \
fputs ("..ng = $", FILE); \
assemble_name (FILE, name); \
fputs ("..ng\n", FILE); \
} \
assemble_name(FILE, alias); \
fputs(" = ", FILE); \
assemble_name(FILE, name); \
fputc('\n', FILE); \
} while (0)
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
@ -602,17 +633,14 @@ do { \
/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
(even more) magical crtbegin.o file which provides part of the
support for getting C++ file-scope static object constructed
before entering `main'.
before entering `main'. */
Don't bother seeing crtstuff.c -- there is absolutely no hope
of getting that file to understand multiple GPs. We provide a
hand-coded assembly version. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
crti.o%s %{shared:crtbeginS.o%s}%{!shared:crtbegin.o%s}"
crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{shared:crtbeginS.o%s}%{!shared:crtbegin.o%s}}"
/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the
magical crtend.o file which provides part of the support for

View File

@ -1,5 +1,5 @@
/* Definitions for DEC Alpha/AXP running FreeBSD using the ELF format
Copyright (C) 2000 Free Software Foundation, Inc.
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
This file is part of GNU CC.
@ -25,14 +25,14 @@ Boston, MA 02111-1307, USA. */
deal with the Alpha's FP issues. */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) \
#define CPP_SPEC "%(cpp_cpu) %(cpp_subtarget) -D__ELF__ \
%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} \
%{mieee:-D_IEEE_FP} \
%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT}"
#undef LINK_SPEC
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
#define LINK_SPEC "%{G*} %{relax:-relax} \
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
@ -44,16 +44,6 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-Bstatic}}"
/* Provide an ASM_SPEC appropriate for a FreeBSD/Alpha target. This differs
from the generic FreeBSD ASM_SPEC in that no special handling of PIC is
necessary on the Alpha. */
/* Per Richard Henderson <rth@cygnus.com>, it is better to use the `.arch'
directive in the assembly file. alpha/elf.h gives us this in
"ASM_FILE_START".
#undef ASM_SPEC
#define ASM_SPEC " %| %{mcpu=*:-m%*}"
*/
/************************[ Target stuff ]***********************************/
@ -65,18 +55,18 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#define WCHAR_TYPE_SIZE 32
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/alpha ELF)");
#define TARGET_ELF 1
#define TARGET_ELF 1
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#undef HAS_INIT_SECTION
@ -89,3 +79,9 @@ Boston, MA 02111-1307, USA. */
#undef DBX_CONTIN_CHAR
#define DBX_CONTIN_CHAR '?'
/* Don't default to pcc-struct-return, we want to retain compatibility with
older FreeBSD releases AND pcc-struct-return may not be reentrant. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0

View File

@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
Contributed by Richard Henderson.
This file is part of GNU CC.
@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
"-D__gnu_linux__ -Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
SUB_CPP_PREDEFINES
/* The GNU C++ standard library requires that these macros be defined. */

View File

@ -79,19 +79,5 @@ Boston, MA 02111-1307, USA. */
%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
/* Make gcc agree with <machine/ansi.h> */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#undef WINT_TYPE
#define WINT_TYPE "int"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NetBSD/alpha ELF)");

View File

@ -47,7 +47,8 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC \
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat)"
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat) \
-D__EXTERN_PREFIX"
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
@ -56,12 +57,13 @@ Boston, MA 02111-1307, USA. */
%{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc"
/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
optimizing, -O1 if we are not. Pass -shared, -non_shared or
optimizing, -O1 if we are not. Pass -S to silence `weak symbol
multiply defined' warnings. Pass -shared, -non_shared or
-call_shared as appropriate. Pass -hidden_symbol so that our
constructor and call-frame data structures are not accidentally
overridden. */
#define LINK_SPEC \
"-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
"-G 8 %{O*:-O3} %{!O*:-O1} -S %{static:-non_shared} \
%{!static:%{shared:-shared -hidden_symbol _GLOBAL_*} \
%{!shared:-call_shared}} %{pg} %{taso} %{rpath*}"
@ -93,19 +95,18 @@ Boston, MA 02111-1307, USA. */
#define ASM_OLDAS_SPEC ""
/* No point in running CPP on our assembler output. */
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
/* Don't pass -g to GNU as, because some versions don't accept this option. */
#define ASM_SPEC "%{malpha-as:-g %(asm_oldas)} -nocpp %{pg}"
#else
/* In OSF/1 v3.2c, the assembler by default does not output file names which
causes mips-tfile to fail. Passing -g to the assembler fixes this problem.
??? Strictly speaking, we need -g only if the user specifies -g. Passing
it always means that we get slightly larger than necessary object files
if the user does not specify -g. If we don't pass -g, then mips-tfile
will need to be fixed to work in this case. Pass -O0 since some
optimization are broken and don't help us anyway. */
#define ASM_SPEC "%{!mgas:-g %(asm_oldas)} -nocpp %{pg} -O0"
optimization are broken and don't help us anyway. Pass -nocpp because
there's no point in running CPP on our assembler output. */
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
#define ASM_SPEC "%{malpha-as:-g %(asm_oldas) -nocpp %{pg} -O0}"
#else
#define ASM_SPEC "%{!mgas:-g %(asm_oldas) -nocpp %{pg} -O0}"
#endif
/* Specify to run a post-processor, mips-tfile after the assembler
@ -209,3 +210,7 @@ __enable_execute_stack (addr) \
/* Handle #pragma weak and #pragma pack. */
#undef HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA 1
/* Handle #pragma extern_prefix. Technically only needed for Tru64 5.x,
but easier to manipulate preprocessor bits from here. */
#define HANDLE_PRAGMA_EXTERN_PREFIX 1

View File

@ -20,3 +20,7 @@ vcrt0.o: $(CRT0_S) $(GCC_PASSES)
pcrt0.o: $(CRT0_S) $(GCC_PASSES)
decc -c /names=as_is $(srcdir)/config/alpha/vms-psxcrt0.c -o pcrt0.o
MULTILIB_OPTIONS = mcpu=ev6
MULTILIB_DIRNAMES = ev6
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib

View File

@ -251,6 +251,12 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
{ \
fprintf (FILE, "\t.arch %s\n", \
(TARGET_CPU_EV6 ? "ev6" \
: TARGET_MAX ? "pca56" : "ev56")); \
} \
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
@ -385,22 +391,14 @@ do { \
#define LINK_EH_SPEC "vms-dwarf2eh.o%s "
#ifdef IN_LIBGCC2
#include <libicb.h>
#include <pdscdef.h>
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned long handle; \
PDSCDEF *pv; \
INVO_CONTEXT_BLK invo; \
PDSCDEF *pv = *((PDSCDEF **) (CONTEXT)->reg [29]); \
\
memset (&invo, 0, sizeof (INVO_CONTEXT_BLK)); \
\
invo.libicb$q_ireg [29] = *((long long *) (CONTEXT)->reg [29]); \
invo.libicb$q_ireg [30] = (long long) (CONTEXT)->cfa; \
handle = LIB$GET_INVO_HANDLE (&invo); \
LIB$GET_INVO_CONTEXT (handle, &invo); \
pv = (PDSCDEF *) invo.libicb$ph_procedure_descriptor; \
if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */ \
pv = *(PDSCDEF **) pv; \
\
if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK)) \
{ \
@ -426,6 +424,19 @@ do { \
\
goto SUCCESS; \
} \
else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER)) \
{ \
(FS)->cfa_offset = pv->pdsc$l_size; \
(FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
(FS)->retaddr_column = 26; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->regs.reg[26].loc.reg = pv->pdsc$b_save_ra; \
(FS)->regs.reg[26].how = REG_SAVED_REG; \
(FS)->regs.reg[29].loc.reg = pv->pdsc$b_save_fp; \
(FS)->regs.reg[29].how = REG_SAVED_REG; \
\
goto SUCCESS; \
} \
} while (0)
#endif
@ -508,11 +519,17 @@ do { \
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
#define MD_EXEC_PREFIX "/gnu/lib/gcc-lib/"
#define MD_STARTFILE_PREFIX "/gnu/lib/gcc-lib/"
/* Specify the list of include file directories. */
#define INCLUDE_DEFAULTS \
{ \
{ "/gnu_gxx_include", 0, 1, 1 }, \
{ "/gnu_cc_include", 0, 0, 0 }, \
{ "/gnu/include", 0, 0, 0 }, \
{ 0, 0, 0, 0 } \
#define INCLUDE_DEFAULTS \
{ \
{ "/gnu/lib/gcc-lib/include", 0, 0, 0 }, \
{ "/gnu_gxx_include", 0, 1, 1 }, \
{ "/gnu_cc_include", 0, 0, 0 }, \
{ "/gnu/include", 0, 0, 0 }, \
{ 0, 0, 0, 0 } \
}
#define LONGLONG_STANDALONE 1

View File

@ -1,6 +1,8 @@
# Under VMS, directory names cannot contain dots.
version:=$(shell echo $(gcc_version) | sed -e 's/\./_/g')
libsubdir=$(libdir)/gcc-lib
# Rules for linker and compiler wrappers. These are only useful on
# a VMS host.
EXTRA_PROGRAMS=ld.exe decc.exe

View File

@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */
/* Open files in stream mode if not otherwise explicitly specified */
#define __UNIX_FOPEN 1
/* Write to stdout using fputc to avoid record terminators in pipes */
#define __UNIX_FWRITE 1
#define STDC_HEADERS 1
#define HOST_EXECUTABLE_SUFFIX ".exe"

View File

@ -120,6 +120,10 @@ do { \
(*ptr++) (); \
} while (0)
/* We really want to put Thumb tables in a read-only data section, but
switching to another section during function output is not
possible. We could however do what the SPARC does and defer the
whole table generation until the end of the function. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
#ifndef ARM_OS_NAME
@ -322,8 +326,13 @@ do { \
/* Output of Dispatch Tables */
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE))
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
do { \
if (TARGET_ARM) \
fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
else \
fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
} while (0)
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))

View File

@ -181,8 +181,16 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE)
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
do \
{ \
if (TARGET_ARM) \
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE); \
else \
asm_fprintf (STREAM, "\t.word\t%LL%d-%LL%d\n", VALUE, REL); \
} \
while (0)
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \

View File

@ -266,12 +266,9 @@ int thumb_code = 0;
PRINT_OPERAND_ADDRESS. */
enum machine_mode output_memory_reference_mode;
/* Nonzero if the prologue must setup `fp'. */
int current_function_anonymous_args;
/* The register number to be used for the PIC offset register. */
const char * arm_pic_register_string = NULL;
int arm_pic_register = 9;
int arm_pic_register = INVALID_REGNUM;
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
@ -654,8 +651,8 @@ arm_override_options ()
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */
if (flag_pic && !TARGET_APCS_STACK)
arm_pic_register = 10;
if (flag_pic)
arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
if (TARGET_APCS_FLOAT)
warning ("passing floating point arguments in fp regs not yet supported");
@ -716,18 +713,16 @@ arm_override_options ()
if (arm_pic_register_string != NULL)
{
int pic_register;
int pic_register = decode_reg_name (arm_pic_register_string);
if (!flag_pic)
warning ("-mpic-register= is useless without -fpic");
pic_register = decode_reg_name (arm_pic_register_string);
/* Prevent the user from choosing an obviously stupid PIC register. */
if (pic_register < 0 || call_used_regs[pic_register]
|| pic_register == HARD_FRAME_POINTER_REGNUM
|| pic_register == STACK_POINTER_REGNUM
|| pic_register >= PC_REGNUM)
else if (pic_register < 0 || call_used_regs[pic_register]
|| pic_register == HARD_FRAME_POINTER_REGNUM
|| pic_register == STACK_POINTER_REGNUM
|| pic_register >= PC_REGNUM)
error ("unable to use '%s' for PIC register", arm_pic_register_string);
else
arm_pic_register = pic_register;
@ -902,14 +897,14 @@ use_return_insn (iscond)
func_type = arm_current_func_type ();
/* Naked functions, volatile functiond and interrupt
functions all need special consideration. */
if (func_type & (ARM_FT_INTERRUPT | ARM_FT_VOLATILE | ARM_FT_NAKED))
/* Naked functions and volatile functions need special
consideration. */
if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED))
return 0;
/* As do variadic functions. */
if (current_function_pretend_args_size
|| current_function_anonymous_args
|| cfun->machine->uses_anonymous_args
/* Of if the function calls __builtin_eh_return () */
|| ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
/* Or if there is no frame pointer and there is a stack adjustment. */
@ -2102,9 +2097,6 @@ arm_encode_call_attribute (decl, flag)
int len = strlen (str);
char * newstr;
if (TREE_CODE (decl) != FUNCTION_DECL)
return;
/* Do not allow weak functions to be treated as short call. */
if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
return;
@ -2318,7 +2310,10 @@ legitimize_pic_address (orig, mode, reg)
else
emit_insn (gen_pic_load_addr_thumb (address, orig));
if (GET_CODE (orig) == LABEL_REF && NEED_GOT_RELOC)
if ((GET_CODE (orig) == LABEL_REF
|| (GET_CODE (orig) == SYMBOL_REF &&
ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
&& NEED_GOT_RELOC)
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
else
{
@ -5334,14 +5329,29 @@ is_jump_table (insn)
return NULL_RTX;
}
#ifndef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 0
#endif
static HOST_WIDE_INT
get_jump_table_size (insn)
rtx insn;
{
rtx body = PATTERN (insn);
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
/* ADDR_VECs only take room if read-only data does into the text
section. */
if (JUMP_TABLES_IN_TEXT_SECTION
#if !defined(READONLY_DATA_SECTION)
|| 1
#endif
)
{
rtx body = PATTERN (insn);
int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
}
return 0;
}
/* Move a minipool fix MP from its current location to before MAX_MP.
@ -7139,17 +7149,16 @@ arm_compute_save_reg_mask ()
/* Decide if we need to save the link register.
Interrupt routines have their own banked link register,
so they never need to save it.
Otheriwse if we do not use the link register we do not need to save
Otherwise if we do not use the link register we do not need to save
it. If we are pushing other registers onto the stack however, we
can save an instruction in the epilogue by pushing the link register
now and then popping it back into the PC. This incurs extra memory
accesses though, so we only do it when optimising for size, and only
if we know that we will not need a fancy return sequence. */
if (! IS_INTERRUPT (func_type)
&& (regs_ever_live [LR_REGNUM]
if (regs_ever_live [LR_REGNUM]
|| (save_reg_mask
&& optimize_size
&& ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)))
&& ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL))
save_reg_mask |= 1 << LR_REGNUM;
if (cfun->machine->lr_save_eliminated)
@ -7207,21 +7216,19 @@ output_return_instruction (operand, really_return, reverse)
live_regs_mask = arm_compute_save_reg_mask ();
/* On some ARM architectures it is faster to use LDR rather than LDM to
load a single register. On other architectures, the cost is the same.
In 26 bit mode we have to use LDM in order to be able to restore the CPSR. */
if ((live_regs_mask == (1 << LR_REGNUM))
&& ! TARGET_INTERWORK
&& ! IS_INTERRUPT (func_type)
&& (! really_return || TARGET_APCS_32))
if (live_regs_mask)
{
if (! really_return)
sprintf (instr, "ldr%s\t%%|lr, [%%|sp], #4", conditional);
const char * return_reg;
/* If we do not have any special requirements for function exit
(eg interworking, or ISR) then we can load the return address
directly into the PC. Otherwise we must load it into LR. */
if (really_return
&& ! TARGET_INTERWORK)
return_reg = reg_names[PC_REGNUM];
else
sprintf (instr, "ldr%s\t%%|pc, [%%|sp], #4", conditional);
}
else if (live_regs_mask)
{
return_reg = reg_names[LR_REGNUM];
if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
/* There are two possible reasons for the IP register being saved.
Either a stack frame was created, in which case IP contains the
@ -7233,96 +7240,91 @@ output_return_instruction (operand, really_return, reverse)
live_regs_mask |= (1 << SP_REGNUM);
}
/* Generate the load multiple instruction to restore the registers. */
if (frame_pointer_needed)
sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
else
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
for (reg = 0; reg <= SP_REGNUM; reg++)
if (live_regs_mask & (1 << reg))
{
strcat (instr, "%|");
strcat (instr, reg_names[reg]);
strcat (instr, ", ");
}
if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
/* On some ARM architectures it is faster to use LDR rather than
LDM to load a single register. On other architectures, the
cost is the same. In 26 bit mode, or for exception handlers,
we have to use LDM to load the PC so that the CPSR is also
restored. */
for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
{
/* If we are not restoring the LR register then we will
have added one too many commas to the list above.
Replace it with a closing brace. */
instr [strlen (instr) - 2] = '}';
if (live_regs_mask == (unsigned int)(1 << reg))
break;
}
if (reg <= LAST_ARM_REGNUM
&& (reg != LR_REGNUM
|| ! really_return
|| (TARGET_APCS_32 && ! IS_INTERRUPT (func_type))))
{
sprintf (instr, "ldr%s\t%%|%s, [%%|sp], #4", conditional,
(reg == LR_REGNUM) ? return_reg : reg_names[reg]);
}
else
{
strcat (instr, "%|");
char *p;
int first = 1;
/* At this point there should only be one or two registers left in
live_regs_mask: always LR, and possibly PC if we created a stack
frame. LR contains the return address. If we do not have any
special requirements for function exit (eg interworking, or ISR)
then we can load this value directly into the PC and save an
instruction. */
if (! TARGET_INTERWORK
&& ! IS_INTERRUPT (func_type)
&& really_return)
strcat (instr, reg_names [PC_REGNUM]);
/* Generate the load multiple instruction to restore the registers. */
if (frame_pointer_needed)
sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
else
strcat (instr, reg_names [LR_REGNUM]);
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
p = instr + strlen (instr);
for (reg = 0; reg <= SP_REGNUM; reg++)
if (live_regs_mask & (1 << reg))
{
int l = strlen (reg_names[reg]);
if (first)
first = 0;
else
{
memcpy (p, ", ", 2);
p += 2;
}
memcpy (p, "%|", 2);
memcpy (p + 2, reg_names[reg], l);
p += l + 2;
}
if (live_regs_mask & (1 << LR_REGNUM))
{
int l = strlen (return_reg);
if (! first)
{
memcpy (p, ", ", 2);
p += 2;
}
memcpy (p, "%|", 2);
memcpy (p + 2, return_reg, l);
strcpy (p + 2 + l, ((TARGET_APCS_32
&& !IS_INTERRUPT (func_type))
|| !really_return)
? "}" : "}^");
}
else
strcpy (p, "}");
}
if (really_return)
output_asm_insn (instr, & operand);
/* See if we need to generate an extra instruction to
perform the actual function return. */
if (really_return
&& func_type != ARM_FT_INTERWORKED
&& (live_regs_mask & (1 << LR_REGNUM)) != 0)
{
/* See if we need to generate an extra instruction to
perform the actual function return. */
switch ((int) ARM_FUNC_TYPE (func_type))
{
case ARM_FT_ISR:
case ARM_FT_FIQ:
output_asm_insn (instr, & operand);
strcpy (instr, "sub");
strcat (instr, conditional);
strcat (instr, "s\t%|pc, %|lr, #4");
break;
case ARM_FT_EXCEPTION:
output_asm_insn (instr, & operand);
strcpy (instr, "mov");
strcat (instr, conditional);
strcat (instr, "s\t%|pc, %|lr");
break;
case ARM_FT_INTERWORKED:
output_asm_insn (instr, & operand);
strcpy (instr, "bx");
strcat (instr, conditional);
strcat (instr, "\t%|lr");
break;
default:
/* The return has already been handled
by loading the LR into the PC. */
if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
{
output_asm_insn (instr, & operand);
strcpy (instr, "mov");
strcat (instr, conditional);
if (! TARGET_APCS_32)
strcat (instr, "s");
strcat (instr, "\t%|pc, %|lr");
}
break;
}
/* The return has already been handled
by loading the LR into the PC. */
really_return = 0;
}
}
else if (really_return)
if (really_return)
{
switch ((int) ARM_FUNC_TYPE (func_type))
{
@ -7340,18 +7342,19 @@ output_return_instruction (operand, really_return, reverse)
break;
default:
sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
conditional, TARGET_APCS_32 ? "" : "s");
/* ARMv5 implementations always provide BX, so interworking
is the default unless APCS-26 is in use. */
if ((insn_flags & FL_ARCH5) != 0 && TARGET_APCS_32)
sprintf (instr, "bx%s\t%%|lr", conditional);
else
sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
conditional, TARGET_APCS_32 ? "" : "s");
break;
}
}
else
/* Nothing to load off the stack, and
no return instruction to generate. */
return "";
output_asm_insn (instr, & operand);
output_asm_insn (instr, & operand);
}
return "";
}
@ -7457,9 +7460,9 @@ arm_output_function_prologue (f, frame_size)
current_function_args_size,
current_function_pretend_args_size, frame_size);
asm_fprintf (f, "\t%@ frame_needed = %d, current_function_anonymous_args = %d\n",
asm_fprintf (f, "\t%@ frame_needed = %d, uses_anonymous_args = %d\n",
frame_pointer_needed,
current_function_anonymous_args);
cfun->machine->uses_anonymous_args);
if (cfun->machine->lr_save_eliminated)
asm_fprintf (f, "\t%@ link register save eliminated.\n");
@ -7479,8 +7482,9 @@ arm_output_epilogue (really_return)
int reg;
unsigned long saved_regs_mask;
unsigned long func_type;
/* If we need this, then it will always be at least this much. */
int floats_offset = 12;
/* Floats_offset is the offset from the "virtual" frame. In an APCS
frame that is $fp + 4 for a non-variadic function. */
int floats_offset = 0;
rtx operands[3];
int frame_size = get_frame_size ();
FILE * f = asm_out_file;
@ -7517,6 +7521,9 @@ arm_output_epilogue (really_return)
saved_regs_mask = arm_compute_save_reg_mask ();
/* XXX We should adjust floats_offset for any anonymous args, and then
re-adjust vfp_offset below to compensate. */
/* Compute how far away the floats will be. */
for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
if (saved_regs_mask & (1 << reg))
@ -7524,6 +7531,8 @@ arm_output_epilogue (really_return)
if (frame_pointer_needed)
{
int vfp_offset = 4;
if (arm_fpu_arch == FP_SOFT2)
{
for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
@ -7531,7 +7540,7 @@ arm_output_epilogue (really_return)
{
floats_offset += 12;
asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
reg, FP_REGNUM, floats_offset);
reg, FP_REGNUM, floats_offset - vfp_offset);
}
}
else
@ -7548,7 +7557,7 @@ arm_output_epilogue (really_return)
if (start_reg - reg == 3)
{
asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
reg, FP_REGNUM, floats_offset);
reg, FP_REGNUM, floats_offset - vfp_offset);
start_reg = reg - 1;
}
}
@ -7557,7 +7566,7 @@ arm_output_epilogue (really_return)
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
FP_REGNUM, floats_offset);
FP_REGNUM, floats_offset - vfp_offset);
start_reg = reg - 1;
}
}
@ -7566,7 +7575,7 @@ arm_output_epilogue (really_return)
if (reg != start_reg)
asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
reg + 1, start_reg - reg,
FP_REGNUM, floats_offset);
FP_REGNUM, floats_offset - vfp_offset);
}
/* saved_regs_mask should contain the IP, which at the time of stack
@ -7660,7 +7669,7 @@ arm_output_epilogue (really_return)
to load use the LDR instruction - it is faster. */
if (saved_regs_mask == (1 << LR_REGNUM))
{
/* The excpetion handler ignores the LR, so we do
/* The exception handler ignores the LR, so we do
not really need to load it off the stack. */
if (eh_ofs)
asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
@ -7686,7 +7695,10 @@ arm_output_epilogue (really_return)
REGNO (eh_ofs));
#endif
if (! really_return)
if (! really_return
|| (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
&& current_function_pretend_args_size == 0
&& saved_regs_mask & (1 << PC_REGNUM)))
return "";
/* Generate the return instruction. */
@ -7754,7 +7766,6 @@ arm_output_function_epilogue (file, frame_size)
abort ();
/* Reset the ARM-specific per-function variables. */
current_function_anonymous_args = 0;
after_arm_reorg = 0;
}
}
@ -8068,7 +8079,7 @@ arm_compute_initial_elimination_offset (from, to)
/* FIXME: Not sure about this. Maybe we should always return 0 ? */
return (frame_pointer_needed
&& current_function_needs_context
&& ! current_function_anonymous_args) ? 4 : 0;
&& ! cfun->machine->uses_anonymous_args) ? 4 : 0;
case STACK_POINTER_REGNUM:
/* If nothing has been pushed on the stack at all
@ -8209,7 +8220,7 @@ arm_expand_prologue ()
else
{
/* Store the args on the stack. */
if (current_function_anonymous_args)
if (cfun->machine->uses_anonymous_args)
insn = emit_multi_reg_push
((0xf0 >> (args_to_push / 4)) & 0xf);
else
@ -8245,7 +8256,7 @@ arm_expand_prologue ()
if (args_to_push)
{
/* Push the argument registers, or reserve space for them. */
if (current_function_anonymous_args)
if (cfun->machine->uses_anonymous_args)
insn = emit_multi_reg_push
((0xf0 >> (args_to_push / 4)) & 0xf);
else
@ -8255,6 +8266,19 @@ arm_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1;
}
/* If this is an interrupt service routine, and the link register is
going to be pushed, subtracting four now will mean that the
function return can be done with a single instruction. */
if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ)
&& (live_regs_mask & (1 << LR_REGNUM)) != 0)
{
emit_insn (gen_rtx_SET (SImode,
gen_rtx_REG (SImode, LR_REGNUM),
gen_rtx_PLUS (SImode,
gen_rtx_REG (SImode, LR_REGNUM),
GEN_INT (-4))));
}
if (live_regs_mask)
{
insn = emit_multi_reg_push (live_regs_mask);
@ -8609,7 +8633,9 @@ arm_assemble_integer (x, size, aligned_p)
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
{
if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
if (GET_CODE (x) == SYMBOL_REF
&& (CONSTANT_POOL_ADDRESS_P (x)
|| ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
fputs ("(GOTOFF)", asm_out_file);
else if (GET_CODE (x) == LABEL_REF)
fputs ("(GOTOFF)", asm_out_file);
@ -9139,20 +9165,8 @@ arm_hard_regno_mode_ok (regno, mode)
return (NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
if (regno <= LAST_ARM_REGNUM)
/* We allow an SImode or smaller value to be stored in any
general purpose register. This does not mean, for example
that GCC will choose to store a variable in the stack pointer
since it is a fixed register. But it is important to allow
access to these special registers, so that they can be
referenced from C code via the asm assembler alias, eg:
register char * stack_ptr asm ("sp");
For any mode requiring more than one register to hold the
value we restrict the choice so that r13, r14, and r15
cannot be part of the register set. */
return (NUM_REGS (mode) <= 1)
|| (regno < (SP_REGNUM - (unsigned) NUM_REGS (mode)));
/* We allow any value to be stored in the general regisetrs. */
return 1;
if ( regno == FRAME_POINTER_REGNUM
|| regno == ARG_POINTER_REGNUM)
@ -10187,7 +10201,6 @@ thumb_expand_prologue ()
if (regno > LAST_LO_REGNUM) /* Very unlikely */
{
rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
rtx insn;
/* Choose an arbitary, non-argument low register. */
reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
@ -10312,7 +10325,7 @@ thumb_output_function_prologue (f, size)
if (current_function_pretend_args_size)
{
if (current_function_anonymous_args)
if (cfun->machine->uses_anonymous_args)
{
int num_pushes;

View File

@ -81,8 +81,6 @@ extern struct rtx_def * pool_vector_label;
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
extern int return_used_this_function;
/* Nonzero if the prologue must setup `fp'. */
extern int current_function_anonymous_args;
/* Just in case configure has failed to define anything. */
#ifndef TARGET_CPU_DEFAULT
@ -855,7 +853,7 @@ extern const char * structure_size_string;
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@ -1029,6 +1027,13 @@ extern const char * structure_size_string;
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26 \
}
/* Interrupt functions can only use registers that have already been
saved by the prologue, even if they would normally be
call-clobbered. */
#define HARD_REGNO_RENAME_OK(SRC, DST) \
(! IS_INTERRUPT (cfun->machine->func_type) || \
regs_ever_live[DST])
/* Register and constant classes. */
@ -1454,6 +1459,8 @@ typedef struct machine_function
int lr_save_eliminated;
/* Records the type of the current function. */
unsigned long func_type;
/* Record if the function has a variable argument list. */
int uses_anonymous_args;
}
machine_function;
@ -1536,8 +1543,7 @@ typedef struct
that way. */
#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
{ \
extern int current_function_anonymous_args; \
current_function_anonymous_args = 1; \
cfun->machine->uses_anonymous_args = 1; \
if ((CUM).nregs < NUM_ARG_REGS) \
(PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD; \
}
@ -1844,7 +1850,8 @@ typedef struct
#define THUMB_LEGITIMATE_CONSTANT_P(X) \
( GET_CODE (X) == CONST_INT \
|| GET_CODE (X) == CONST_DOUBLE \
|| CONSTANT_ADDRESS_P (X))
|| CONSTANT_ADDRESS_P (X) \
|| flag_pic)
#define LEGITIMATE_CONSTANT_P(X) \
(TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X))
@ -1892,9 +1899,9 @@ typedef struct
or known to be defined in this file then encode a short call flag.
This macro is used inside the ENCODE_SECTION macro. */
#define ARM_ENCODE_CALL_TYPE(decl) \
if (TREE_CODE (decl) == FUNCTION_DECL) \
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') \
{ \
if (DECL_WEAK (decl)) \
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl)) \
arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
else if (! TREE_PUBLIC (decl)) \
arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \

View File

@ -135,8 +135,12 @@
(define_attr "neg_pool_range" "" (const_int 0))
; An assembler sequence may clobber the condition codes without us knowing.
; If such an insn references the pool, then we have no way of knowing how,
; so use the most conservative value for pool_range.
(define_asm_attributes
[(set_attr "conds" "clob")])
[(set_attr "conds" "clob")
(set_attr "length" "4")
(set_attr "pool_range" "250")])
; TYPE attribute is used to detect floating point instructions which, if
; running on a co-processor can run in parallel with other, basic instructions
@ -3959,7 +3963,7 @@
[(set_attr "length" "8")
(set_attr "type" "*,load,store2")
(set_attr "pool_range" "*,1020,*")
(set_attr "neg_pool_range" "*,1012,*")]
(set_attr "neg_pool_range" "*,1008,*")]
)
;;; ??? This should have alternatives for constants.
@ -4132,27 +4136,6 @@
}"
)
(define_expand "movaddr"
[(set (match_operand:SI 0 "s_register_operand" "")
(match_operand:DI 1 "address_operand" ""))]
"TARGET_ARM"
""
)
(define_insn "*movaddr_insn"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operand:DI 1 "address_operand" "p"))]
"TARGET_ARM
&& reload_completed
&& (GET_CODE (operands[1]) == LABEL_REF
|| (GET_CODE (operands[1]) == CONST
&& GET_CODE (XEXP (operands[1], 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
&& GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
"adr%?\\t%0, %a1"
[(set_attr "predicable" "yes")]
)
;; When generating pic, we need to load the symbol offset into a register.
;; So that the optimizer does not confuse this with a normal symbol load
;; we use an unspec. The offset will be loaded from a constant pool entry,
@ -5110,8 +5093,8 @@
(set_attr "predicable" "yes")
(set_attr "type"
"load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
(set_attr "pool_range" "*,*,*,*,252,*,*,1024,*,*,*")
(set_attr "neg_pool_range" "*,*,*,*,244,*,*,1012,*,*,*")]
(set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
(set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
)
;; Software floating point version. This is essentially the same as movdi.
@ -5126,8 +5109,8 @@
"* return output_move_double (operands);"
[(set_attr "length" "8,8,8")
(set_attr "type" "*,load,store2")
(set_attr "pool_range" "252")
(set_attr "neg_pool_range" "244")]
(set_attr "pool_range" "1020")
(set_attr "neg_pool_range" "1008")]
)
;;; ??? This should have alternatives for constants.
@ -5201,7 +5184,7 @@
(set_attr "predicable" "yes")
(set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
(set_attr "pool_range" "*,*,1024,*,*,*,*")
(set_attr "neg_pool_range" "*,*,1012,*,*,*,*")]
(set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
)
@ -6655,7 +6638,8 @@
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_THUMB
&& operands[2] == const0_rtx && (GET_CODE (operands[0]) == SYMBOL_REF)"
&& GET_CODE (operands[0]) == SYMBOL_REF
&& !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
"bl\\t%a0"
[(set_attr "length" "4")
(set_attr "type" "call")]
@ -6668,7 +6652,8 @@
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_THUMB
&& operands[3] == const0_rtx && (GET_CODE (operands[1]) == SYMBOL_REF)"
&& GET_CODE (operands[1]) == SYMBOL_REF
&& !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
"bl\\t%a1"
[(set_attr "length" "4")
(set_attr "type" "call")]
@ -8297,6 +8282,7 @@
"TARGET_ARM
&& !BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS
&& !arm_arch4
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& (GET_CODE (operands[2]) != REG
@ -8315,6 +8301,7 @@
"TARGET_ARM
&& !BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS
&& !arm_arch4
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& (GET_CODE (operands[2]) != REG
@ -8479,6 +8466,7 @@
"TARGET_ARM
&& !BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS
&& !arm_arch4
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
@ -8499,6 +8487,7 @@
"TARGET_ARM
&& !BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS
&& !arm_arch4
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
@ -8562,6 +8551,7 @@
"TARGET_ARM
&& !BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS
&& !arm_arch4
&& REGNO (operands[0]) != REGNO(operands[1])
&& (GET_CODE (operands[2]) != REG
|| REGNO(operands[0]) != REGNO (operands[2]))"
@ -9136,11 +9126,28 @@
;; Miscellaneous Thumb patterns
(define_insn "tablejump"
(define_expand "tablejump"
[(parallel [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
(use (label_ref (match_operand 1 "" "")))])]
"TARGET_THUMB"
"
if (flag_pic)
{
/* Hopefully, CSE will eliminate this copy. */
rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
rtx reg2 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (reg2, operands[0], reg1));
operands[0] = reg2;
}
"
)
(define_insn "*thumb_tablejump"
[(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_THUMB"
"mov pc, %0"
"mov\\t%|pc, %0"
[(set_attr "length" "2")]
)

View File

@ -72,7 +72,9 @@ Boston, MA 02111-1307, USA. */
/* Define this macro if jump tables (for `tablejump' insns) should be
output in the text section, along with the assembler instructions.
Otherwise, the readonly data section is used. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
/* We put ARM jump tables in the text section, because it makes the code
more efficient, but for Thumb it's better to put them out of band. */
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION rdata_section

View File

@ -103,7 +103,9 @@ Boston, MA 02111-1307, USA. */
/* Define this macro if jump tables (for `tablejump' insns) should be
output in the text section, along with the assembler instructions.
Otherwise, the readonly data section is used. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
/* We put ARM jump tables in the text section, because it makes the code
more efficient, but for Thumb it's better to put them out of band. */
#define JUMP_TABLES_IN_TEXT_SECTION (TARGET_ARM)
#ifndef LINK_SPEC
#define LINK_SPEC "%{mbig-endian:-EB} -X"

View File

@ -1,5 +1,5 @@
/* Definitions for ARM running Linux-based GNU systems using ELF
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org>
@ -42,6 +42,10 @@ Boston, MA 02111-1307, USA. */
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
/* The GNU C++ standard library requires that these macros be defined. */
#undef CPLUSPLUS_CPP_SPEC
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
/* Now we define the strings used to build the spec file. */
#define LIB_SPEC \
"%{shared: -lc} \
@ -87,7 +91,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-Dunix -Dlinux -D__ELF__ \
"-Dunix -D__gnu_linux__ -Dlinux -D__ELF__ \
-Asystem=unix -Asystem=posix"
/* Allow #sccs in preprocessor. */

View File

@ -1,4 +1,4 @@
/* NetBSD/arm (RiscBSD) version.
/* NetBSD/arm a.out version.
Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
Contributed by Mark Brinicombe (amb@physig.ph.kcl.ac.uk)
@ -77,15 +77,6 @@ Boston, MA 02111-1307, USA. */
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#define HANDLE_SYSV_PRAGMA
/* We don't have any limit on the length as out debugger is GDB. */

View File

@ -1,5 +1,5 @@
/* Definitions for RTEMS based ARM systems using ELF
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -19,15 +19,10 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/ELF RTEMS)", stderr);
#define HAS_INIT_SECTION
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Darm -Darm_elf -Drtems -D__rtems__ -D__ELF__ \
-Asystem(rtems) -Acpu(arm) -Amachine(arm)"
/*#undef INVOKE_main*/
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__rtems__ -D__ELF__ -Asystem=rtems"

View File

@ -66,7 +66,7 @@
#undef DBL_MAX_10_EXP
#define DBL_MAX_10_EXP 308
#if defined(__sparcv9) || defined(__arch64__)
#if defined(__sparcv9) || defined(__arch64__) || defined(__LONG_DOUBLE_128__)
/* Number of base-FLT_RADIX digits in the significand of a long double */
#undef LDBL_MANT_DIG

View File

@ -59,31 +59,30 @@ Boston, MA 02111-1307, USA. */
/************************[ Target stuff ]***********************************/
/* All FreeBSD Architectures support the ELF object file format. */
#undef OBJECT_FORMAT_ELF
#define OBJECT_FORMAT_ELF
/* Don't assume anything about the header files. */
#undef NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C 1
/* Allow #sccs in preprocessor. */
#undef SCCS_DIRECTIVE
#define SCCS_DIRECTIVE
#define SCCS_DIRECTIVE 1
/* Make gcc agree with FreeBSD's standard headers (<machine/ansi.h>, etc...) */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#define WCHAR_UNSIGNED 0
#define MATH_LIBRARY_PROFILE "-lm_p"
/* Code generation parameters. */
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
we want to retain compatibility with older gcc versions
(even though the SVR4 ABI for the i386 says that records and unions are
returned in memory). */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0
/* Use periods rather than dollar signs in special g++ assembler names.
This ensures the configuration knows our system correctly so we can link
with libraries compiled with the native cc. */
@ -92,37 +91,4 @@ Boston, MA 02111-1307, USA. */
/* Used by libgcc2.c. We support file locking with fcntl / F_SETLKW.
This enables the test coverage code to use file locking when exiting a
program, which avoids race conditions if the program has forked. */
#define TARGET_HAS_F_SETLKW
/* The prefix to add to user-visible assembler symbols.
For System V Release 4 & ELF the convention is *not* to prepend a leading
underscore onto user-level symbol names. Some CPU files such as
config/sparc/sparc.h set this wrong for ELF. */
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
/* Handle #pragma weak and #pragma pack. */
#undef HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA
/************************[ Assembler stuff ]********************************/
#undef IDENT_ASM_OP
#define IDENT_ASM_OP "\t.ident\t"
/************************[ Debugger stuff ]*********************************/
/* All ELF targets can support DWARF-2. */
#undef DWARF2_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO
/* This is BSD, so we want the DBX format. */
#undef DBX_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO
/* Even though this is BSD, ELF and the GNU tools operates better with dwarf2
than stabs. Since we don't have any native tools to be compatible with,
defaulting to dwarf2 is OK. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#define TARGET_HAS_F_SETLKW 1

View File

@ -423,6 +423,11 @@ extern void i386_pe_unique_section PARAMS ((TREE, int));
#undef ASM_COMMENT_START
#define ASM_COMMENT_START " #"
/* DWARF2 Unwinding doesn't work with exception handling yet. To make it
work, we need to build a libgcc_s.dll, and dcrt0.o should be changed to
call __register_frame_info/__deregister_frame_info. */
#define DWARF2_UNWIND_INFO 0
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C

View File

@ -1,7 +1,7 @@
/* Configuration for an i386 running RTEMS on top of MS-DOS with
DJGPP v2.x.
Copyright (C) 1996,1999 Free Software Foundation, Inc.
Copyright (C) 1996, 1999, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
This file is part of GNU CC.
@ -21,20 +21,15 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "i386/djgpp.h"
/* Specify predefined symbols in preprocessor. */
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
#define CPP_PREDEFINES "-Dunix -DGO32 -DDJGPP=2 -DMSDOS \
#define CPP_PREDEFINES "-Dunix -DGO32 -DDJGPP=2 -DMSDOS -D__rtems__ \
-Asystem=unix -Asystem=msdos -Asystem=rtems"
/* Generate calls to memcpy, memcmp and memset. */
#ifndef TARGET_MEM_FUNCTIONS
#define TARGET_MEM_FUNCTIONS
#endif
/* end of i386/djgpp-rtems.h */

View File

@ -1,5 +1,5 @@
/* Definitions for Intel 386 running FreeBSD with ELF format
Copyright (C) 1996, 2000 Free Software Foundation, Inc.
Copyright (C) 1996, 2000, 2002 Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
Adapted from GNU/Linux version by John Polstra.
@ -22,23 +22,24 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/ELF)");
/* Override the default comment-starter of "/". */
#undef ASM_COMMENT_START
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
#undef ASM_APP_ON
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
#undef ASM_APP_OFF
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
#undef SET_ASM_OP
#undef SET_ASM_OP
#define SET_ASM_OP "\t.set\t"
#undef DBX_REGISTER_NUMBER
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) \
(TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
@ -47,7 +48,7 @@ Boston, MA 02111-1307, USA. */
/* Tell final.c that we don't need a label passed to mcount. */
#undef FUNCTION_PROFILER
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ \
if (flag_pic) \
@ -58,13 +59,13 @@ Boston, MA 02111-1307, USA. */
/* Make gcc agree with <machine/ansi.h>. */
#undef SIZE_TYPE
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE_SIZE
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add
@ -105,7 +106,7 @@ Boston, MA 02111-1307, USA. */
done. */
#undef LINK_SPEC
#define LINK_SPEC "-m elf_i386 \
#define LINK_SPEC "\
%{Wl,*:%*} \
%{v:-V} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
@ -130,3 +131,11 @@ Boston, MA 02111-1307, USA. */
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
#endif
/* Don't default to pcc-struct-return, we want to retain compatibility with
older gcc versions AND pcc-struct-return is nonreentrant.
(even though the SVR4 ABI for the i386 says that records and unions are
returned in memory). */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0

View File

@ -5,7 +5,7 @@
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__ELF__ -DMACH -Asystem=mach \
-Dunix -Asystem=unix -Asystem=posix -D__GNU__ -Asystem=gnu"
-Dunix -Asystem=unix -Asystem=posix -D__gnu_hurd__ -D__GNU__ -Asystem=gnu"
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) \

View File

@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
-D_M_IX86=300 -D_X86_=1 \
-D__stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem=unix -Asystem=interix"
#undef CPP_SPEC
@ -237,6 +238,7 @@ Boston, MA 02111-1307, USA. */
#undef LD_INIT_SWITCH
#undef LD_FINI_SWITCH
#define EH_FRAME_IN_DATA_SECTION
/* Note that there appears to be two different ways to support const
sections at the moment. You can either #define the symbol
@ -410,10 +412,10 @@ extern void i386_pe_unique_section ();
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
#endif /* 0 */
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
#endif /* 0 */
/* DWARF2 Unwinding doesn't work with exception handling yet. */
#define DWARF2_UNWIND_INFO 0
@ -421,3 +423,11 @@ extern void i386_pe_unique_section ();
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
/* MSVC returns structs of up to 8 bytes via registers. */
#define DEFAULT_PCC_STRUCT_RETURN 0
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE (TYPE) == BLKmode || \
(AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes(TYPE) > 8 ))

View File

@ -169,6 +169,7 @@ extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
extern void x86_order_regs_for_local_alloc PARAMS ((void));
#ifdef TREE_CODE

View File

@ -392,6 +392,7 @@ const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
const int x86_decompose_lea = m_PENT4;
const int x86_arch_always_fancy_math_387 = m_PENT|m_PPRO|m_ATHLON|m_PENT4;
/* In case the avreage insn count for single function invocation is
lower than this constant, emit fast (but longer) prologue and
@ -1085,14 +1086,14 @@ override_options ()
don't want additional code to keep the stack aligned when
optimizing for code size. */
ix86_preferred_stack_boundary = (optimize_size
? TARGET_64BIT ? 64 : 32
? TARGET_64BIT ? 128 : 32
: 128);
if (ix86_preferred_stack_boundary_string)
{
i = atoi (ix86_preferred_stack_boundary_string);
if (i < (TARGET_64BIT ? 3 : 2) || i > 12)
if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
error ("-mpreferred-stack-boundary=%d is not between %d and 12", i,
TARGET_64BIT ? 3 : 2);
TARGET_64BIT ? 4 : 2);
else
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
@ -1117,6 +1118,11 @@ override_options ()
if (flag_unsafe_math_optimizations)
target_flags &= ~MASK_IEEE_FP;
/* If the architecture always has an FPU, turn off NO_FANCY_MATH_387,
since the insns won't need emulation. */
if (x86_arch_always_fancy_math_387 & (1 << ix86_arch))
target_flags &= ~MASK_NO_FANCY_MATH_387;
if (TARGET_64BIT)
{
if (TARGET_ALIGN_DOUBLE)
@ -1328,7 +1334,7 @@ ix86_osf_output_function_prologue (file, size)
{
const char *prefix = "";
const char *const lprefix = LPREFIX;
int labelno = profile_label_no;
int labelno = current_function_profile_label_no;
#ifdef OSF_OS
@ -1466,12 +1472,25 @@ ix86_return_pops_args (fundecl, funtype, size)
return size;
}
/* Lose any fake structure return argument. */
/* Lose any fake structure return argument if it is passed on the stack. */
if (aggregate_value_p (TREE_TYPE (funtype))
&& !TARGET_64BIT)
return GET_MODE_SIZE (Pmode);
{
int nregs = ix86_regparm;
return 0;
if (funtype)
{
tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (funtype));
if (attr)
nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
}
if (!nregs)
return GET_MODE_SIZE (Pmode);
}
return 0;
}
/* Argument support functions. */
@ -1713,7 +1732,8 @@ classify_argument (mode, type, classes, bit_offset)
classes[i] = subclasses[i % num];
}
/* Unions are similar to RECORD_TYPE but offset is always 0. */
else if (TREE_CODE (type) == UNION_TYPE)
else if (TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
{
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
@ -1819,7 +1839,19 @@ classify_argument (mode, type, classes, bit_offset)
case SCmode:
classes[0] = X86_64_SSE_CLASS;
return 1;
case V4SFmode:
case V4SImode:
classes[0] = X86_64_SSE_CLASS;
classes[1] = X86_64_SSEUP_CLASS;
return 2;
case V2SFmode:
case V2SImode:
case V4HImode:
case V8QImode:
classes[0] = X86_64_SSE_CLASS;
return 1;
case BLKmode:
case VOIDmode:
return 0;
default:
abort ();
@ -1932,7 +1964,7 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
abort ();
}
if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS)
return gen_rtx_REG (TImode, SSE_REGNO (sse_regno));
return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
if (n == 2
&& class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
return gen_rtx_REG (TFmode, FIRST_STACK_REG);
@ -1985,7 +2017,7 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
sse_regno++;
break;
case X86_64_SSE_CLASS:
if (i < n && class[i + 1] == X86_64_SSEUP_CLASS)
if (i < n - 1 && class[i + 1] == X86_64_SSEUP_CLASS)
tmpmode = TImode, i++;
else
tmpmode = DImode;
@ -2477,6 +2509,7 @@ ix86_va_start (stdarg_p, valist, nextarg)
t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
cfun->preferred_stack_boundary = 128;
}
/* Implement va_arg. */
@ -3855,9 +3888,7 @@ ix86_save_reg (regno, maybe_eh_return)
int regno;
int maybe_eh_return;
{
if (flag_pic
&& ! TARGET_64BIT
&& regno == PIC_OFFSET_TABLE_REGNUM
if (regno == PIC_OFFSET_TABLE_REGNUM
&& (current_function_uses_pic_offset_table
|| current_function_uses_const_pool
|| current_function_calls_eh_return))
@ -4974,11 +5005,15 @@ legitimize_pic_address (orig, reg)
if (GET_CODE (addr) == CONST)
{
addr = XEXP (addr, 0);
if (GET_CODE (addr) == UNSPEC)
{
/* Check that the unspec is one of the ones we generate? */
}
else if (GET_CODE (addr) != PLUS)
/* We must match stuff we generate before. Assume the only
unspecs that can get here are ours. Not that we could do
anything with them anyway... */
if (GET_CODE (addr) == UNSPEC
|| (GET_CODE (addr) == PLUS
&& GET_CODE (XEXP (addr, 0)) == UNSPEC))
return orig;
if (GET_CODE (addr) != PLUS)
abort ();
}
if (GET_CODE (addr) == PLUS)
@ -5365,34 +5400,70 @@ rtx
i386_simplify_dwarf_addr (orig_x)
rtx orig_x;
{
rtx x = orig_x;
rtx x = orig_x, y;
if (GET_CODE (x) == MEM)
x = XEXP (x, 0);
if (TARGET_64BIT)
{
if (GET_CODE (x) != CONST
|| GET_CODE (XEXP (x, 0)) != UNSPEC
|| XINT (XEXP (x, 0), 1) != 15)
|| XINT (XEXP (x, 0), 1) != 15
|| GET_CODE (orig_x) != MEM)
return orig_x;
return XVECEXP (XEXP (x, 0), 0, 0);
}
if (GET_CODE (x) != PLUS
|| GET_CODE (XEXP (x, 0)) != REG
|| GET_CODE (XEXP (x, 1)) != CONST)
return orig_x;
if (GET_CODE (XEXP (x, 0)) == REG
&& REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
/* %ebx + GOT/GOTOFF */
y = NULL;
else if (GET_CODE (XEXP (x, 0)) == PLUS)
{
/* %ebx + %reg * scale + GOT/GOTOFF */
y = XEXP (x, 0);
if (GET_CODE (XEXP (y, 0)) == REG
&& REGNO (XEXP (y, 0)) == PIC_OFFSET_TABLE_REGNUM)
y = XEXP (y, 1);
else if (GET_CODE (XEXP (y, 1)) == REG
&& REGNO (XEXP (y, 1)) == PIC_OFFSET_TABLE_REGNUM)
y = XEXP (y, 0);
else
return orig_x;
if (GET_CODE (y) != REG
&& GET_CODE (y) != MULT
&& GET_CODE (y) != ASHIFT)
return orig_x;
}
else
return orig_x;
x = XEXP (XEXP (x, 1), 0);
if (GET_CODE (x) == UNSPEC
&& (XINT (x, 1) == 6
|| XINT (x, 1) == 7))
return XVECEXP (x, 0, 0);
&& ((XINT (x, 1) == 6 && GET_CODE (orig_x) == MEM)
|| (XINT (x, 1) == 7 && GET_CODE (orig_x) != MEM)))
{
if (y)
return gen_rtx_PLUS (Pmode, y, XVECEXP (x, 0, 0));
return XVECEXP (x, 0, 0);
}
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == UNSPEC
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& (XINT (XEXP (x, 0), 1) == 6
|| XINT (XEXP (x, 0), 1) == 7))
return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
&& ((XINT (XEXP (x, 0), 1) == 6 && GET_CODE (orig_x) == MEM)
|| (XINT (XEXP (x, 0), 1) == 7 && GET_CODE (orig_x) != MEM)))
{
x = gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
if (y)
return gen_rtx_PLUS (Pmode, y, x);
return x;
}
return orig_x;
}
@ -5581,6 +5652,8 @@ print_reg (x, code, file)
C -- print opcode suffix for set/cmov insn.
c -- like C, but print reversed condition
F,f -- likewise, but for floating-point.
O -- if CMOV_SUN_AS_SYNTAX, expand to "w.", "l." or "q.", otherwise
nothing
R -- print the prefix for register names.
z -- print the opcode suffix for the size of the current operand.
* -- print a star (in certain assembler syntax)
@ -5670,11 +5743,14 @@ print_operand (file, x, code)
case 'z':
/* 387 opcodes don't get size suffixes if the operands are
registers. */
if (STACK_REG_P (x))
return;
/* this is the size of op from size of operand */
/* Likewise if using Intel opcodes. */
if (ASSEMBLER_DIALECT == ASM_INTEL)
return;
/* This is the size of op from size of operand. */
switch (GET_MODE_SIZE (GET_MODE (x)))
{
case 2:
@ -5775,10 +5851,31 @@ print_operand (file, x, code)
break;
}
return;
case 'O':
#ifdef CMOV_SUN_AS_SYNTAX
if (ASSEMBLER_DIALECT == ASM_ATT)
{
switch (GET_MODE (x))
{
case HImode: putc ('w', file); break;
case SImode:
case SFmode: putc ('l', file); break;
case DImode:
case DFmode: putc ('q', file); break;
default: abort ();
}
putc ('.', file);
}
#endif
return;
case 'C':
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
return;
case 'F':
#ifdef CMOV_SUN_AS_SYNTAX
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('.', file);
#endif
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 1, file);
return;
@ -5794,6 +5891,10 @@ print_operand (file, x, code)
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file);
return;
case 'f':
#ifdef CMOV_SUN_AS_SYNTAX
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('.', file);
#endif
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
return;
case '+':
@ -5830,11 +5931,7 @@ print_operand (file, x, code)
return;
}
default:
{
char str[50];
sprintf (str, "invalid operand code `%c'", code);
output_operand_lossage (str);
}
output_operand_lossage ("invalid operand code `%c'", code);
}
}
@ -6565,7 +6662,7 @@ ix86_output_addr_diff_elt (file, value, rel)
int value, rel;
{
if (TARGET_64BIT)
fprintf (file, "%s%s%d-.+4+(.-%s%d)\n",
fprintf (file, "%s%s%d-.+(.-%s%d)\n",
ASM_LONG, LPREFIX, value, LPREFIX, rel);
else if (HAVE_AS_GOTOFF_IN_DATA)
fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
@ -6692,7 +6789,7 @@ ix86_expand_vector_move (mode, operands)
&& !register_operand (operands[1], mode)
&& operands[1] != CONST0_RTX (mode))
{
rtx temp = force_reg (TImode, operands[1]);
rtx temp = force_reg (GET_MODE (operands[1]), operands[1]);
emit_move_insn (operands[0], temp);
return;
}
@ -7105,7 +7202,7 @@ ix86_prepare_fp_compare_args (code, pop0, pop1)
/* Try to rearrange the comparison to make it cheaper. */
if (ix86_fp_comparison_cost (code)
> ix86_fp_comparison_cost (swap_condition (code))
&& (GET_CODE (op0) == REG || !reload_completed))
&& (GET_CODE (op1) == REG || !no_new_pseudos))
{
rtx tmp;
tmp = op0, op0 = op1, op1 = tmp;
@ -11323,6 +11420,12 @@ ix86_expand_binop_builtin (icode, arglist, target)
if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
/* In the commutative cases, both op0 and op1 are nonimmediate_operand,
yet one of the two must not be a memory. This is normally enforced
by expanders, but we didn't bother to create one here. */
if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
op0 = copy_to_mode_reg (mode0, op0);
pat = GEN_FCN (icode) (target, op0, op1);
if (! pat)
return 0;
@ -11355,6 +11458,12 @@ ix86_expand_timode_binop_builtin (icode, arglist, target)
if (! (*insn_data[icode].operand[2].predicate) (op1, TImode))
op1 = copy_to_mode_reg (TImode, op1);
/* In the commutative cases, both op0 and op1 are nonimmediate_operand,
yet one of the two must not be a memory. This is normally enforced
by expanders, but we didn't bother to create one here. */
if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
op0 = copy_to_mode_reg (TImode, op0);
pat = GEN_FCN (icode) (target, op0, op1);
if (! pat)
return 0;
@ -11382,6 +11491,10 @@ ix86_expand_store_builtin (icode, arglist)
op1 = safe_vector_operand (op1, mode1);
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
pat = GEN_FCN (icode) (op0, op1);
if (pat)
emit_insn (pat);
@ -11436,7 +11549,7 @@ ix86_expand_unop1_builtin (icode, arglist, target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
rtx op1, op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
@ -11450,8 +11563,12 @@ ix86_expand_unop1_builtin (icode, arglist, target)
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
pat = GEN_FCN (icode) (target, op0, op0);
op1 = op0;
if (! (*insn_data[icode].operand[2].predicate) (op1, mode0))
op1 = copy_to_mode_reg (mode0, op1);
pat = GEN_FCN (icode) (target, op0, op1);
if (! pat)
return 0;
emit_insn (pat);
@ -11661,7 +11778,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
return target;
case IX86_BUILTIN_MASKMOVQ:
icode = CODE_FOR_mmx_maskmovq;
icode = TARGET_64BIT ? CODE_FOR_mmx_maskmovq_rex : CODE_FOR_mmx_maskmovq;
/* Note the arg order is different from the operand order. */
arg1 = TREE_VALUE (arglist);
arg2 = TREE_VALUE (TREE_CHAIN (arglist));
@ -11673,7 +11790,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
mode1 = insn_data[icode].operand[1].mode;
mode2 = insn_data[icode].operand[2].mode;
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
@ -12312,3 +12429,47 @@ ix86_svr3_asm_out_constructor (symbol, priority)
fputc ('\n', asm_out_file);
}
#endif
/* Order the registers for register allocator. */
void
x86_order_regs_for_local_alloc ()
{
int pos = 0;
int i;
/* First allocate the local general purpose registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (GENERAL_REGNO_P (i) && call_used_regs[i])
reg_alloc_order [pos++] = i;
/* Global general purpose registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (GENERAL_REGNO_P (i) && !call_used_regs[i])
reg_alloc_order [pos++] = i;
/* x87 registers come first in case we are doing FP math
using them. */
if (!TARGET_SSE_MATH)
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
reg_alloc_order [pos++] = i;
/* SSE registers. */
for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
reg_alloc_order [pos++] = i;
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
reg_alloc_order [pos++] = i;
/* x87 registerts. */
if (TARGET_SSE_MATH)
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
reg_alloc_order [pos++] = i;
for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
reg_alloc_order [pos++] = i;
/* Initialize the rest of array as we do not allocate some registers
at all. */
while (pos < FIRST_PSEUDO_REGISTER)
reg_alloc_order [pos++] = 0;
}

View File

@ -222,6 +222,7 @@ extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8;
extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
extern const int x86_accumulate_outgoing_args, x86_prologue_using_move;
extern const int x86_epilogue_using_move, x86_decompose_lea;
extern const int x86_arch_always_fancy_math_387;
extern int x86_prefetch_sse;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
@ -281,18 +282,23 @@ extern int x86_prefetch_sse;
#define TARGET_RED_ZONE (!(target_flags & MASK_NO_RED_ZONE))
/* WARNING: Do not mark empty strings for translation, as calling
gettext on an empty string does NOT return an empty
string. */
#define TARGET_SWITCHES \
{ { "80387", MASK_80387, N_("Use hardware fp") }, \
{ "no-80387", -MASK_80387, N_("Do not use hardware fp") }, \
{ "hard-float", MASK_80387, N_("Use hardware fp") }, \
{ "soft-float", -MASK_80387, N_("Do not use hardware fp") }, \
{ "no-soft-float", MASK_80387, N_("Use hardware fp") }, \
{ "386", 0, N_("") /*Deprecated.*/}, \
{ "486", 0, N_("") /*Deprecated.*/}, \
{ "pentium", 0, N_("") /*Deprecated.*/}, \
{ "pentiumpro", 0, N_("") /*Deprecated.*/}, \
{ "intel-syntax", 0, N_("") /*Deprecated.*/}, \
{ "no-intel-syntax", 0, N_("") /*Deprecated.*/}, \
{ "386", 0, "" /*Deprecated.*/}, \
{ "486", 0, "" /*Deprecated.*/}, \
{ "pentium", 0, "" /*Deprecated.*/}, \
{ "pentiumpro", 0, "" /*Deprecated.*/}, \
{ "intel-syntax", 0, "" /*Deprecated.*/}, \
{ "no-intel-syntax", 0, "" /*Deprecated.*/}, \
{ "rtd", MASK_RTD, \
N_("Alternate calling convention") }, \
{ "no-rtd", -MASK_RTD, \
@ -346,20 +352,20 @@ extern int x86_prefetch_sse;
N_("Support MMX built-in functions") }, \
{ "no-mmx", -MASK_MMX, \
N_("Do not support MMX built-in functions") }, \
{ "no-mmx", MASK_MMX_SET, N_("") }, \
{ "no-mmx", MASK_MMX_SET, "" }, \
{ "3dnow", MASK_3DNOW | MASK_3DNOW_SET, \
N_("Support 3DNow! built-in functions") }, \
{ "no-3dnow", -MASK_3DNOW, N_("") }, \
{ "no-3dnow", -MASK_3DNOW, "" }, \
{ "no-3dnow", MASK_3DNOW_SET, \
N_("Do not support 3DNow! built-in functions") }, \
{ "sse", MASK_SSE | MASK_SSE_SET, \
N_("Support MMX and SSE built-in functions and code generation") }, \
{ "no-sse", -MASK_SSE, N_("") }, \
{ "no-sse", -MASK_SSE, "" }, \
{ "no-sse", MASK_SSE_SET, \
N_("Do not support MMX and SSE built-in functions and code generation") },\
{ "sse2", MASK_SSE2 | MASK_SSE2_SET, \
N_("Support MMX, SSE and SSE2 built-in functions and code generation") }, \
{ "no-sse2", -MASK_SSE2, N_("") }, \
{ "no-sse2", -MASK_SSE2, "" }, \
{ "no-sse2", MASK_SSE2_SET, \
N_("Do not support MMX, SSE and SSE2 built-in functions and code generation") }, \
{ "128bit-long-double", MASK_128BIT_LONG_DOUBLE, \
@ -440,9 +446,9 @@ extern int ix86_arch;
{ "cmodel=", &ix86_cmodel_string, \
N_("Use given x86-64 code model") }, \
{ "debug-arg", &ix86_debug_arg_string, \
N_("" /* Undocumented. */) }, \
"" /* Undocumented. */ }, \
{ "debug-addr", &ix86_debug_addr_string, \
N_("" /* Undocumented. */) }, \
"" /* Undocumented. */ }, \
{ "asm=", &ix86_asm_string, \
N_("Use given assembler dialect") }, \
SUBTARGET_OPTIONS \
@ -606,10 +612,10 @@ extern int ix86_arch;
%{march=athlon-tbird|march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4:\
-D__SSE__ }\
%{march=pentium-mmx|march=k6|march=k6-2|march=k6-3\
march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon-mp|march=pentium2|march=pentium3|march=pentium4: -D__MMX__ }\
%{march=k6-2|march=k6-3\
march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon-mp: -D__3dNOW__ }\
%{march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
|march=athlon-mp: -D__3dNOW_A__ }\
@ -926,38 +932,21 @@ march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
registers listed in CALL_USED_REGISTERS, keeping the others
available for storage of persistent values.
Three different versions of REG_ALLOC_ORDER have been tried:
If the order is edx, ecx, eax, ... it produces a slightly faster compiler,
but slower code on simple functions returning values in eax.
If the order is eax, ecx, edx, ... it causes reload to abort when compiling
perl 4.036 due to not being able to create a DImode register (to hold a 2
word union).
If the order is eax, edx, ecx, ... it produces better code for simple
functions, and a slightly slower compiler. Users complained about the code
generated by allocating edx first, so restore the 'natural' order of things. */
The ORDER_REGS_FOR_LOCAL_ALLOC actually overwrite the order,
so this is just empty initializer for array. */
#define REG_ALLOC_ORDER \
/*ax,dx,cx,*/ \
{ 0, 1, 2, \
/* bx,si,di,bp,sp,*/ \
3, 4, 5, 6, 7, \
/*r8,r9,r10,r11,*/ \
37,38, 39, 40, \
/*r12,r15,r14,r13*/ \
41, 44, 43, 42, \
/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \
21, 22, 23, 24, 25, 26, 27, 28, \
/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \
45, 46, 47, 48, 49, 50, 51, 52, \
/*st,st1,st2,st3,st4,st5,st6,st7*/ \
8, 9, 10, 11, 12, 13, 14, 15, \
/*,arg,cc,fpsr,dir,frame*/ \
16,17, 18, 19, 20, \
/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/ \
29, 30, 31, 32, 33, 34, 35, 36 }
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
48, 49, 50, 51, 52 }
/* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
to be rearranged based on a particular function. When using sse math,
we want to allocase SSE before x87 registers and vice vera. */
#define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
/* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \
@ -969,7 +958,7 @@ do { \
call_used_regs[i] = (call_used_regs[i] \
& (TARGET_64BIT ? 2 : 1)) != 0; \
} \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@ -1145,11 +1134,11 @@ do { \
#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? FIRST_REX_INT_REG + 10 - 8 : 2)
/* Register to hold the addressing base for position independent
code access to data items.
We don't use PIC pointer for 64bit mode. Define the regnum to
dummy value to prevent gcc from pessimizing code dealing with EBX.
*/
#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? INVALID_REGNUM : 3)
code access to data items. We don't use PIC pointer for 64bit
mode. Define the regnum to dummy value to prevent gcc from
pessimizing code dealing with EBX. */
#define PIC_OFFSET_TABLE_REGNUM \
(TARGET_64BIT || !flag_pic ? INVALID_REGNUM : 3)
/* Register in which address to store a structure value
arrives in the function. On the 386, the prologue
@ -1347,7 +1336,7 @@ enum reg_class
#define SSE_REG_P(N) (REG_P (N) && SSE_REGNO_P (REGNO (N)))
#define SSE_FLOAT_MODE_P(MODE) \
((TARGET_SSE_MATH && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode))
((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode))
#define MMX_REGNO_P(N) ((N) >= FIRST_MMX_REG && (N) <= LAST_MMX_REG)
#define MMX_REG_P(XOP) (REG_P (XOP) && MMX_REGNO_P (REGNO (XOP)))
@ -2360,7 +2349,7 @@ do { \
/* When a prototype says `char' or `short', really pass an `int'.
(The 386 can't easily push less than an int.) */
#define PROMOTE_PROTOTYPES 1
#define PROMOTE_PROTOTYPES (!TARGET_64BIT)
/* A macro to update M and UNSIGNEDP when an object whose type is
TYPE and which has the specified mode and signedness is to be

View File

@ -1733,9 +1733,14 @@
(set_attr "mode" "SI")
(set_attr "length_immediate" "1")])
; The first alternative is used only to compute proper length of instruction.
; Reload's algorithm does not take into account the cost of spill instructions
; needed to free register in given class, so avoid it from choosing the first
; alternative when eax is not available.
(define_insn "*movsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
{
switch (get_attr_type (insn))
@ -1746,6 +1751,8 @@
return "movd\t{%1, %0|%0, %1}";
case TYPE_MMX:
if (get_attr_mode (insn) == DImode)
return "movq\t{%1, %0|%0, %1}";
return "movd\t{%1, %0|%0, %1}";
case TYPE_LEA:
@ -1758,17 +1765,17 @@
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "4,5")
(cond [(eq_attr "alternative" "4,5,6")
(const_string "mmx")
(eq_attr "alternative" "6,7,8")
(eq_attr "alternative" "7,8,9")
(const_string "sse")
(and (ne (symbol_ref "flag_pic") (const_int 0))
(match_operand:SI 1 "symbolic_operand" ""))
(const_string "lea")
]
(const_string "imov")))
(set_attr "modrm" "0,*,0,*,*,*,*,*,*")
(set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
(set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
(set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
;; Stores and loads of ax to arbitary constant address.
;; We fake an second form of instruction to force reload to load address
@ -1841,8 +1848,13 @@
[(set_attr "type" "push")
(set_attr "mode" "QI")])
; The first alternative is used only to compute proper length of instruction.
; Reload's algorithm does not take into account the cost of spill instructions
; needed to free register in given class, so avoid it from choosing the first
; alternative when eax is not available.
(define_insn "*movhi_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
[(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
(match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
{
@ -2460,7 +2472,7 @@
(set_attr "length_immediate" "1")])
(define_insn "*movdi_2"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
"!TARGET_64BIT
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
@ -2713,8 +2725,8 @@
(set (mem:SF (reg:DI 7)) (match_dup 1))])
(define_insn "*movsf_1"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@ -2752,7 +2764,10 @@
case 4:
return "mov{l}\t{%1, %0|%0, %1}";
case 5:
return "pxor\t%0, %0";
if (TARGET_SSE2)
return "pxor\t%0, %0";
else
return "xorps\t%0, %0";
case 6:
if (TARGET_PARTIAL_REG_DEPENDENCY)
return "movaps\t{%1, %0|%0, %1}";
@ -2762,12 +2777,19 @@
case 8:
return "movss\t{%1, %0|%0, %1}";
case 9:
case 10:
return "movd\t{%1, %0|%0, %1}";
case 11:
return "movq\t{%1, %0|%0, %1}";
default:
abort();
}
}
[(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
(set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
[(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
(set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
(define_insn "*swapsf"
[(set (match_operand:SF 0 "register_operand" "+f")
@ -5127,7 +5149,7 @@
(define_expand "floatsidf2"
[(set (match_operand:DF 0 "register_operand" "")
(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
""
"TARGET_80387 || TARGET_SSE2"
"")
(define_insn "*floatsidf2_i387"
@ -7330,45 +7352,85 @@
(set_attr "prefix_0f" "0,0,1")
(set_attr "mode" "HI")])
(define_insn "mulqi3"
(define_expand "mulqi3"
[(parallel [(set (match_operand:QI 0 "register_operand" "")
(mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "register_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_QIMODE_MATH"
"")
(define_insn "*mulqi3_1"
[(set (match_operand:QI 0 "register_operand" "=a")
(mult:QI (match_operand:QI 1 "register_operand" "%0")
(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
(match_operand:QI 2 "nonimmediate_operand" "qm")))
(clobber (reg:CC 17))]
"TARGET_QIMODE_MATH"
"TARGET_QIMODE_MATH
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
(set_attr "mode" "QI")])
(define_insn "umulqihi3"
(define_expand "umulqihi3"
[(parallel [(set (match_operand:HI 0 "register_operand" "")
(mult:HI (zero_extend:HI
(match_operand:QI 1 "nonimmediate_operand" ""))
(zero_extend:HI
(match_operand:QI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"TARGET_QIMODE_MATH"
"")
(define_insn "*umulqihi3_1"
[(set (match_operand:HI 0 "register_operand" "=a")
(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
(zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
(clobber (reg:CC 17))]
"TARGET_QIMODE_MATH"
"TARGET_QIMODE_MATH
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
(set_attr "mode" "QI")])
(define_insn "mulqihi3"
(define_expand "mulqihi3"
[(parallel [(set (match_operand:HI 0 "register_operand" "")
(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
(sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"TARGET_QIMODE_MATH"
"")
(define_insn "*mulqihi3_insn"
[(set (match_operand:HI 0 "register_operand" "=a")
(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
(sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
(clobber (reg:CC 17))]
"TARGET_QIMODE_MATH"
"TARGET_QIMODE_MATH
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"imul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
(set_attr "mode" "QI")])
(define_insn "umulditi3"
(define_expand "umulditi3"
[(parallel [(set (match_operand:TI 0 "register_operand" "")
(mult:TI (zero_extend:TI
(match_operand:DI 1 "nonimmediate_operand" ""))
(zero_extend:TI
(match_operand:DI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
"")
(define_insn "*umulditi3_insn"
[(set (match_operand:TI 0 "register_operand" "=A")
(mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
(zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
@ -7376,70 +7438,132 @@
(set_attr "mode" "DI")])
;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
(define_insn "umulsidi3"
(define_expand "umulsidi3"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(mult:DI (zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" ""))
(zero_extend:DI
(match_operand:SI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"!TARGET_64BIT"
"")
(define_insn "*umulsidi3_insn"
[(set (match_operand:DI 0 "register_operand" "=A")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
(zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
(clobber (reg:CC 17))]
"!TARGET_64BIT"
"!TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
(set_attr "mode" "SI")])
(define_insn "mulditi3"
(define_expand "mulditi3"
[(parallel [(set (match_operand:TI 0 "register_operand" "")
(mult:TI (sign_extend:TI
(match_operand:DI 1 "nonimmediate_operand" ""))
(sign_extend:TI
(match_operand:DI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
"")
(define_insn "*mulditi3_insn"
[(set (match_operand:TI 0 "register_operand" "=A")
(mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
(sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"imul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
(set_attr "mode" "DI")])
(define_insn "mulsidi3"
(define_expand "mulsidi3"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(mult:DI (sign_extend:DI
(match_operand:SI 1 "nonimmediate_operand" ""))
(sign_extend:DI
(match_operand:SI 2 "register_operand" ""))))
(clobber (reg:CC 17))])]
"!TARGET_64BIT"
"")
(define_insn "*mulsidi3_insn"
[(set (match_operand:DI 0 "register_operand" "=A")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
(clobber (reg:CC 17))]
"!TARGET_64BIT"
"!TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
(set_attr "mode" "SI")])
(define_expand "umuldi3_highpart"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(truncate:DI
(lshiftrt:TI
(mult:TI (zero_extend:TI
(match_operand:DI 1 "nonimmediate_operand" ""))
(zero_extend:TI
(match_operand:DI 2 "register_operand" "")))
(const_int 64))))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
"")
(define_insn "*umuldi3_highpart_rex64"
[(set (match_operand:DI 0 "register_operand" "=d")
(truncate:DI
(lshiftrt:TI
(mult:TI (zero_extend:TI
(match_operand:DI 1 "register_operand" "%a"))
(match_operand:DI 1 "nonimmediate_operand" "%a"))
(zero_extend:TI
(match_operand:DI 2 "nonimmediate_operand" "rm")))
(const_int 64))))
(clobber (match_scratch:DI 3 "=a"))
(clobber (match_scratch:DI 3 "=1"))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
(set_attr "mode" "DI")])
(define_insn "umulsi3_highpart"
(define_expand "umulsi3_highpart"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(truncate:SI
(lshiftrt:DI
(mult:DI (zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" ""))
(zero_extend:DI
(match_operand:SI 2 "register_operand" "")))
(const_int 32))))
(clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 17))])]
""
"")
(define_insn "*umulsi3_highpart_insn"
[(set (match_operand:SI 0 "register_operand" "=d")
(truncate:SI
(lshiftrt:DI
(mult:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "%a"))
(match_operand:SI 1 "nonimmediate_operand" "%a"))
(zero_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "rm")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=a"))
(clobber (match_scratch:SI 3 "=1"))
(clobber (reg:CC 17))]
""
"GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
"mul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
@ -7451,48 +7575,78 @@
(zero_extend:DI (truncate:SI
(lshiftrt:DI
(mult:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "%a"))
(match_operand:SI 1 "nonimmediate_operand" "%a"))
(zero_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "rm")))
(const_int 32)))))
(clobber (match_scratch:SI 3 "=a"))
(clobber (match_scratch:SI 3 "=1"))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"mul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
(set_attr "mode" "SI")])
(define_expand "smuldi3_highpart"
[(parallel [(set (match_operand:DI 0 "register_operand" "=d")
(truncate:DI
(lshiftrt:TI
(mult:TI (sign_extend:TI
(match_operand:DI 1 "nonimmediate_operand" ""))
(sign_extend:TI
(match_operand:DI 2 "register_operand" "")))
(const_int 64))))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
"")
(define_insn "*smuldi3_highpart_rex64"
[(set (match_operand:DI 0 "register_operand" "=d")
(truncate:DI
(lshiftrt:TI
(mult:TI (sign_extend:TI
(match_operand:DI 1 "register_operand" "%a"))
(match_operand:DI 1 "nonimmediate_operand" "%a"))
(sign_extend:TI
(match_operand:DI 2 "nonimmediate_operand" "rm")))
(const_int 64))))
(clobber (match_scratch:DI 3 "=a"))
(clobber (match_scratch:DI 3 "=1"))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"imul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "mode" "DI")])
(define_insn "smulsi3_highpart"
(define_expand "smulsi3_highpart"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(truncate:SI
(lshiftrt:DI
(mult:DI (sign_extend:DI
(match_operand:SI 1 "nonimmediate_operand" ""))
(sign_extend:DI
(match_operand:SI 2 "register_operand" "")))
(const_int 32))))
(clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 17))])]
""
"")
(define_insn "*smulsi3_highpart_insn"
[(set (match_operand:SI 0 "register_operand" "=d")
(truncate:SI
(lshiftrt:DI
(mult:DI (sign_extend:DI
(match_operand:SI 1 "register_operand" "%a"))
(match_operand:SI 1 "nonimmediate_operand" "%a"))
(sign_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "rm")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=a"))
(clobber (match_scratch:SI 3 "=1"))
(clobber (reg:CC 17))]
""
"GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
@ -7503,13 +7657,14 @@
(zero_extend:DI (truncate:SI
(lshiftrt:DI
(mult:DI (sign_extend:DI
(match_operand:SI 1 "register_operand" "%a"))
(match_operand:SI 1 "nonimmediate_operand" "%a"))
(sign_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "rm")))
(const_int 32)))))
(clobber (match_scratch:SI 3 "=a"))
(clobber (match_scratch:SI 3 "=1"))
(clobber (reg:CC 17))]
"TARGET_64BIT"
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
@ -13539,7 +13694,7 @@
simply pretend the untyped call returns a complex long double
value. */
emit_call_insn (TARGET_80387
emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
operands[0], const0_rtx,
GEN_INT (SSE_REGPARM_MAX - 1))
@ -13854,10 +14009,11 @@
(define_insn "*fop_sf_comm_nosse"
[(set (match_operand:SF 0 "register_operand" "=f")
(match_operator:SF 3 "binary_fp_operator"
[(match_operand:SF 1 "register_operand" "%0")
[(match_operand:SF 1 "nonimmediate_operand" "%0")
(match_operand:SF 2 "nonimmediate_operand" "fm")]))]
"TARGET_80387 && !TARGET_SSE_MATH
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(if_then_else (match_operand:SF 3 "mult_operator" "")
@ -13868,10 +14024,11 @@
(define_insn "*fop_sf_comm"
[(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
(match_operator:SF 3 "binary_fp_operator"
[(match_operand:SF 1 "register_operand" "%0,0")
[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
(match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
"TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(if_then_else (eq_attr "alternative" "1")
@ -13884,9 +14041,10 @@
(define_insn "*fop_sf_comm_sse"
[(set (match_operand:SF 0 "register_operand" "=x")
(match_operator:SF 3 "binary_fp_operator"
[(match_operand:SF 1 "register_operand" "%0")
[(match_operand:SF 1 "nonimmediate_operand" "%0")
(match_operand:SF 2 "nonimmediate_operand" "xm")]))]
"TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
"TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set_attr "type" "sse")
(set_attr "mode" "SF")])
@ -13894,10 +14052,11 @@
(define_insn "*fop_df_comm_nosse"
[(set (match_operand:DF 0 "register_operand" "=f")
(match_operator:DF 3 "binary_fp_operator"
[(match_operand:DF 1 "register_operand" "%0")
[(match_operand:DF 1 "nonimmediate_operand" "%0")
(match_operand:DF 2 "nonimmediate_operand" "fm")]))]
"TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(if_then_else (match_operand:SF 3 "mult_operator" "")
@ -13908,10 +14067,11 @@
(define_insn "*fop_df_comm"
[(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
(match_operator:DF 3 "binary_fp_operator"
[(match_operand:DF 1 "register_operand" "%0,0")
[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
(match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
"TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(if_then_else (eq_attr "alternative" "1")
@ -13924,10 +14084,11 @@
(define_insn "*fop_df_comm_sse"
[(set (match_operand:DF 0 "register_operand" "=Y")
(match_operator:DF 3 "binary_fp_operator"
[(match_operand:DF 1 "register_operand" "%0")
[(match_operand:DF 1 "nonimmediate_operand" "%0")
(match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
"TARGET_SSE2 && TARGET_SSE_MATH
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"* return output_387_binary_op (insn, operands);"
[(set_attr "type" "sse")
(set_attr "mode" "DF")])
@ -14561,7 +14722,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(match_operand:DF 1 "register_operand" "0"))))]
"!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
"!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@ -14581,7 +14742,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(match_operand:SF 1 "register_operand" "0"))))]
"!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
"!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@ -14628,7 +14789,7 @@
(define_insn "sinxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
"!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
"!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
@ -15748,8 +15909,8 @@
"TARGET_64BIT && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
cmov%C1\t{%2, %0|%0, %2}
cmov%c1\t{%3, %0|%0, %3}"
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "icmov")
(set_attr "mode" "DI")])
@ -15790,8 +15951,8 @@
"TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
cmov%C1\t{%2, %0|%0, %2}
cmov%c1\t{%3, %0|%0, %3}"
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "icmov")
(set_attr "mode" "SI")])
@ -15812,8 +15973,8 @@
"TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
cmov%C1\t{%2, %0|%0, %2}
cmov%c1\t{%3, %0|%0, %3}"
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "icmov")
(set_attr "mode" "HI")])
@ -15836,8 +15997,8 @@
"@
fcmov%F1\t{%2, %0|%0, %2}
fcmov%f1\t{%3, %0|%0, %3}
cmov%C1\t{%2, %0|%0, %2}
cmov%c1\t{%3, %0|%0, %3}"
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "fcmov,fcmov,icmov,icmov")
(set_attr "mode" "SF,SF,SI,SI")])
@ -15876,8 +16037,8 @@
"@
fcmov%F1\t{%2, %0|%0, %2}
fcmov%f1\t{%3, %0|%0, %3}
cmov%C1\t{%2, %0|%0, %2}
cmov%c1\t{%3, %0|%0, %3}"
cmov%O2%C1\t{%2, %0|%0, %2}
cmov%O2%c1\t{%3, %0|%0, %3}"
[(set_attr "type" "fcmov,fcmov,icmov,icmov")
(set_attr "mode" "DF")])
@ -15965,12 +16126,13 @@
(define_insn "*minsf_nonieee"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC 17))]
"TARGET_SSE && !TARGET_IEEE_FP"
"TARGET_SSE && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
@ -16047,12 +16209,13 @@
(define_insn "*mindf_nonieee"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC 17))]
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
@ -16128,12 +16291,13 @@
(define_insn "*maxsf_nonieee"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC 17))]
"TARGET_SSE && !TARGET_IEEE_FP"
"TARGET_SSE && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
@ -16208,12 +16372,13 @@
(define_insn "*maxdf_nonieee"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC 17))]
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
@ -17945,7 +18110,16 @@
[(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
(match_operand:V8QI 2 "register_operand" "y")] 32))]
"TARGET_SSE || TARGET_3DNOW_A"
"(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
;; @@@ check ordering of operands in intel/nonintel syntax
"maskmovq\t{%2, %1|%1, %2}"
[(set_attr "type" "sse")])
(define_insn "mmx_maskmovq_rex"
[(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
(match_operand:V8QI 2 "register_operand" "y")] 32))]
"(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
;; @@@ check ordering of operands in intel/nonintel syntax
"maskmovq\t{%2, %1|%1, %2}"
[(set_attr "type" "sse")])
@ -18229,17 +18403,19 @@
(define_insn "sse_andti3"
[(set (match_operand:TI 0 "register_operand" "=x")
(and:TI (match_operand:TI 1 "register_operand" "%0")
(and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE && !TARGET_SSE2"
"TARGET_SSE && !TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"andps\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "*sse_andti3_sse2"
[(set (match_operand:TI 0 "register_operand" "=x")
(and:TI (match_operand:TI 1 "register_operand" "%0")
(and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2"
"TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"pand\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
@ -18309,17 +18485,19 @@
(define_insn "sse_iorti3"
[(set (match_operand:TI 0 "register_operand" "=x")
(ior:TI (match_operand:TI 1 "register_operand" "%0")
(ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE && !TARGET_SSE2"
"TARGET_SSE && !TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"orps\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "*sse_iorti3_sse2"
[(set (match_operand:TI 0 "register_operand" "=x")
(ior:TI (match_operand:TI 1 "register_operand" "%0")
(ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2"
"TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"por\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
@ -18357,17 +18535,19 @@
(define_insn "sse_xorti3"
[(set (match_operand:TI 0 "register_operand" "=x")
(xor:TI (match_operand:TI 1 "register_operand" "%0")
(xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE && !TARGET_SSE2"
"TARGET_SSE && !TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"xorps\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "*sse_xorti3_sse2"
[(set (match_operand:TI 0 "register_operand" "=x")
(xor:TI (match_operand:TI 1 "register_operand" "%0")
(xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2"
"TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"pxor\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
@ -18837,14 +19017,14 @@
(plus:V8QI (plus:V8QI
(match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym"))
(vec_const:V8QI (parallel [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_vector:V8QI [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)]))
(const_int 1)))]
"TARGET_SSE || TARGET_3DNOW_A"
"pavgb\t{%2, %0|%0, %2}"
@ -18856,10 +19036,10 @@
(plus:V4HI (plus:V4HI
(match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym"))
(vec_const:V4HI (parallel [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_vector:V4HI [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)]))
(const_int 1)))]
"TARGET_SSE || TARGET_3DNOW_A"
"pavgw\t{%2, %0|%0, %2}"
@ -19573,12 +19753,11 @@
(match_operand:V4HI 1 "register_operand" "0"))
(sign_extend:V4SI
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))
(vec_const:V4SI
(parallel [(const_int 32768)
(const_int 32768)
(const_int 32768)
(const_int 32768)])))
(const_int 16))))]
(const_vector:V4SI [(const_int 32768)
(const_int 32768)
(const_int 32768)
(const_int 32768)]))
(const_int 16))))]
"TARGET_3DNOW"
"pmulhrw\\t{%2, %0|%0, %2}"
[(set_attr "type" "mmx")])

View File

@ -0,0 +1,25 @@
# 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__
%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

View File

@ -1,5 +1,5 @@
/* Definitions for Intel 386 running Linux-based GNU systems using a.out.
Copyright (C) 1992, 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1992, 1994, 1995, 1997, 1998, 2002 Free Software Foundation, Inc.
Contributed by H.J. Lu (hjl@nynexst.com)
This file is part of GNU CC.
@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */
/* Specify predefined symbols in preprocessor. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Dlinux -Asystem=posix"
#define CPP_PREDEFINES "-Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"

View File

@ -1,6 +1,6 @@
/* Definitions for Intel 386 running Linux-based GNU systems with pre-BFD
a.out linkers.
Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1995, 1997, 1998, 2002 Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com)
This file is part of GNU CC.
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
/* Specify predefined symbols in preprocessor. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Dlinux -Asystem=posix"
#define CPP_PREDEFINES "-Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"

View File

@ -85,7 +85,7 @@ Boston, MA 02111-1307, USA. */
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem=posix"
#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -Asystem=posix"
#undef CPP_SPEC
#ifdef USE_GNULIBC_1

View File

@ -1,5 +1,5 @@
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
This file is part of GNU CC.
@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem(posix)"
#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -Asystem(posix)"
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT} %{!m32:-D__LONG_MAX__=9223372036854775807L}"
@ -39,10 +39,96 @@ Boston, MA 02111-1307, USA. */
done. */
#undef LINK_SPEC
#define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} %{shared:-shared} \
#define LINK_SPEC "%{!m32:-m elf_x86_64 -Y P,/usr/lib64} %{m32:-m elf_i386} \
%{shared:-shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}} \
%{static:-static}}"
%{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
%{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
%{static:-static}}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{m32:%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
crti.o%s %{static:crtbeginT.o%s}\
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}} \
%{!m32:%{!shared: \
%{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} \
%{!p:%{profile:/usr/lib64/gcrt1.o%s} %{!profile:/usr/lib64/crt1.o%s}}}}\
/usr/lib64/crti.o%s %{static:crtbeginT.o%s} \
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "\
%{m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s} \
%{!m32:%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s}"
#define MULTILIB_DEFAULTS { "m64" }
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#endif
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
\
/* movq __NR_rt_sigreturn, %rax ; syscall */ \
if (*(unsigned char *)(pc_+0) == 0x48 \
&& *(unsigned long *)(pc_+1) == 0x050f0000000fc0c7) \
{ \
struct ucontext *uc_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &uc_->uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->rsp; \
(FS)->cfa_how = CFA_REG_OFFSET; \
/* Register 7 is rsp */ \
(FS)->cfa_reg = 7; \
(FS)->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_->rbx - 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_->rdx - new_cfa_; \
(FS)->regs.reg[4].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[4].loc.offset = (long)&sc_->rbp - new_cfa_; \
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[5].loc.offset = (long)&sc_->rsi - new_cfa_; \
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[6].loc.offset = (long)&sc_->rdi - 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)->retaddr_column = 16; \
goto SUCCESS; \
} while (0)

View File

@ -51,18 +51,6 @@ Boston, MA 02111-1307, USA. */
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#undef WINT_TYPE
#define WINT_TYPE "int"
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"

View File

@ -22,15 +22,6 @@
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"

View File

@ -1,5 +1,5 @@
/* Definitions for rtems targeting an Intel i386 using coff.
Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
This file is part of GNU CC.
@ -19,19 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "i386/i386-coff.h"
/* Specify predefined symbols in preprocessor. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Drtems -D__rtems__ -Asystem=rtems"
/* Generate calls to memcpy, memcmp and memset. */
#ifndef TARGET_MEM_FUNCTIONS
#define TARGET_MEM_FUNCTIONS
#endif
/* Get machine-independent configuration parameters for RTEMS. */
#include <rtems.h>
/* end of i386/rtems.h */
#define CPP_PREDEFINES "-D__rtems__ -Asystem=rtems"

View File

@ -1,8 +1,6 @@
/* Definitions for Intel 386 running Linux-based GNU systems with ELF format.
Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000
Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
/* Definitions for rtems targeting a ix86 using ELF.
Copyright (C) 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
This file is part of GNU CC.
@ -21,65 +19,13 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define LINUX_DEFAULT_ELF
/* Specify predefined symbols in preprocessor. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 RTEMS with ELF)");
#include <i386/i386elf.h>
/* The svr4 ABI for the i386 says that records and unions are returned
in memory. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ \
if (flag_pic) \
{ \
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \
LPREFIX, (LABELNO)); \
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
} \
else \
{ \
fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \
fprintf (FILE, "\tcall mcount\n"); \
} \
}
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "long int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Drtems -D__rtems__ -Asystem=rtems"
#define CPP_PREDEFINES "-D__rtems__ -Asystem=rtems \
-D__ELF__ -D__i386__ -D__USE_INIT_FINI__"
/* A C statement (sans semicolon) to output to the stdio stream
FILE the assembler definition of uninitialized global DECL named
NAME whose size is SIZE bytes and alignment is ALIGN bytes.
Try to use asm_output_aligned_bss to implement this macro. */
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
/* end of i386/rtemself.h */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{msoft-float:-D_SOFT_FLOAT}"

View File

@ -20,9 +20,6 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "i386/i386.h" /* Base i386 target definitions */
#include "i386/att.h" /* Use AT&T i386 assembler syntax */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386, SCO OpenServer 5 Syntax)");

View File

@ -39,6 +39,8 @@ Boston, MA 02111-1307, USA. */
#define ASM_SPEC \
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s"
#define CMOV_SUN_AS_SYNTAX 1
#else /* GAS_REJECTS_MINUS_S */
/* Same as above, except for -s, unsupported by GNU as. */
@ -73,10 +75,11 @@ Boston, MA 02111-1307, USA. */
#undef WINT_TYPE_SIZE
#define WINT_TYPE_SIZE BITS_PER_WORD
/* Add "sun" to the list of symbols defined for SVR4. */
#define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-Dunix -D__svr4__ -D__SVR4 -Dsun -Asystem=svr4"
"-Dunix -D__svr4__ -D__SVR4 -Dsun -D__PRAGMA_REDEFINE_EXTNAME -Asystem=svr4"
/* Solaris 2/Intel as chokes on #line directives. */
#undef CPP_SPEC
@ -154,3 +157,6 @@ Boston, MA 02111-1307, USA. */
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
/* The Solaris assembler does not support .quad. Do not use it. */
#undef ASM_QUAD

View File

@ -4,5 +4,3 @@ LIB1ASMFUNCS = _chkstk
interix.o: $(srcdir)/config/i386/interix.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/interix.c
# System headers will track gcc's needs.
USER_H=

View File

@ -0,0 +1,15 @@
# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
# override the settings
# from t-slibgcc-elf-ver and t-linux
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
$(srcdir)/config/i386/libgcc-x86_64-glibc.ver
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:

View File

@ -12,3 +12,43 @@ crtn.o: $(srcdir)/config/i386/sol2-cn.asm $(GCC_PASSES)
sed -e '/^!/d' <$(srcdir)/config/i386/sol2-cn.asm >crtn.s
$(GCC_FOR_TARGET) -c -o crtn.o crtn.s
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
FPBIT = fp-bit.c
DPBIT = dp-bit.c
LIB2FUNCS_EXTRA = xp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
echo '#endif' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
xp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define EXTENDED_FLOAT_STUBS' > xp-bit.c
cat $(srcdir)/config/fp-bit.c >> xp-bit.c
MULTILIB_OPTIONS = mcpu=i486/mcpu=pentium/mcpu=pentiumpro/mcpu=k6/mcpu=athlon \
msoft-float mno-fp-ret-in-387
MULTILIB_DIRNAMES= m486 mpentium mpentiumpro k6 athlon soft-float nofp
MULTILIB_MATCHES = msoft-float=mno-m80387
MULTILIB_EXCEPTIONS = \
mno-fp-ret-in-387 \
mcpu=i486/*mno-fp-ret-in-387* \
mcpu=pentium/*msoft-float* mcpu=pentium/*mno-fp-ret-in-387* \
mcpu=pentiumpro/*msoft-float* mcpu=pentiumpro/*mno-fp-ret-in-387* \
mcpu=k6/*msoft-float* mcpu=k6/*mno-fp-ret-in-387* \
mcpu=athlon/*msoft-float* mcpu=athlon/*mno-fp-ret-in-387*
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib

View File

@ -73,7 +73,6 @@ Boston, MA 02111-1307, USA. */
This is used to align code labels according to Intel recommendations. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
if ((LOG) != 0) { \
@ -81,7 +80,6 @@ Boston, MA 02111-1307, USA. */
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
} \
} while (0)
#endif
/* i386 System V Release 4 uses DWARF debugging info.

View File

@ -86,9 +86,9 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "\
-D__ia64 -D__ia64__ -D_AIX -D_AIX64 -D_LONGLONG -Dunix \
-D__LP64__ -D__ELF__ -Asystem=unix -Asystem=aix -Acpu=ia64 -Amachine=ia64 \
-D__64BIT__ -D_LONG_LONG -D_IA64 -D__int128=__size128_t"
-D_AIX -D_AIX64 -D_LONGLONG -Dunix \
-Asystem=unix -Asystem=aix \
-D__64BIT__ -D_LONG_LONG -D_IA64 -D__int128=__size128_t"
/* The GNU C++ standard library requires that these macros be defined. */
#undef CPLUSPLUS_CPP_SPEC
@ -100,10 +100,6 @@ Boston, MA 02111-1307, USA. */
-D__LONG_MAX__=9223372036854775807L \
%{cpp_cpu}"
/* ia64-specific options for gas */
#undef ASM_SPEC
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
/* Define this for shared library support. */
#undef LINK_SPEC
@ -115,14 +111,8 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker /usr/lib/ia64l64/libc.so.1}} \
%{static:-static}}"
#define DONT_USE_BUILTIN_SETJMP
#define JMP_BUF_SIZE 85
/* Output any profiling code before the prologue. */
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
/* A C statement or compound statement to output to FILE some assembler code to
call the profiling subroutine `mcount'.

View File

@ -17,10 +17,12 @@
#if ((TARGET_CPU_DEFAULT | TARGET_DEFAULT) & MASK_GNU_AS) != 0
/* GNU AS. */
#define ASM_SPEC \
"%{mno-gnu-as:-N so} %{!mno-gnu-as:-x} %{mconstant-gp} %{mauto-pic}"
#undef ASM_EXTRA_SPEC
#define ASM_EXTRA_SPEC \
"%{mno-gnu-as:-N so} %{!mno-gnu-as:-x}"
#else
/* Intel ias. */
#undef ASM_SPEC
#define ASM_SPEC \
"%{!mgnu-as:-N so} %{mgnu-as:-x} %{mconstant-gp:-M const_gp}\
%{mauto-pic:-M no_plabel}"

View File

@ -19,7 +19,6 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef LINK_SPEC
#define LINK_SPEC \
"%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{Wl,*:%*} \
@ -32,9 +31,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-Bstatic}}"
#undef ASM_SPEC
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
/************************[ Target stuff ]***********************************/
@ -57,10 +53,4 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define TARGET_ELF 1
#define DONT_USE_BUILTIN_SETJMP
#define JMP_BUF_SIZE 76
/* Output any profiling code before the prologue. */
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1

View File

@ -27,9 +27,9 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "\
-D__IA64__ -D__ia64 -D__ia64__ -D__hpux -D__hpux__ -Dhpux -Dunix \
-D__BIG_ENDIAN__ -D_LONGLONG -D__ELF__ \
-Asystem=hpux -Asystem=posix -Asystem=unix -Acpu=ia64 -Amachine=ia64 \
-D__IA64__ -D__hpux -D__hpux__ -Dhpux -Dunix \
-D__BIG_ENDIAN__ -D_LONGLONG \
-Asystem=hpux -Asystem=posix -Asystem=unix \
-D_UINT128_T"
/* -D__fpreg=long double is needed to compensate for the lack of __fpreg
@ -40,15 +40,14 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "\
%{mcpu=itanium:-D__itanium__} \
%{mlp64:-D__LP64__ -D__LONG_MAX__=9223372036854775807L} \
%{mlp64:-D__LP64__ -D_LP64 -D__LONG_MAX__=9223372036854775807L} \
%{!ansi:%{!std=c*:%{!std=i*: -D_HPUX_SOURCE -D__STDC_EXT__}}} \
-D__fpreg=long\\ double \
-D__float80=long\\ double \
-D__float128=long\\ double"
#undef ASM_SPEC
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} \
%{milp32:-milp32} %{mlp64:-mlp64}"
#undef ASM_EXTRA_SPEC
#define ASM_EXTRA_SPEC "%{milp32:-milp32} %{mlp64:-mlp64}"
#undef ENDFILE_SPEC
@ -84,7 +83,6 @@ Boston, MA 02111-1307, USA. */
#define POINTERS_EXTEND_UNSIGNED -1
#define DONT_USE_BUILTIN_SETJMP
#define JMP_BUF_SIZE (8 * 76)
#undef CONST_SECTION_ASM_OP

View File

@ -113,6 +113,9 @@ extern int ia64_function_arg_partial_nregs PARAMS((CUMULATIVE_ARGS *,
extern void ia64_function_arg_advance PARAMS((CUMULATIVE_ARGS *,
enum machine_mode,
tree, int));
extern int ia64_function_arg_pass_by_reference PARAMS((CUMULATIVE_ARGS *,
enum machine_mode,
tree, int));
extern int ia64_return_in_memory PARAMS((tree));
extern void ia64_asm_output_external PARAMS((FILE *, tree, const char *));
@ -122,6 +125,7 @@ extern void ia64_encode_section_info PARAMS((tree));
extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
enum reg_class));
extern int ia64_epilogue_uses PARAMS((int));
extern int ia64_eh_uses PARAMS((int));
extern void emit_safe_across_calls PARAMS((FILE *));
extern void ia64_init_builtins PARAMS((void));
extern void ia64_override_options PARAMS((void));

View File

@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "real.h"
@ -46,6 +45,7 @@ Boston, MA 02111-1307, USA. */
#include "timevar.h"
#include "target.h"
#include "target-def.h"
#include "tm_p.h"
/* This is used for communication between ASM_OUTPUT_LABEL and
ASM_OUTPUT_LABELREF. */
@ -138,7 +138,6 @@ static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode, int,
static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
tree, rtx));
static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));
const struct attribute_spec ia64_attribute_table[];
static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
@ -156,6 +155,14 @@ static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
static rtx ia64_cycle_display PARAMS ((int, rtx));
/* Table of valid machine attributes. */
static const struct attribute_spec ia64_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "syscall_linkage", 0, 0, false, true, true, NULL },
{ NULL, 0, 0, false, false, false, NULL }
};
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
@ -1137,7 +1144,8 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
rtx nextarg;
int sibcall_p;
{
rtx insn, b0, pfs, gp_save, narg_rtx;
rtx insn, b0, pfs, gp_save, narg_rtx, dest;
bool indirect_p;
int narg;
addr = XEXP (addr, 0);
@ -1164,61 +1172,36 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
return;
}
if (sibcall_p)
indirect_p = ! symbolic_operand (addr, VOIDmode);
if (sibcall_p || (TARGET_CONST_GP && !indirect_p))
gp_save = NULL_RTX;
else
gp_save = ia64_gp_save_reg (setjmp_operand (addr, VOIDmode));
if (gp_save)
emit_move_insn (gp_save, pic_offset_table_rtx);
/* If this is an indirect call, then we have the address of a descriptor. */
if (! symbolic_operand (addr, VOIDmode))
if (indirect_p)
{
rtx dest;
if (! sibcall_p)
emit_move_insn (gp_save, pic_offset_table_rtx);
dest = force_reg (DImode, gen_rtx_MEM (DImode, addr));
emit_move_insn (pic_offset_table_rtx,
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
if (sibcall_p)
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_pic (dest, narg_rtx, b0);
else
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
emit_call_insn (insn);
if (! sibcall_p)
emit_move_insn (pic_offset_table_rtx, gp_save);
}
else if (TARGET_CONST_GP)
{
if (sibcall_p)
insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_nopic (addr, narg_rtx, b0);
else
insn = gen_call_value_nopic (retval, addr, narg_rtx, b0);
emit_call_insn (insn);
}
else
{
if (sibcall_p)
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
else
{
emit_move_insn (gp_save, pic_offset_table_rtx);
dest = addr;
if (! retval)
insn = gen_call_pic (addr, narg_rtx, b0);
else
insn = gen_call_value_pic (retval, addr, narg_rtx, b0);
emit_call_insn (insn);
if (sibcall_p)
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_pic (dest, narg_rtx, b0);
else
insn = gen_call_value_pic (retval, dest, narg_rtx, b0);
emit_call_insn (insn);
emit_move_insn (pic_offset_table_rtx, gp_save);
}
}
if (gp_save)
emit_move_insn (pic_offset_table_rtx, gp_save);
}
/* Begin the assembly file. */
@ -2040,7 +2023,7 @@ ia64_expand_prologue ()
/* We don't need an alloc instruction if we've used no outputs or locals. */
if (current_frame_info.n_local_regs == 0
&& current_frame_info.n_output_regs == 0
&& current_frame_info.n_input_regs <= current_function_args_info.words)
&& current_frame_info.n_input_regs <= current_function_args_info.int_regs)
{
/* If there is no alloc, but there are input registers used, then we
need a .regstk directive. */
@ -2873,7 +2856,7 @@ hfa_element_mode (type, nested)
return VOIDmode;
case ARRAY_TYPE:
return TYPE_MODE (TREE_TYPE (type));
return hfa_element_mode (TREE_TYPE (type), 1);
case RECORD_TYPE:
case UNION_TYPE:
@ -3181,14 +3164,14 @@ ia64_function_arg_advance (cum, mode, type, named)
FR registers, then FP values must also go in general registers. This can
happen when we have a SFmode HFA. */
else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
return;
cum->int_regs = cum->words;
/* If there is a prototype, then FP values go in a FR register when
named, and in a GR registeer when unnamed. */
else if (cum->prototype)
{
if (! named)
return;
cum->int_regs = cum->words;
else
/* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
@ -3196,10 +3179,24 @@ ia64_function_arg_advance (cum, mode, type, named)
/* If there is no prototype, then FP values go in both FR and GR
registers. */
else
/* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
{
/* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
cum->int_regs = cum->words;
}
}
return;
/* Variable sized types are passed by reference. */
/* ??? At present this is a GCC extension to the IA-64 ABI. */
int
ia64_function_arg_pass_by_reference (cum, mode, type, named)
CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
tree type;
int named ATTRIBUTE_UNUSED;
{
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
}
/* Implement va_start. */
@ -3232,6 +3229,13 @@ ia64_va_arg (valist, type)
{
tree t;
/* Variable sized types are passed by reference. */
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
}
/* Arguments with alignment larger than 8 bytes start at the next even
boundary. */
if (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
@ -4765,6 +4769,7 @@ group_barrier_needed_p (insn)
/* We play dependency tricks with the epilogue in order
to get proper schedules. Undo this for dv analysis. */
case CODE_FOR_epilogue_deallocate_stack:
case CODE_FOR_prologue_allocate_stack:
pat = XVECEXP (pat, 0, 0);
break;
@ -5236,21 +5241,22 @@ ia64_single_set (insn)
x = COND_EXEC_CODE (x);
if (GET_CODE (x) == SET)
return x;
ret = single_set_2 (insn, x);
if (ret == NULL && GET_CODE (x) == PARALLEL)
/* Special case here prologue_allocate_stack and epilogue_deallocate_stack.
Although they are not classical single set, the second set is there just
to protect it from moving past FP-relative stack accesses. */
switch (recog_memoized (insn))
{
/* Special case here prologue_allocate_stack and
epilogue_deallocate_stack. Although it is not a classical
single set, the second set is there just to protect it
from moving past FP-relative stack accesses. */
if (XVECLEN (x, 0) == 2
&& GET_CODE (XVECEXP (x, 0, 0)) == SET
&& GET_CODE (XVECEXP (x, 0, 1)) == SET
&& GET_CODE (SET_DEST (XVECEXP (x, 0, 1))) == REG
&& SET_DEST (XVECEXP (x, 0, 1)) == SET_SRC (XVECEXP (x, 0, 1))
&& ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IALU)
ret = XVECEXP (x, 0, 0);
case CODE_FOR_prologue_allocate_stack:
case CODE_FOR_epilogue_deallocate_stack:
ret = XVECEXP (x, 0, 0);
break;
default:
ret = single_set_2 (insn, x);
break;
}
return ret;
}
@ -5348,6 +5354,7 @@ ia64_adjust_cost (insn, link, dep_insn, cost)
if (reg_overlap_mentioned_p (SET_DEST (set), addr))
return cost + 1;
}
if ((dep_class == ITANIUM_CLASS_IALU
|| dep_class == ITANIUM_CLASS_ILOG
|| dep_class == ITANIUM_CLASS_LD)
@ -5355,25 +5362,28 @@ ia64_adjust_cost (insn, link, dep_insn, cost)
|| insn_class == ITANIUM_CLASS_MMSHF
|| insn_class == ITANIUM_CLASS_MMSHFI))
return 3;
if (dep_class == ITANIUM_CLASS_FMAC
&& (insn_class == ITANIUM_CLASS_FMISC
|| insn_class == ITANIUM_CLASS_FCVTFX
|| insn_class == ITANIUM_CLASS_XMPY))
return 7;
if ((dep_class == ITANIUM_CLASS_FMAC
|| dep_class == ITANIUM_CLASS_FMISC
|| dep_class == ITANIUM_CLASS_FCVTFX
|| dep_class == ITANIUM_CLASS_XMPY)
&& insn_class == ITANIUM_CLASS_STF)
return 8;
/* Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
but HP engineers say any non-MM operation. */
if ((dep_class == ITANIUM_CLASS_MMMUL
|| dep_class == ITANIUM_CLASS_MMSHF
|| dep_class == ITANIUM_CLASS_MMSHFI)
&& (insn_class == ITANIUM_CLASS_LD
|| insn_class == ITANIUM_CLASS_ST
|| insn_class == ITANIUM_CLASS_IALU
|| insn_class == ITANIUM_CLASS_ILOG
|| insn_class == ITANIUM_CLASS_ISHF))
&& insn_class != ITANIUM_CLASS_MMMUL
&& insn_class != ITANIUM_CLASS_MMSHF
&& insn_class != ITANIUM_CLASS_MMSHFI)
return 4;
return cost;
@ -5475,32 +5485,6 @@ ia64_emit_insn_before (insn, before)
emit_insn_before (insn, before);
}
#if 0
/* Generate a nop insn of the given type. Note we never generate L type
nops. */
static rtx
gen_nop_type (t)
enum attr_type t;
{
switch (t)
{
case TYPE_M:
return gen_nop_m ();
case TYPE_I:
return gen_nop_i ();
case TYPE_B:
return gen_nop_b ();
case TYPE_F:
return gen_nop_f ();
case TYPE_X:
return gen_nop_x ();
default:
abort ();
}
}
#endif
/* When rotating a bundle out of the issue window, insert a bundle selector
insn in front of it. DUMP is the scheduling dump file or NULL. START
is either 0 or 3, depending on whether we want to emit a bundle selector
@ -5565,8 +5549,8 @@ cycle_end_fill_slots (dump)
if (slot > sched_data.split)
abort ();
if (dump)
fprintf (dump, "// Packet needs %s, have %s\n", type_names[packet->t[slot]],
type_names[t]);
fprintf (dump, "// Packet needs %s, have %s\n",
type_names[packet->t[slot]], type_names[t]);
sched_data.types[slot] = packet->t[slot];
sched_data.insns[slot] = 0;
sched_data.stopbit[slot] = 0;
@ -5578,15 +5562,22 @@ cycle_end_fill_slots (dump)
slot++;
}
/* Do _not_ use T here. If T == TYPE_A, then we'd risk changing the
actual slot type later. */
sched_data.types[slot] = packet->t[slot];
sched_data.insns[slot] = tmp_insns[i];
sched_data.stopbit[slot] = 0;
slot++;
/* TYPE_L instructions always fill up two slots. */
if (t == TYPE_L)
slot++;
{
sched_data.types[slot] = packet->t[slot];
sched_data.insns[slot] = 0;
sched_data.stopbit[slot] = 0;
slot++;
}
}
/* This isn't right - there's no need to pad out until the forced split;
@ -5629,6 +5620,8 @@ rotate_one_bundle (dump)
memmove (sched_data.insns,
sched_data.insns + 3,
sched_data.cur * sizeof *sched_data.insns);
sched_data.packet
= &packets[(sched_data.packet->t2 - bundle) * NR_BUNDLES];
}
else
{
@ -6060,6 +6053,7 @@ static void
maybe_rotate (dump)
FILE *dump;
{
cycle_end_fill_slots (dump);
if (sched_data.cur == 6)
rotate_two_bundles (dump);
else if (sched_data.cur >= 3)
@ -6074,12 +6068,6 @@ static int prev_cycle;
value of sched_data.first_slot. */
static int prev_first;
/* The last insn that has been scheduled. At the start of a new cycle
we know that we can emit new insns after it; the main scheduling code
has already emitted a cycle_display insn after it and is using that
as its current last insn. */
static rtx last_issued;
/* Emit NOPs to fill the delay between PREV_CYCLE and CLOCK_VAR. Used to
pad out the delay between MM (shifts, etc.) and integer operations. */
@ -6090,12 +6078,13 @@ nop_cycles_until (clock_var, dump)
{
int prev_clock = prev_cycle;
int cycles_left = clock_var - prev_clock;
bool did_stop = false;
/* Finish the previous cycle; pad it out with NOPs. */
if (sched_data.cur == 3)
{
rtx t = gen_insn_group_barrier (GEN_INT (3));
last_issued = emit_insn_after (t, last_issued);
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
did_stop = true;
maybe_rotate (dump);
}
else if (sched_data.cur > 0)
@ -6114,12 +6103,9 @@ nop_cycles_until (clock_var, dump)
int i;
for (i = sched_data.cur; i < split; i++)
{
rtx t;
t = gen_nop_type (sched_data.packet->t[i]);
last_issued = emit_insn_after (t, last_issued);
sched_data.types[i] = sched_data.packet->t[sched_data.cur];
sched_data.insns[i] = last_issued;
rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
sched_data.types[i] = sched_data.packet->t[i];
sched_data.insns[i] = t;
sched_data.stopbit[i] = 0;
}
sched_data.cur = split;
@ -6131,12 +6117,9 @@ nop_cycles_until (clock_var, dump)
int i;
for (i = sched_data.cur; i < 6; i++)
{
rtx t;
t = gen_nop_type (sched_data.packet->t[i]);
last_issued = emit_insn_after (t, last_issued);
sched_data.types[i] = sched_data.packet->t[sched_data.cur];
sched_data.insns[i] = last_issued;
rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
sched_data.types[i] = sched_data.packet->t[i];
sched_data.insns[i] = t;
sched_data.stopbit[i] = 0;
}
sched_data.cur = 6;
@ -6146,8 +6129,8 @@ nop_cycles_until (clock_var, dump)
if (need_stop || sched_data.cur == 6)
{
rtx t = gen_insn_group_barrier (GEN_INT (3));
last_issued = emit_insn_after (t, last_issued);
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
did_stop = true;
}
maybe_rotate (dump);
}
@ -6155,24 +6138,22 @@ nop_cycles_until (clock_var, dump)
cycles_left--;
while (cycles_left > 0)
{
rtx t = gen_bundle_selector (GEN_INT (0));
last_issued = emit_insn_after (t, last_issued);
t = gen_nop_type (TYPE_M);
last_issued = emit_insn_after (t, last_issued);
t = gen_nop_type (TYPE_I);
last_issued = emit_insn_after (t, last_issued);
sched_emit_insn (gen_bundle_selector (GEN_INT (0)));
sched_emit_insn (gen_nop_type (TYPE_M));
sched_emit_insn (gen_nop_type (TYPE_I));
if (cycles_left > 1)
{
t = gen_insn_group_barrier (GEN_INT (2));
last_issued = emit_insn_after (t, last_issued);
sched_emit_insn (gen_insn_group_barrier (GEN_INT (2)));
cycles_left--;
}
t = gen_nop_type (TYPE_I);
last_issued = emit_insn_after (t, last_issued);
t = gen_insn_group_barrier (GEN_INT (3));
last_issued = emit_insn_after (t, last_issued);
sched_emit_insn (gen_nop_type (TYPE_I));
sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
did_stop = true;
cycles_left--;
}
if (did_stop)
init_insn_group_barriers ();
}
/* We are about to being issuing insns for this clock cycle.
@ -6198,31 +6179,34 @@ ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
dump_current_packet (dump);
}
/* Work around the pipeline flush that will occurr if the results of
an MM instruction are accessed before the result is ready. Intel
documentation says this only happens with IALU, ISHF, ILOG, LD,
and ST consumers, but experimental evidence shows that *any* non-MM
type instruction will incurr the flush. */
if (reorder_type == 0 && clock_var > 0 && ia64_final_schedule)
{
for (insnp = ready; insnp < e_ready; insnp++)
{
rtx insn = *insnp;
rtx insn = *insnp, link;
enum attr_itanium_class t = ia64_safe_itanium_class (insn);
if (t == ITANIUM_CLASS_IALU || t == ITANIUM_CLASS_ISHF
|| t == ITANIUM_CLASS_ILOG
|| t == ITANIUM_CLASS_LD || t == ITANIUM_CLASS_ST)
{
rtx link;
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) != REG_DEP_OUTPUT
&& REG_NOTE_KIND (link) != REG_DEP_ANTI)
if (t == ITANIUM_CLASS_MMMUL
|| t == ITANIUM_CLASS_MMSHF
|| t == ITANIUM_CLASS_MMSHFI)
continue;
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == 0)
{
rtx other = XEXP (link, 0);
enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
if (t0 == ITANIUM_CLASS_MMSHF || t0 == ITANIUM_CLASS_MMMUL)
{
rtx other = XEXP (link, 0);
enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
if (t0 == ITANIUM_CLASS_MMSHF
|| t0 == ITANIUM_CLASS_MMMUL)
{
nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
goto out;
}
nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
goto out;
}
}
}
}
}
out:
@ -6486,8 +6470,6 @@ ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
{
enum attr_type t = ia64_safe_type (insn);
last_issued = insn;
if (sched_data.last_was_stop)
{
int t = sched_data.first_slot;
@ -6833,13 +6815,33 @@ ia64_epilogue_uses (regno)
}
}
/* Table of valid machine attributes. */
const struct attribute_spec ia64_attribute_table[] =
/* Return true if REGNO is used by the frame unwinder. */
int
ia64_eh_uses (regno)
int regno;
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "syscall_linkage", 0, 0, false, true, true, NULL },
{ NULL, 0, 0, false, false, false, NULL }
};
if (! reload_completed)
return 0;
if (current_frame_info.reg_save_b0
&& regno == current_frame_info.reg_save_b0)
return 1;
if (current_frame_info.reg_save_pr
&& regno == current_frame_info.reg_save_pr)
return 1;
if (current_frame_info.reg_save_ar_pfs
&& regno == current_frame_info.reg_save_ar_pfs)
return 1;
if (current_frame_info.reg_save_ar_unat
&& regno == current_frame_info.reg_save_ar_unat)
return 1;
if (current_frame_info.reg_save_ar_lc
&& regno == current_frame_info.reg_save_ar_lc)
return 1;
return 0;
}
/* For ia64, SYMBOL_REF_FLAG set means that it is a function.

View File

@ -31,12 +31,19 @@ Boston, MA 02111-1307, USA. */
/* Run-time target specifications */
#define CPP_CPU_SPEC "\
-Acpu=ia64 -Amachine=ia64 \
%{!ansi:%{!std=c*:%{!std=i*:-Dia64}}} -D__ia64 -D__ia64__"
#define EXTRA_SPECS \
{ "cpp_cpu", CPP_CPU_SPEC }, \
{ "asm_extra", ASM_EXTRA_SPEC },
#define CPP_CPU_SPEC " \
-Acpu=ia64 -Amachine=ia64 -D__ia64 -D__ia64__ %{!milp32:-D_LP64 -D__LP64__} \
-D__ELF__"
#define CC1_SPEC "%(cc1_cpu) "
#define ASM_EXTRA_SPEC ""
/* This declaration should be present. */
extern int target_flags;
@ -203,6 +210,7 @@ extern const char *ia64_fixed_range_string;
defines in other tm.h files. */
#define CPP_SPEC \
"%{mcpu=itanium:-D__itanium__} %{mbig-endian:-D__BIG_ENDIAN__} \
%(cpp_cpu) \
-D__LONG_MAX__=9223372036854775807L"
/* This is always "long" so it doesn't "change" in ILP32 vs. LP64. */
@ -340,7 +348,7 @@ while (0)
/* By default, the C++ compiler will use function addresses in the
vtable entries. Setting this non-zero tells the compiler to use
function descriptors instead. The value of this macro says how
many words wide the descriptor is (normally 2). It is assumed
many words wide the descriptor is (normally 2). It is assumed
that the address of a function descriptor may be treated as a
pointer to a function. */
#define TARGET_VTABLE_USES_DESCRIPTORS 2
@ -397,7 +405,7 @@ while (0)
/* Register Basics */
/* Number of hardware registers known to the compiler.
/* Number of hardware registers known to the compiler.
We have 128 general registers, 128 floating point registers,
64 predicate registers, 8 branch registers, one frame pointer,
and several "application" registers. */
@ -459,7 +467,7 @@ while (0)
f0: constant 0.0
f1: constant 1.0
p0: constant true
fp: eliminable frame pointer */
fp: eliminable frame pointer */
/* The last 16 stacked regs are reserved for the 8 input and 8 output
registers. */
@ -529,12 +537,12 @@ while (0)
1, 1, 1, 1, 1, 0, 1 \
}
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
problem which makes CALL_USED_REGISTERS *always* include
all the FIXED_REGISTERS. Until this problem has been
all the FIXED_REGISTERS. Until this problem has been
resolved this macro can be used to overcome this situation.
In particular, block_propagate() requires this list
be acurate, or we can remove registers which should be live.
In particular, block_propagate() requires this list
be acurate, or we can remove registers which should be live.
This macro is used in regs_invalidated_by_call. */
#define CALL_REALLY_USED_REGISTERS \
@ -1151,6 +1159,14 @@ enum reg_class
in it. */
#define ARG_POINTER_REGNUM R_GR(0)
/* Due to the way varargs and argument spilling happens, the argument
pointer is not 16-byte aligned like the stack pointer. */
#define INIT_EXPANDERS \
do { \
if (cfun && cfun->emit->regno_pointer_align) \
REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = 64; \
} while (0)
/* The register number for the return address register. For IA-64, this
is not actually a pointer as the name suggests, but that's a name that
gen_rtx_REG already takes care to keep unique. We modify
@ -1258,7 +1274,8 @@ enum reg_class
pointer is passed in whatever way is appropriate for passing a pointer to
that type. */
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the type
@ -1267,6 +1284,7 @@ enum reg_class
typedef struct ia64_args
{
int words; /* # words of arguments so far */
int int_regs; /* # GR registers used so far */
int fp_regs; /* # FR registers used so far */
int prototype; /* whether function prototyped */
} CUMULATIVE_ARGS;
@ -1277,6 +1295,7 @@ typedef struct ia64_args
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
do { \
(CUM).words = 0; \
(CUM).int_regs = 0; \
(CUM).fp_regs = 0; \
(CUM).prototype = ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)) || (LIBNAME); \
} while (0)
@ -1290,6 +1309,7 @@ do { \
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
do { \
(CUM).words = 0; \
(CUM).int_regs = 0; \
(CUM).fp_regs = 0; \
(CUM).prototype = 1; \
} while (0)
@ -1355,7 +1375,7 @@ do { \
#define FUNCTION_VALUE_REGNO_P(REGNO) \
(((REGNO) >= GR_RET_FIRST && (REGNO) <= GR_RET_LAST) \
|| ((REGNO) >= FR_RET_FIRST && (REGNO) <= FR_RET_LAST))
|| ((REGNO) >= FR_RET_FIRST && (REGNO) <= FR_RET_LAST))
/* How Large Values are Returned */
@ -1404,6 +1424,10 @@ do { \
#define EPILOGUE_USES(REGNO) ia64_epilogue_uses (REGNO)
/* Nonzero for registers used by the exception handling mechanism. */
#define EH_USES(REGNO) ia64_eh_uses (REGNO)
/* Output at beginning of assembler file. */
#define ASM_FILE_START(FILE) \
@ -1722,7 +1746,7 @@ do { \
|| (CLASS) == GR_AND_FR_REGS ? 4 : 10)
/* A C expression for the cost of a branch instruction. A value of 1 is the
default; other values are interpreted relative to that. Used by the
default; other values are interpreted relative to that. Used by the
if-conversion code as max instruction count. */
/* ??? This requires investigation. The primary effect might be how
many additional insn groups we run into, vs how good the dynamic
@ -2273,7 +2297,7 @@ do { \
fprintf (FILE, "[.%s%d:]\n", PREFIX, NUM)
/* Use section-relative relocations for debugging offsets. Unlike other
targets that fake this by putting the section VMA at 0, IA-64 has
targets that fake this by putting the section VMA at 0, IA-64 has
proper relocations for them. */
#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL) \
do { \
@ -2527,4 +2551,11 @@ enum fetchop_code {
IA64_ADD_OP, IA64_SUB_OP, IA64_OR_OP, IA64_AND_OP, IA64_XOR_OP, IA64_NAND_OP
};
#define DONT_USE_BUILTIN_SETJMP
/* Output any profiling code before the prologue. */
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
/* End of ia64.h */

View File

@ -4848,7 +4848,7 @@
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
(match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
(set (match_operand:DI 3 "register_operand" "=r,r,r")
(set (match_operand:DI 3 "register_operand" "+r,r,r")
(match_dup 3))]
""
"@
@ -5045,6 +5045,37 @@
[(set_attr "itanium_class" "stop_bit")
(set_attr "predicable" "no")])
(define_expand "trap"
[(trap_if (const_int 1) (const_int 0))]
""
"")
;; ??? We don't have a match-any slot type. Setting the type to unknown
;; produces worse code that setting the slot type to A.
(define_insn "*trap"
[(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
""
"break %0"
[(set_attr "itanium_class" "chk_s")])
(define_expand "conditional_trap"
[(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
""
{
operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
})
(define_insn "*conditional_trap"
[(trap_if (match_operator 0 "predicate_operator"
[(match_operand:BI 1 "register_operand" "c")
(const_int 0)])
(match_operand 2 "const_int_operand" ""))]
""
"(%J0) break %2"
[(set_attr "itanium_class" "chk_s")
(set_attr "predicable" "no")])
(define_insn "break_f"
[(unspec_volatile [(const_int 0)] 3)]
""

View File

@ -11,12 +11,8 @@
/* ??? Maybe this should be in sysv4.h? */
#define CPP_PREDEFINES "\
-D__ia64 -D__ia64__ -D__linux -D__linux__ -D_LONGLONG -Dlinux -Dunix \
-D__LP64__ -D__ELF__ -Asystem=linux -Acpu=ia64 -Amachine=ia64"
/* ??? ia64 gas doesn't accept standard svr4 assembler options? */
#undef ASM_SPEC
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
-D__gnu_linux__ -D__linux -D__linux__ -D_LONGLONG \
-Dlinux -Dunix -Asystem=linux"
/* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
#undef STARTFILE_SPEC
@ -46,14 +42,8 @@
%{static:-static}}"
#define DONT_USE_BUILTIN_SETJMP
#define JMP_BUF_SIZE 76
/* Output any profiling code before the prologue. */
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
/* Override linux.h LINK_EH_SPEC definition.
Signalize that because we have fde-glibc, we don't need all C shared libs
linked against -lgcc_s. */
@ -98,10 +88,16 @@
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
(CONTEXT)->bsp = sc_->sc_ar_bsp; \
(CONTEXT)->pr = sc_->sc_pr; \
(CONTEXT)->psp = sc_->sc_gr[12]; \
(CONTEXT)->gp = sc_->sc_gr[1]; \
/* Signal frame doesn't have an associated reg. stack frame \
other than what we adjust for below. */ \
(FS) -> no_reg_stack_frame = 1; \
\
/* Don't touch the branch registers. The kernel doesn't \
/* Don't touch the branch registers o.t. b0. The kernel doesn't \
pass the preserved branch registers in the sigcontext but \
leaves them intact, so there's no need to do anything \
with them here. */ \

View File

@ -22,6 +22,11 @@
#undef ASCII_DATA_ASM_OP
#define ASCII_DATA_ASM_OP "\tstring\t"
/* ia64-specific options for gas
??? ia64 gas doesn't accept standard svr4 assembler options? */
#undef ASM_SPEC
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} %(asm_extra)"
/* ??? Unfortunately, .lcomm doesn't work, because it puts things in either
.bss or .sbss, and we can't control the decision of which is used. When
I use .lcomm, I get a cryptic "Section group has no member" error from

View File

@ -35,6 +35,10 @@
#include "tsystem.h"
#include "unwind.h"
#include "unwind-ia64.h"
#include "ia64intrin.h"
/* This isn't thread safe, but nice for occasional tests. */
#undef ENABLE_MALLOC_CHECKING
#ifndef __USING_SJLJ_EXCEPTIONS__
#define UNW_VER(x) ((x) >> 48)
@ -121,13 +125,24 @@ struct unw_reg_info
int when; /* when the register gets saved */
};
struct unw_reg_state {
struct unw_reg_state *next; /* next (outer) element on state stack */
struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
};
struct unw_labeled_state {
struct unw_labeled_state *next; /* next labeled state (or NULL) */
unsigned long label; /* label for this state */
struct unw_reg_state saved_state;
};
typedef struct unw_state_record
{
unsigned int first_region : 1; /* is this the first region? */
unsigned int done : 1; /* are we done scanning descriptors? */
unsigned int any_spills : 1; /* got any register spills? */
unsigned int in_body : 1; /* are we inside a body? */
unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */
unsigned char *imask; /* imask of of spill_mask record or NULL */
unsigned long pr_val; /* predicate values */
unsigned long pr_mask; /* predicate mask */
@ -141,11 +156,8 @@ typedef struct unw_state_record
unsigned char gr_save_loc; /* next general register to use for saving */
unsigned char return_link_reg; /* branch register for return link */
struct unw_reg_state {
struct unw_reg_state *next;
unsigned long label; /* label of this state record */
struct unw_reg_info reg[UNW_NUM_REGS];
} curr, *stack, *reg_state_list;
struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state curr; /* current state */
_Unwind_Personality_Fn personality;
@ -184,9 +196,12 @@ struct _Unwind_Context
void *lsda; /* language specific data area */
/* Preserved state. */
unsigned long *bsp_loc; /* previous bsp save location */
unsigned long *bsp_loc; /* previous bsp save location
Appears to be write-only? */
unsigned long *bspstore_loc;
unsigned long *pfs_loc;
unsigned long *pfs_loc; /* Save location for pfs in current
(corr. to sp) frame. Target
contains cfm for caller. */
unsigned long *pri_unat_loc;
unsigned long *unat_loc;
unsigned long *lc_loc;
@ -226,29 +241,197 @@ static unsigned char const save_order[] =
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
/* Unwind decoder routines */
/* MASK is a bitmap describing the allocation state of emergency buffers,
with bit set indicating free. Return >= 0 if allocation is successful;
< 0 if failure. */
static inline int
atomic_alloc (unsigned int *mask)
{
unsigned int old = *mask, ret, new;
while (1)
{
if (old == 0)
return -1;
ret = old & -old;
new = old & ~ret;
new = __sync_val_compare_and_swap (mask, old, new);
if (old == new)
break;
old = new;
}
return __builtin_ffs (ret) - 1;
}
/* Similarly, free an emergency buffer. */
static inline void
atomic_free (unsigned int *mask, int bit)
{
__sync_xor_and_fetch (mask, 1 << bit);
}
#define SIZE(X) (sizeof(X) / sizeof(*(X)))
#define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
#define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
static struct unw_reg_state emergency_reg_state[32];
static int emergency_reg_state_free = MASK_FOR (emergency_reg_state);
static struct unw_labeled_state emergency_labeled_state[8];
static int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state);
#ifdef ENABLE_MALLOC_CHECKING
static int reg_state_alloced;
static int labeled_state_alloced;
#endif
/* Allocation and deallocation of structures. */
static struct unw_reg_state *
alloc_reg_state (void)
{
struct unw_reg_state *rs;
#ifdef ENABLE_MALLOC_CHECKING
reg_state_alloced++;
#endif
rs = malloc (sizeof (struct unw_reg_state));
if (!rs)
{
int n = atomic_alloc (&emergency_reg_state_free);
if (n >= 0)
rs = &emergency_reg_state[n];
}
return rs;
}
static void
free_reg_state (struct unw_reg_state *rs)
{
#ifdef ENABLE_MALLOC_CHECKING
reg_state_alloced--;
#endif
if (PTR_IN (emergency_reg_state, rs))
atomic_free (&emergency_reg_state_free, rs - emergency_reg_state);
else
free (rs);
}
static struct unw_labeled_state *
alloc_label_state (void)
{
struct unw_labeled_state *ls;
#ifdef ENABLE_MALLOC_CHECKING
labeled_state_alloced++;
#endif
ls = malloc(sizeof(struct unw_labeled_state));
if (!ls)
{
int n = atomic_alloc (&emergency_labeled_state_free);
if (n >= 0)
ls = &emergency_labeled_state[n];
}
return ls;
}
static void
free_label_state (struct unw_labeled_state *ls)
{
#ifdef ENABLE_MALLOC_CHECKING
labeled_state_alloced--;
#endif
if (PTR_IN (emergency_labeled_state, ls))
atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls);
else
free (ls);
}
/* Routines to manipulate the state stack. */
static void
push (struct unw_state_record *sr)
{
struct unw_reg_state *rs;
rs = malloc (sizeof (struct unw_reg_state));
struct unw_reg_state *rs = alloc_reg_state ();
memcpy (rs, &sr->curr, sizeof (*rs));
rs->next = sr->stack;
sr->stack = rs;
sr->curr.next = rs;
}
static void
pop (struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_reg_state *rs = sr->curr.next;
rs = sr->stack;
sr->stack = rs->next;
free (rs);
if (!rs)
abort ();
memcpy (&sr->curr, rs, sizeof(*rs));
free_reg_state (rs);
}
/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
static struct unw_reg_state *
dup_state_stack (struct unw_reg_state *rs)
{
struct unw_reg_state *copy, *prev = NULL, *first = NULL;
while (rs)
{
copy = alloc_reg_state ();
memcpy (copy, rs, sizeof(*copy));
if (first)
prev->next = copy;
else
first = copy;
rs = rs->next;
prev = copy;
}
return first;
}
/* Free all stacked register states (but not RS itself). */
static void
free_state_stack (struct unw_reg_state *rs)
{
struct unw_reg_state *p, *next;
for (p = rs->next; p != NULL; p = next)
{
next = p->next;
free_reg_state (p);
}
rs->next = NULL;
}
/* Free all labeled states. */
static void
free_label_states (struct unw_labeled_state *ls)
{
struct unw_labeled_state *next;
for (; ls ; ls = next)
{
next = ls->next;
free_state_stack (&ls->saved_state);
free_label_state (ls);
}
}
/* Unwind decoder routines */
static enum unw_register_index __attribute__((const))
decode_abreg (unsigned char abreg, int memory)
{
@ -295,8 +478,8 @@ alloc_spill_area (unsigned long *offp, unsigned long regsize,
if (reg->where == UNW_WHERE_SPILL_HOME)
{
reg->where = UNW_WHERE_PSPREL;
reg->val = 0x10 - *offp;
*offp += regsize;
*offp -= regsize;
reg->val = *offp;
}
}
}
@ -330,7 +513,7 @@ finish_prologue (struct unw_state_record *sr)
/* First, resolve implicit register save locations
(see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
for (i = 0; i < (int) sizeof(save_order); ++i)
for (i = 0; i < (int) sizeof (save_order); ++i)
{
reg = sr->curr.reg + save_order[i];
if (reg->where == UNW_WHERE_GR_SAVE)
@ -363,8 +546,8 @@ finish_prologue (struct unw_state_record *sr)
mask = *cp++;
kind = (mask >> 2*(3-(t & 3))) & 3;
if (kind > 0)
spill_next_when(&regs[kind - 1], sr->curr.reg + limit[kind - 1],
sr->region_start + t);
spill_next_when (&regs[kind - 1], sr->curr.reg + limit[kind - 1],
sr->region_start + t);
}
}
@ -372,12 +555,12 @@ finish_prologue (struct unw_state_record *sr)
if (sr->any_spills)
{
off = sr->spill_offset;
alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2,
sr->curr.reg + UNW_REG_F31);
alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1,
sr->curr.reg + UNW_REG_B5);
alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4,
sr->curr.reg + UNW_REG_R7);
alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2,
sr->curr.reg + UNW_REG_F31);
alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1,
sr->curr.reg + UNW_REG_B5);
alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4,
sr->curr.reg + UNW_REG_R7);
}
}
@ -392,23 +575,24 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
int i;
if (!(sr->in_body || sr->first_region))
finish_prologue(sr);
finish_prologue (sr);
sr->first_region = 0;
/* Check if we're done. */
if (body && sr->when_target < sr->region_start + sr->region_len)
if (sr->when_target < sr->region_start + sr->region_len)
{
sr->done = 1;
return;
}
for (i = 0; i < sr->epilogue_count; ++i)
pop(sr);
pop (sr);
sr->epilogue_count = 0;
sr->epilogue_start = UNW_WHEN_NEVER;
if (!body)
push(sr);
push (sr);
sr->region_start += sr->region_len;
sr->region_len = rlen;
@ -494,7 +678,8 @@ desc_frgr_mem (unsigned char grmask, unw_word frmask,
{
if ((frmask & 1) != 0)
{
set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4;
set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
sr->region_start + sr->region_len - 1, 0);
sr->any_spills = 1;
}
@ -631,13 +816,15 @@ desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
static inline void
desc_copy_state (unw_word label, struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_labeled_state *ls;
for (rs = sr->reg_state_list; rs; rs = rs->next)
for (ls = sr->labeled_states; ls; ls = ls->next)
{
if (rs->label == label)
{
memcpy (&sr->curr, rs, sizeof(sr->curr));
if (ls->label == label)
{
free_state_stack (&sr->curr);
memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
sr->curr.next = dup_state_stack (ls->saved_state.next);
return;
}
}
@ -647,13 +834,15 @@ desc_copy_state (unw_word label, struct unw_state_record *sr)
static inline void
desc_label_state (unw_word label, struct unw_state_record *sr)
{
struct unw_reg_state *rs;
struct unw_labeled_state *ls = alloc_label_state ();
rs = malloc (sizeof (struct unw_reg_state));
memcpy (rs, &sr->curr, sizeof (*rs));
rs->label = label;
rs->next = sr->reg_state_list;
sr->reg_state_list = rs;
ls->label = label;
memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
ls->saved_state.next = dup_state_stack (sr->curr.next);
/* Insert into list of labeled states. */
ls->next = sr->labeled_states;
sr->labeled_states = ls;
}
/*
@ -1461,8 +1650,11 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
unsigned long *unw, header, length;
unsigned char *insn, *insn_end;
unsigned long segment_base;
struct unw_reg_info *r;
memset (fs, 0, sizeof (*fs));
for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
r->when = UNW_WHEN_NEVER;
context->lsda = 0;
ent = _Unwind_FindTableEntry ((void *) context->rp,
@ -1518,6 +1710,14 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
while (!fs->done && insn < insn_end)
insn = unw_decode (insn, fs->in_body, fs);
free_label_states (fs->labeled_states);
free_state_stack (&fs->curr);
#ifdef ENABLE_MALLOC_CHECKING
if (reg_state_alloced || labeled_state_alloced)
abort ();
#endif
/* If we're in the epilogue, sp has been restored and all values
on the memory stack below psp also have been restored. */
if (fs->when_target > fs->epilogue_start)
@ -1578,7 +1778,7 @@ uw_update_reg_address (struct _Unwind_Context *context,
/* Note that while RVAL can only be 1-5 from normal descriptors,
we can want to look at B0 due to having manually unwound a
signal frame. */
if (rval >= 0 && rval <= 5)
if (rval <= 5)
addr = context->br_loc[rval];
else
abort ();
@ -1677,8 +1877,7 @@ uw_update_reg_address (struct _Unwind_Context *context,
context->psp = *(unsigned long *)addr;
break;
case UNW_REG_RNAT:
case UNW_NUM_REGS:
default:
abort ();
}
}
@ -1720,7 +1919,10 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
/* Unwind BSP for the local registers allocated this frame. */
/* ??? What to do with stored BSP or BSPSTORE registers. */
if (fs->when_target > fs->curr.reg[UNW_REG_PFS].when)
/* We assert that we are either at a call site, or we have
just unwound through a signal frame. In either case
pfs_loc is valid. */
if (!(fs -> no_reg_stack_frame))
{
unsigned long pfs = *context->pfs_loc;
unsigned long sol = (pfs >> 7) & 0x7f;

View File

@ -0,0 +1,23 @@
# 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.
%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
}

View File

@ -109,3 +109,16 @@
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA
/* Define some types that are the same on all NetBSD platforms,
making them agree with <machine/ansi.h>. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#undef WINT_TYPE
#define WINT_TYPE "int"

View File

@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -27,6 +27,9 @@ Boston, MA 02111-1307, USA. */
collect has a chance to see them, so scan the object files directly. */
#define COLLECT_EXPORT_LIST
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA
/* This is the only version of nm that collect2 can work with. */
#define REAL_NM_FILE_NAME "/usr/ucb/nm"

View File

@ -199,10 +199,6 @@ do { \
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
/* Since there are separate multilibs for pthreads, determine the
thread model based on the command-line arguments. */
#define THREAD_MODEL_SPEC "%{pthread:posix}%{!pthread:single}"
/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */
#undef PTRDIFF_TYPE

Some files were not shown because too many files have changed in this diff Show More