Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
This commit is contained in:
parent
1952e2e1c1
commit
909b401074
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=96263
File diff suppressed because it is too large
Load Diff
3781
contrib/gcc/ChangeLog.lib
Normal file
3781
contrib/gcc/ChangeLog.lib
Normal file
File diff suppressed because it is too large
Load Diff
10110
contrib/gcc/FSFChangeLog.10
Normal file
10110
contrib/gcc/FSFChangeLog.10
Normal file
File diff suppressed because it is too large
Load Diff
14493
contrib/gcc/FSFChangeLog.11
Normal file
14493
contrib/gcc/FSFChangeLog.11
Normal file
File diff suppressed because it is too large
Load Diff
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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!! ### */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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; }
|
||||
;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
236
contrib/gcc/concat.c
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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)");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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))
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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); \
|
||||
|
@ -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")]
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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 ))
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")])
|
||||
|
25
contrib/gcc/config/i386/libgcc-x86_64-glibc.ver
Normal file
25
contrib/gcc/config/i386/libgcc-x86_64-glibc.ver
Normal 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
|
@ -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}"
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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}"
|
||||
|
@ -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)");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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=
|
||||
|
15
contrib/gcc/config/i386/t-linux64
Normal file
15
contrib/gcc/config/i386/t-linux64
Normal 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:
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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'.
|
||||
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)]
|
||||
""
|
||||
|
@ -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. */ \
|
||||
|
@ -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
|
||||
|
@ -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(®s[kind - 1], sr->curr.reg + limit[kind - 1],
|
||||
sr->region_start + t);
|
||||
spill_next_when (®s[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;
|
||||
|
23
contrib/gcc/config/libgcc-glibc.ver
Normal file
23
contrib/gcc/config/libgcc-glibc.ver
Normal 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
|
||||
}
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user